fix: catch parameter alias handling and snapshot updates for noBackwardRangeExtension#639
fix: catch parameter alias handling and snapshot updates for noBackwardRangeExtension#639everettbu wants to merge 3 commits into
Conversation
Greptile SummaryThis PR combines two changes: (1) a fix for the
Confidence Score: 4/5
Important Files Changed
Last reviewed commit: 99d6d02 |
| } else if ( | ||
| parent.isCallExpression() && | ||
| parent.parentPath.isVariableDeclarator() && | ||
| parent.parentPath.get('init').node === parent.node | ||
| ) { | ||
| // const MyComponent = wrap(() => {}); | ||
| id = parent.parentPath.get('id'); |
There was a problem hiding this comment.
IIFE incorrectly matched by CallExpression branch
This new branch matches any function whose parent is a CallExpression assigned to a variable, but it doesn't distinguish whether the function is an argument (HOF pattern: wrap(() => {})) or the callee (IIFE pattern: (() => {})()).
For const Items = (() => { ... })(), the arrow function is the callee of the CallExpression. The AST path is identical — parent.isCallExpression() is true, parent.parentPath.isVariableDeclarator() is true — so getFunctionName would return Items. Since Items starts with uppercase, getComponentOrHookLike would then incorrectly classify this IIFE as a component.
Consider adding a guard to ensure the function is an argument, not the callee:
| } else if ( | |
| parent.isCallExpression() && | |
| parent.parentPath.isVariableDeclarator() && | |
| parent.parentPath.get('init').node === parent.node | |
| ) { | |
| // const MyComponent = wrap(() => {}); | |
| id = parent.parentPath.get('id'); | |
| } else if ( | |
| parent.isCallExpression() && | |
| parent.get('callee').node !== path.node && | |
| parent.parentPath.isVariableDeclarator() && | |
| parent.parentPath.get('init').node === parent.node | |
| ) { | |
| // const MyComponent = wrap(() => {}); | |
| id = parent.parentPath.get('id'); |
Prompt To Fix With AI
This is a comment left during a code review.
Path: compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts
Line: 1327-1333
Comment:
**IIFE incorrectly matched by `CallExpression` branch**
This new branch matches any function whose parent is a `CallExpression` assigned to a variable, but it doesn't distinguish whether the function is an **argument** (HOF pattern: `wrap(() => {})`) or the **callee** (IIFE pattern: `(() => {})()`).
For `const Items = (() => { ... })()`, the arrow function is the `callee` of the `CallExpression`. The AST path is identical — `parent.isCallExpression()` is true, `parent.parentPath.isVariableDeclarator()` is true — so `getFunctionName` would return `Items`. Since `Items` starts with uppercase, `getComponentOrHookLike` would then incorrectly classify this IIFE as a component.
Consider adding a guard to ensure the function is an argument, not the callee:
```suggestion
} else if (
parent.isCallExpression() &&
parent.get('callee').node !== path.node &&
parent.parentPath.isVariableDeclarator() &&
parent.parentPath.get('init').node === parent.node
) {
// const MyComponent = wrap(() => {});
id = parent.parentPath.get('id');
```
How can I resolve this? If you propose a fix, please make it concise.…assed to HOFs (#35910)
…n noBackwardRangeExtension heuristic Track catch handler bindings in AliasingState so the backward-alias walk in mutate() stops at catch parameters. Without this, catch parameters aliased to call results in try blocks incorrectly trigger the effectiveSkipAliases heuristic, preventing backward range extension and causing 'Expected a break target' crashes when try-catch blocks get split across reactive scopes. Fixes 4 compiler crashes (try-catch-try-value-modified-in-catch and variants) and 1 snapshot regression (try-catch-alias-try-values). Updates 8 snapshot expectations for tests where the noBackwardRangeExtension change produces different but functionally correct memoization output. Closes #35902
cc3ca6b to
99d6d02
Compare
|
Upstream PR was closed or merged. Code is synced via branch mirror. |
Mirror of facebook/react#35934
Original author: fresh3nough
Summary
Fixes failing compiler snapshot tests introduced by the
noBackwardRangeExtensionchanges for method call receivers.Problem
The
noBackwardRangeExtensionheuristic inInferMutationAliasingRanges.tswalks backward through alias edges to detect function call results (identified by havingmaybeAliases). However, catch parameters are aliased to call results in try blocks via terminalAliaseffects. This caused the heuristic to incorrectly treat catch parameters as independently-memoizable function call results, preventing backward range extension and causing:Invariant: Expected a break target) when try-catch blocks got split across reactive scopesFix
Track catch handler binding identifiers in
AliasingState.catchParams. During the backward-alias walk inmutate(), stop traversal when a catch parameter is encountered. This prevents the heuristic from walking through catch parameter aliases to reach call results withmaybeAliases.Changes
InferMutationAliasingRanges.ts: AddedcatchParams: Set<Identifier>toAliasingState, populated frommaybe-throwterminal Alias effects, and checked during the backward-alias heuristic walk.expect.mdfiles for tests where thenoBackwardRangeExtensionchange produces different but functionally correct memoization output (all eval outputs remain correct)Tests fixed
try-catch-try-value-modified-in-catch(and propagate-scope-deps-hir-fork variant)try-catch-try-value-modified-in-catch-escaping(and propagate-scope-deps-hir-fork variant)try-catch-alias-try-valuesCloses react/react#35902