Conversation
Greptile SummaryThis PR updates 9 validation passes in the React compiler to record errors directly on
Confidence Score: 4/5
Important Files Changed
Last reviewed commit: edfde88 |
| let reactiveFunction!: ReactiveFunction; | ||
| env.tryRecord(() => { | ||
| reactiveFunction = buildReactiveFunction(hir); | ||
| }); |
There was a problem hiding this comment.
Definite assignment assertion may cause runtime crash
If buildReactiveFunction throws a non-invariant CompilerError (e.g., a CompilerError.throwTodo() at BuildReactiveFunction.ts:1010, 1168, or 1176), tryRecord will catch and record it, but reactiveFunction will remain undefined at runtime despite the ! assertion. Subsequent code like assertWellFormedBreakTargets(reactiveFunction) (line 485), pruneUnusedLabels(reactiveFunction) (line 488), and many other passes will then crash with a confusing TypeError when accessing properties on undefined.
Consider either returning early when reactiveFunction is unassigned, or giving it a safe default and guarding subsequent usage:
let reactiveFunction: ReactiveFunction | undefined;
env.tryRecord(() => {
reactiveFunction = buildReactiveFunction(hir);
});
if (reactiveFunction === undefined) {
return Err(env.aggregateErrors());
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts
Line: 475-478
Comment:
**Definite assignment assertion may cause runtime crash**
If `buildReactiveFunction` throws a non-invariant `CompilerError` (e.g., a `CompilerError.throwTodo()` at [BuildReactiveFunction.ts:1010](../ReactiveScopes/BuildReactiveFunction.ts#L1010), [1168](../ReactiveScopes/BuildReactiveFunction.ts#L1168), or [1176](../ReactiveScopes/BuildReactiveFunction.ts#L1176)), `tryRecord` will catch and record it, but `reactiveFunction` will remain `undefined` at runtime despite the `!` assertion. Subsequent code like `assertWellFormedBreakTargets(reactiveFunction)` (line 485), `pruneUnusedLabels(reactiveFunction)` (line 488), and many other passes will then crash with a confusing TypeError when accessing properties on `undefined`.
Consider either returning early when `reactiveFunction` is unassigned, or giving it a safe default and guarding subsequent usage:
```
let reactiveFunction: ReactiveFunction | undefined;
env.tryRecord(() => {
reactiveFunction = buildReactiveFunction(hir);
});
if (reactiveFunction === undefined) {
return Err(env.aggregateErrors());
}
```
How can I resolve this? If you propose a fix, please make it concise.| if (this.logger != null) { | ||
| this.logger.logEvent(this.filename, { | ||
| kind: 'CompileError', | ||
| detail: error, | ||
| fnLoc: null, | ||
| }); | ||
| } |
There was a problem hiding this comment.
Duplicate logging of recorded errors
recordError logs each error here with fnLoc: null. Later, when the pipeline returns Err(aggregateErrors), processFn in Program.ts calls handleError → logError, which logs the same errors again with the real fnLoc. This produces duplicate log entries as visible in the dynamic-gating-bailout-nopanic.expect.md fixture — the same PreserveManualMemo error appears twice in the logs, once with "fnLoc":null and once with the actual function location.
This may be intentional for now (e.g., to get early logging before knowing whether compilation will succeed), but it's worth noting as it could confuse consumers of the logger output.
Prompt To Fix With AI
This is a comment left during a code review.
Path: compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts
Line: 737-743
Comment:
**Duplicate logging of recorded errors**
`recordError` logs each error here with `fnLoc: null`. Later, when the pipeline returns `Err(aggregateErrors)`, `processFn` in Program.ts calls `handleError` → `logError`, which logs the same errors again with the real `fnLoc`. This produces duplicate log entries as visible in the `dynamic-gating-bailout-nopanic.expect.md` fixture — the same `PreserveManualMemo` error appears twice in the logs, once with `"fnLoc":null` and once with the actual function location.
This may be intentional for now (e.g., to get early logging before knowing whether compilation will succeed), but it's worth noting as it could confuse consumers of the logger output.
How can I resolve this? If you propose a fix, please make it concise.…rs on env Update 9 validation passes to record errors directly on fn.env instead of returning Result<void, CompilerError>: - validateHooksUsage - validateNoCapitalizedCalls (also changed throwInvalidReact to recordError) - validateUseMemo - dropManualMemoization - validateNoRefAccessInRender - validateNoSetStateInRender - validateNoImpureFunctionsInRender - validateNoFreezingKnownMutableFunctions - validateExhaustiveDependencies Each pass now calls fn.env.recordErrors() instead of returning errors.asResult(). Pipeline.ts call sites updated to remove tryRecord() wrappers and .unwrap().
|
Upstream PR was closed or merged. Code is synced via branch mirror. |
| env.tryRecord(() => { | ||
| validateNoFreezingKnownMutableFunctions(hir).unwrap(); | ||
| validateNoFreezingKnownMutableFunctions(hir); | ||
| }); |
There was a problem hiding this comment.
Redundant tryRecord wrapper
validateNoFreezingKnownMutableFunctions now records errors directly on fn.env (like the other 8 passes updated in this PR), so it will never throw a non-invariant CompilerError. The tryRecord wrapper here is a no-op — its only purpose was to catch the thrown error from .unwrap(), which has been removed. All other passes in this PR had their tryRecord wrappers removed; this one appears to have been missed.
| env.tryRecord(() => { | |
| validateNoFreezingKnownMutableFunctions(hir).unwrap(); | |
| validateNoFreezingKnownMutableFunctions(hir); | |
| }); | |
| validateNoFreezingKnownMutableFunctions(hir); |
Prompt To Fix With AI
This is a comment left during a code review.
Path: compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts
Line: 280-282
Comment:
**Redundant `tryRecord` wrapper**
`validateNoFreezingKnownMutableFunctions` now records errors directly on `fn.env` (like the other 8 passes updated in this PR), so it will never throw a non-invariant `CompilerError`. The `tryRecord` wrapper here is a no-op — its only purpose was to catch the thrown error from `.unwrap()`, which has been removed. All other passes in this PR had their `tryRecord` wrappers removed; this one appears to have been missed.
```suggestion
validateNoFreezingKnownMutableFunctions(hir);
```
How can I resolve this? If you propose a fix, please make it concise.
Mirror of facebook/react#35875
Original author: josephsavona
Update 9 validation passes to record errors directly on fn.env instead of
returning Result<void, CompilerError>:
Each pass now calls fn.env.recordErrors() instead of returning errors.asResult().
Pipeline.ts call sites updated to remove tryRecord() wrappers and .unwrap().
Stack created with Sapling. Best reviewed with ReviewStack.