Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 7, 2022

Conversation

lowr
Copy link
Contributor

@lowr lowr commented Dec 10, 2021

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.

@typescript-bot typescript-bot added the For Backlog Bug PRs that fix a backlog bug label Dec 10, 2021
@@ -16496,7 +16496,7 @@ namespace ts {
const result = createSymbol(symbol.flags, symbol.escapedName, CheckFlags.Instantiated | getCheckFlags(symbol) & (CheckFlags.Readonly | CheckFlags.Late | CheckFlags.OptionalParameter | CheckFlags.RestParameter));
result.declarations = symbol.declarations;
result.parent = symbol.parent;
result.target = symbol;
result.target = resolveSymbol(symbol);
Copy link
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
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
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
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.

@gabritto gabritto removed their request for review February 9, 2022 20:34
@sandersn
Copy link
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
Contributor Author

lowr commented Apr 1, 2022

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

@lowr
Copy link
Contributor Author

lowr commented Apr 7, 2022

@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.

@lowr lowr requested a review from weswigham April 7, 2022 18:04
Copy link
Member

@weswigham weswigham left a comment

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.

@sandersn and @andrewbranch you wanna be extra eyes on this for a merge, since I helped author it?

@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
Member

@andrewbranch andrewbranch left a comment

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.

}
return undefined;
}
function tryGetAliasTarget(symbol: Symbol): Symbol | undefined {
function tryGetTarget(symbol: Symbol): Symbol | undefined {
Copy link
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
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
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 weswigham merged commit b45cf0d into microsoft:main Apr 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Backlog Bug PRs that fix a backlog bug
Projects
Archived in project
5 participants