Skip to content

fix(44179): disentangle the meaning of SymbolLinks.target - #47098

Merged
Wesley Wigham (weswigham) merged 1 commit into
microsoft:mainfrom
lowr:fix/44179
Apr 7, 2022
Merged

Wesley Wigham (weswigham) merged 1 commit into
microsoft:mainfrom
lowr:fix/44179

Conversation

@lowr

Copy link
Copy Markdown
Contributor

Fixes #44179

FWIW, there are several other places in checker (L.21013, L.27167, L.27391 as of 48228b8) where "unresolved" Symbol is set to target of newly created Symbol. I ran all tests but couldn't find any code in which alias Symbol is substituted to target like the issue, so I left them intact.

Comment thread src/compiler/checker.ts Outdated
result.declarations = symbol.declarations;
result.parent = symbol.parent;
result.target = symbol;
result.target = resolveSymbol(symbol);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instantiateSymbol should absolutely not be eagerly resolving symbols like this, much as it may fix an issue like this, it's liable to cause other (performance) issues elsewhere. Instead, the code doing the spread copying needs to be resolving the symbols it's copying the members of, otherwise it can't guarantee they're all present.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the code doing the spread copying is already resolving the symbols it's copying the members of, but not the members themselves, which may be aliases and set to target, causing the problem. Resolving every member of a symbol upon checking the spread copying isn't what we want either, right?

I do understand now that instantiateSymbol shouldn't be resolving those symbols. How about not setting result.target when symbol is an alias? This fixes the issue in proper way, I believe, in that it also defers the resolution of member symbols maximally.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I think the fundamental issue is that symbol instantiation and alias resolution shouldn't both be using the same field (for referring to the original symbol and for caching the alias resolution result, respectively). Maybe there was a time when it was safe because instantiated (or copied) alias symbols couldn't exist, but that time is certainly not now. IMO, we should swap the usage in resolveAlias to use a new member (aliasTarget?) to cache results, rather than .target, and see if we can fix up what breaks and disentangle the two meanings of a .target. Something like https://gist.github.com/weswigham/22acfad2595f1c1eab3d357385907e90 looks like a promising start to that, though some more changes may be needed to fixup some assumptions in the language service.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disentangling the meanings of target sounds really nice and would make the code cleaner! Thanks for the patch, I've applied it and saw some fourslash tests failing as you anticipated. Let me fix things up in the coming days.

@sandersn

Copy link
Copy Markdown
Member

Do you want to keep working on this? Otherwise I'd like to close it to reduce the number of open PRs.

@lowr

Copy link
Copy Markdown
Contributor Author

Sorry for the huge delay. I'll work on this over the weekend.

@lowr

Copy link
Copy Markdown
Contributor Author

Wesley Wigham (@weswigham) I'm sorry I couldn't update this PR earlier. I've updated it based on your suggestion. Would you review it again?

tryGetAliasTarget() was the sole reason some fourslash tests were failing with your patch. It seems its purpose is to retrieve root .target of symbols rather than .aliasTarget despite its name. I renamed it to avoid further confusion.

@weswigham Wesley Wigham (weswigham) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thanks for helping wrap this up.

Nathan Shively-Sanders (@sandersn) and Andrew Branch (@andrewbranch) you wanna be extra eyes on this for a merge, since I helped author it?

@lowr LowR (lowr) changed the title fix(44179): resolve target symbol before substituting fix(44179): disentangle the meaning of SymbolLinks.target Apr 7, 2022

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this is great. The overloading of this property definitely caused me confusion before I learned to expect it.

Comment thread src/compiler/checker.ts
return undefined;
}
function tryGetAliasTarget(symbol: Symbol): Symbol | undefined {
function tryGetTarget(symbol: Symbol): Symbol | undefined {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this function didn't need to be renamed?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was renamed because it handles .target rather than .aliasTarget lookups, for clarity.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack, my comment was misguided because of GitHub's silent truncation of the diff. It looked like this function was handling .aliasTarget still. All good.

@weswigham
Wesley Wigham (weswigham) merged commit b45cf0d into microsoft:main Apr 7, 2022
@microsoft Microsoft (microsoft) locked as resolved and limited conversation to collaborators Oct 22, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

For Backlog Bug PRs that fix a backlog bug

Projects

Archived in project

5 participants