Skip to content

[WIP] Fix issue 63192 in TypeScript repository#2907

Open
Copilot wants to merge 5 commits intomainfrom
copilot/fix-issue-63192
Open

[WIP] Fix issue 63192 in TypeScript repository#2907
Copilot wants to merge 5 commits intomainfrom
copilot/fix-issue-63192

Conversation

Copy link
Contributor

Copilot AI commented Feb 25, 2026

  • Investigate TypeScript issue #63192 - infinite recursion when destructuring loop variables with defaults
  • Analyze two distinct cycle paths in the stack trace
  • Add NodeCheckFlagsResolvingInitialType reentrancy guard in getInitialTypeOfVariableDeclaration (cycle path 1)
  • Add NodeCheckFlagsResolvingInitialType reentrancy guard in tryGetNameFromEntityNameExpression (cycle path 2)
  • Generate and accept test baselines
  • Verify all existing tests pass
  • Run code review and address feedback
  • Run security checks

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits February 25, 2026 23:43
…les (#63192)

Add a reentrancy guard in getInitialTypeOfVariableDeclaration to detect
when flow analysis circularly computes the initial type of the same
variable declaration. This occurs when destructuring a loop variable with
default values causes flow analysis to re-evaluate the destructuring
source expression, which in turn needs the destructured bindings.

When circularity is detected, return errorType to break the cycle,
which allows the existing type resolution circularity mechanism
(pushTypeResolution/popTypeResolution) to report the appropriate
"referenced directly or indirectly in its own initializer" error.

Co-authored-by: RyanCavanaugh <[email protected]>
Copilot AI and others added 2 commits February 26, 2026 00:17
Add circularity guards for two distinct cycle paths triggered by
destructuring loop variables with default values (TypeScript#63192):

1. getInitialTypeOfVariableDeclaration: Guards against a cycle where flow
   analysis for a variable evaluates the initializer of a const variable
   declaration, which in turn needs the type of a binding element whose
   parent type depends on the destructuring source, which triggers flow
   analysis again.

2. tryGetNameFromEntityNameExpression: Guards against a cycle where
   isMatchingReference needs the type of a binding element to compute a
   property name for an element access expression (e.g. children[index]),
   which triggers parent type inference, which evaluates the initializer,
   which triggers flow analysis again.

Both guards use NodeCheckFlagsResolvingInitialType, a reentrancy flag
on the AST node. This flag is needed (rather than reusing the existing
pushTypeResolution mechanism) because the cycle occurs entirely within
flow analysis paths that bypass the normal getTypeOfSymbol entry point.
In the `let x = x` case, circularity is caught by pushTypeResolution in
getTypeOfVariableOrParameterOrPropertyWorker because `x` has no type
annotation and its type must be inferred, causing the cycle to re-enter
symbol type resolution. In the destructuring loop case, the destructuring
source variable (`node`) has an explicit type annotation, so getTypeOfSymbol
returns immediately without entering type resolution. The cycle is
entirely within flow analysis, never touching pushTypeResolution.

Co-authored-by: RyanCavanaugh <[email protected]>
@RyanCavanaugh RyanCavanaugh marked this pull request as ready for review February 26, 2026 00:26
@RyanCavanaugh
Copy link
Member

@ahejlsberg the code comments here are a bit much but does this look like a correct CFA fix?

@RyanCavanaugh
Copy link
Member

Via microsoft/TypeScript#63192

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants