Skip to content

Refrain from attempting to perform parameter fixing on a generic signature multiple times #43835

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

Conversation

weswigham
Copy link
Member

Fixes #43833

We would perform contextual parameter fixing twice on the same signature (against different instantiations of the target signature) - once during generic propagation, and again later when doing contextual typing. This caused the typeParameters of the signature being fixed to get mutated, while the cached calculated type of each parameter was unchanged, causing a type parameter mismatch leading to inference failure. Since signatures are supposed to be immutable-ish, I disallowed the second fixing pass if the first fixing pass has occurred. Additionally, there is now a debug assertion in parameter fixing for if we attempt to fix a type to a parameter and it already has a cached type which differs from the type we want to fix. Logically, we never want this to happen (since we can only contextually fix a given signature once), so the assertion should only be triggered if we've broken this subtle invariant somewhere.

@typescript-bot typescript-bot added Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Apr 26, 2021
Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

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

One comment and some background questions.

@@ -30345,7 +30345,14 @@ namespace ts {
}

function assignContextualParameterTypes(signature: Signature, context: Signature) {
signature.typeParameters = context.typeParameters;
if (context.typeParameters) {
Copy link
Member

Choose a reason for hiding this comment

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

Is context.typeParameters ever undefined? Was that the bug here?

Copy link
Member Author

Choose a reason for hiding this comment

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

I mean, I don't want to overwrite a signature's type parameters with undefined, and there's no reason to do anything if they're both undefined.

signature.typeParameters = context.typeParameters;
}
else {
return; // This signature has already has a contextual inference performed and cached on it!
Copy link
Member

Choose a reason for hiding this comment

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

Double-checking my understanding; is this correct?: it's enough to bail after seeing that typeParameters is set, because a normal run of this function sets both typeParameters and parameters. So you don't have to check parameters as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

Aye. Moreover, if a function somehow has type parameters set already, but not parameters, fixing parameters which contain a separate set of type parameters would be bad, too. (It'd be like the inverse of the original issue that caused the report)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Contextually inferred generic function with generic rest parameter not assignable to itself
3 participants