-
Notifications
You must be signed in to change notification settings - Fork 802
Fix stack overflow caused by circular destructuring #2542
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes a stack overflow that occurred when type-checking circular destructuring patterns in strict mode. The issue was caused by improper management of a re-entrancy guard flag that should prevent infinite recursion during type narrowing operations.
Changes:
- Added a test case for circular destructuring that previously caused a crash
- Fixed the re-entrancy guard in
getNarrowedTypeOfSymbolby ensuring the flag is cleared only after all recursive operations complete - Refactored two if-statements to switch-case statements for better code structure
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| testdata/tests/cases/compiler/circularDestructuring.ts | New test case that reproduces the circular destructuring bug |
| testdata/baselines/reference/compiler/circularDestructuring.types | Expected type output showing both variables typed as any |
| testdata/baselines/reference/compiler/circularDestructuring.symbols | Expected symbol output for the destructuring pattern |
| testdata/baselines/reference/compiler/circularDestructuring.errors.txt | Expected errors including circular reference and type mismatch errors |
| internal/checker/checker.go | Core fix that moves the re-entrancy guard flag cleanup to after all recursive operations, preventing stack overflow |
|
What was the stack trace? Even the other PR doesn't link back to anything. |
| // for the declaration [x, y]: [1, 2] | [3], we may have narrowed the parent type to just [3]. | ||
| return c.getBindingElementTypeFromParentType(declaration, narrowedType, true /*noTupleBoundsCheck*/) | ||
| } | ||
| links.flags &^= NodeCheckFlagsInCheckIdentifier |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason you didn't unset the flag before the if like in the original code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it was simply that it wasn't clear we might recurse through getBindingElementTypeFromParentType.
|
Okay, this is the original issue: microsoft/TypeScript#62993 |
|
And a recurrence we're running into is So the answer to my other question is basically "it's different from the original code because this is a fix that also needs to happen in the other codebase." (I misread and thought this was a porting bug) |
Right, we should consider back-porting this to 6.0. |
|
FWIW, I already had this PR open in Strada. I used a different approach and once I saw this PR here, I ran an experiment to see if that would allow me to remove the |
Fixes crash caused by this code in
--strictmode:Supersedes #2528, which didn't seem to go anywhere.