Don't ignore all generic self tail calls when collecting the return type of a function - #63999
Don't ignore all generic self tail calls when collecting the return type of a function#63999Mateusz Burzyński (Andarist) wants to merge 2 commits into
Conversation
…ype of a function
There was a problem hiding this comment.
Pull request overview
Tightens generic recursive return-type inference so only same-instantiation tail calls are ignored.
Changes:
- Checks recursive arguments against the current generic signature.
- Adds regression coverage and generated baselines.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
tsc/internal/checker/checker.go |
Refines recursive-call inference handling. |
tsc/testdata/tests/cases/compiler/genericRecursiveFunctionReturn.ts |
Adds regression scenarios. |
tsc/testdata/baselines/reference/compiler/genericRecursiveFunctionReturn.errors.txt |
Records expected diagnostics. |
tsc/testdata/baselines/reference/compiler/genericRecursiveFunctionReturn.types |
Records inferred types. |
tsc/testdata/baselines/reference/compiler/genericRecursiveFunctionReturn.symbols |
Records symbols. |
tsc/testdata/baselines/reference/compiler/genericRecursiveFunctionReturn.js |
Records emitted JavaScript. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
|
TypeScript Bot (@typescript-bot) test it |
What's an intuition for why this is the correct rule? |
|
Ryan Cavanaugh (@RyanCavanaugh) Here are the results of running the user tests with tsc comparing There were infrastructure failures potentially unrelated to your change:
Otherwise... Everything looks good! |
|
Ryan Cavanaugh (@RyanCavanaugh) Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Ryan Cavanaugh (@RyanCavanaugh) Here are the results of running the top 400 repos with tsc comparing Everything looks good! |
|
Ryan Cavanaugh (@RyanCavanaugh) it seems to me the only possible instantiation of such a recursive self-tail call (when supplied arg type match the exact parameter types) is one that can't contribute anything new to the possible return type. That's because, by nature, the recursion would reach the same branches, in the same way, when analyzing (in abstract) that recursive call. So if we think about the overall return type of this signature, it's like: Return<Fn> = Base | Return<Fn>This means that |
fixes #63990 (a bug introduced with #53995 )
This PR avoids ignoring recursive self calls when the arguments list is not assignable to the parameter list of the signature declaration.
So this errors:
But this continues to work:
It also ignores generic calls with type argument lists because that can lead to other instantiations of the signature declaration.