[compiler] Phase 8: Add multi-error test fixture and update plan (#35877)
Add test fixture demonstrating fault tolerance: the compiler now reports both a mutation error and a ref access error in the same function, where previously only one would be reported before bailing out. Update plan doc to mark all phases as complete. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/35877). * #35888 * #35884 * #35883 * #35882 * #35881 * #35880 * #35879 * #35878 * __->__ #35877
Joseph Savona committed
Feb 23, 2026 at 16:02 UTC
59d7c27087fae2b7abbb360187b473068c4bcaaa
3 files changed
+85
-6
compiler/fault-tolerance-overview.md
+6
-6
@@ -279,27 +279,27 @@ Walk through `runWithEnvironment` and wrap each pass call site. This is the inte
279
280
### Phase 8: Testing
281
282
-- [ ] **8.1 Update existing `error.todo-*` fixture expectations**
282
+- [x] **8.1 Update existing `error.todo-*` fixture expectations**
283
- Currently, fixtures with `error.todo-` prefix expect a single error and bailout
284
- After fault tolerance, some of these may now produce multiple errors
285
- Update the `.expect.md` files to reflect the new aggregated error output
286
287
-- [ ] **8.2 Add multi-error test fixtures**
287
+- [x] **8.2 Add multi-error test fixtures**
288
- Create test fixtures that contain multiple independent errors (e.g., both a `var` declaration and a mutation of a frozen value)
289
- Verify that all errors are reported, not just the first one
290
291
-- [ ] **8.3 Add test for invariant-still-throws behavior**
291
+- [x] **8.3 Add test for invariant-still-throws behavior**
292
- Verify that `CompilerError.invariant()` failures still cause immediate abort
293
- Verify that non-CompilerError exceptions still cause immediate abort
294
295
-- [ ] **8.4 Add test for partial HIR codegen**
295
+- [x] **8.4 Add test for partial HIR codegen**
296
- Verify that when BuildHIR produces partial HIR (with `UnsupportedNode` values), later passes handle it gracefully and codegen produces the original AST for unsupported portions
297
298
-- [ ] **8.5 Verify error severity in aggregated output**
298
+- [x] **8.5 Verify error severity in aggregated output**
299
- Test that the aggregated `CompilerError` correctly reports `hasErrors()` vs `hasWarning()` vs `hasHints()` based on the mix of accumulated diagnostics
300
- Verify that `panicThreshold` behavior in Program.ts is correct for aggregated errors
301
302
-- [ ] **8.6 Run full test suite**
302
+- [x] **8.6 Run full test suite**
303
- Run `yarn snap` and `yarn snap -u` to update all fixture expectations
304
- Ensure no regressions in passing tests
305
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.fault-tolerance-reports-multiple-errors.expect.md
new
+60
@@ -0,0 +1,60 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @validateRefAccessDuringRender
6
+/**
7
+ * This fixture tests fault tolerance: the compiler should report
8
+ * multiple independent errors rather than stopping at the first one.
9
+ *
10
+ * Error 1: Ref access during render (ref.current)
11
+ * Error 2: Mutation of frozen value (props)
12
+ */
13
+function Component(props) {
14
+ const ref = useRef(null);
15
+
16
+ // Error: reading ref during render
17
+ const value = ref.current;
18
+
19
+ // Error: mutating frozen value (props, which is frozen after hook call)
20
+ props.items = [];
21
+
22
+ return <div>{value}</div>;
23
+}
24
+
25
+```
26
+
27
+
28
+## Error
29
+
30
+```
31
+Found 2 errors:
32
+
33
+Error: This value cannot be modified
34
+
35
+Modifying component props or hook arguments is not allowed. Consider using a local variable instead.
36
+
37
+error.fault-tolerance-reports-multiple-errors.ts:16:2
38
+ 14 |
39
+ 15 | // Error: mutating frozen value (props, which is frozen after hook call)
40
+> 16 | props.items = [];
41
+ | ^^^^^ value cannot be modified
42
+ 17 |
43
+ 18 | return <div>{value}</div>;
44
+ 19 | }
45
+
46
+Error: Cannot access refs during render
47
+
48
+React refs are values that are not needed for rendering. Refs should only be accessed outside of render, such as in event handlers or effects. Accessing a ref value (the `current` property) during render can cause your component not to update as expected (https://react.dev/reference/react/useRef).
49
+
50
+error.fault-tolerance-reports-multiple-errors.ts:13:16
51
+ 11 |
52
+ 12 | // Error: reading ref during render
53
+> 13 | const value = ref.current;
54
+ | ^^^^^^^^^^^ Cannot access ref value during render
55
+ 14 |
56
+ 15 | // Error: mutating frozen value (props, which is frozen after hook call)
57
+ 16 | props.items = [];
58
+```
59
+
60
+
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.fault-tolerance-reports-multiple-errors.js
new
+19
@@ -0,0 +1,19 @@
1
+// @validateRefAccessDuringRender
2
+/**
3
+ * This fixture tests fault tolerance: the compiler should report
4
+ * multiple independent errors rather than stopping at the first one.
5
+ *
6
+ * Error 1: Ref access during render (ref.current)
7
+ * Error 2: Mutation of frozen value (props)
8
+ */
9
+function Component(props) {
10
+ const ref = useRef(null);
11
+
12
+ // Error: reading ref during render
13
+ const value = ref.current;
14
+
15
+ // Error: mutating frozen value (props, which is frozen after hook call)
16
+ props.items = [];
17
+
18
+ return <div>{value}</div>;
19
+}