[compiler] Enable new inference by default (#33497)
--- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33497). * #33571 * #33558 * #33547 * #33543 * #33533 * #33532 * #33530 * #33526 * #33522 * #33518 * #33514 * #33513 * #33512 * #33504 * #33500 * __->__ #33497 * #33496
Joseph Savona committed
Jun 18, 2025 at 13:02 UTC
90ccbd71c158a8aeb1bf3ec704011ddd58842b71
25 files changed
+277
-203
compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts
+1
-1
@@ -246,7 +246,7 @@ export const EnvironmentConfigSchema = z.object({
246
/**
247
* Enable a new model for mutability and aliasing inference
248
*/
249
- enableNewMutationAliasingModel: z.boolean().default(false),
249
+ enableNewMutationAliasingModel: z.boolean().default(true),
250
251
/**
252
* Enables inference of optional dependency chains. Without this flag
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/aliased-nested-scope-truncated-dep.expect.md
+3
-10
@@ -175,21 +175,14 @@ import {
175
* and mutability.
176
*/
177
function Component(t0) {
178
- const $ = _c(4);
178
+ const $ = _c(2);
179
const { prop } = t0;
180
let t1;
181
if ($[0] !== prop) {
182
const obj = shallowCopy(prop);
183
const aliasedObj = identity(obj);
184
- let t2;
185
- if ($[2] !== obj) {
186
- t2 = [obj.id];
187
- $[2] = obj;
188
- $[3] = t2;
189
- } else {
190
- t2 = $[3];
191
- }
192
- const id = t2;
184
+
185
+ const id = [obj.id];
186
187
mutate(aliasedObj);
188
setPropertyByKey(aliasedObj, "id", prop.id + 1);
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-function-alias-computed-load-2-iife.expect.md
+14
-6
@@ -25,17 +25,25 @@ export const FIXTURE_ENTRYPOINT = {
25
```javascript
26
import { c as _c } from "react/compiler-runtime";
27
function bar(a) {
28
- const $ = _c(2);
29
- let y;
28
+ const $ = _c(4);
29
+ let t0;
30
if ($[0] !== a) {
31
- const x = [a];
31
+ t0 = [a];
32
+ $[0] = a;
33
+ $[1] = t0;
34
+ } else {
35
+ t0 = $[1];
36
+ }
37
+ const x = t0;
38
+ let y;
39
+ if ($[2] !== x[0][1]) {
40
y = {};
41
42
y = x[0][1];
35
- $[0] = a;
36
- $[1] = y;
43
+ $[2] = x[0][1];
44
+ $[3] = y;
45
} else {
38
- y = $[1];
46
+ y = $[3];
47
}
48
return y;
49
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-function-alias-computed-load-3-iife.expect.md
+16
-7
@@ -29,20 +29,29 @@ export const FIXTURE_ENTRYPOINT = {
29
```javascript
30
import { c as _c } from "react/compiler-runtime";
31
function bar(a, b) {
32
- const $ = _c(3);
33
- let y;
32
+ const $ = _c(6);
33
+ let t0;
34
if ($[0] !== a || $[1] !== b) {
35
- const x = [a, b];
35
+ t0 = [a, b];
36
+ $[0] = a;
37
+ $[1] = b;
38
+ $[2] = t0;
39
+ } else {
40
+ t0 = $[2];
41
+ }
42
+ const x = t0;
43
+ let y;
44
+ if ($[3] !== x[0][1] || $[4] !== x[1][0]) {
45
y = {};
46
let t = {};
47
48
y = x[0][1];
49
t = x[1][0];
41
- $[0] = a;
42
- $[1] = b;
43
- $[2] = y;
50
+ $[3] = x[0][1];
51
+ $[4] = x[1][0];
52
+ $[5] = y;
53
} else {
45
- y = $[2];
54
+ y = $[5];
55
}
56
return y;
57
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-function-alias-computed-load-4-iife.expect.md
+14
-6
@@ -25,17 +25,25 @@ export const FIXTURE_ENTRYPOINT = {
25
```javascript
26
import { c as _c } from "react/compiler-runtime";
27
function bar(a) {
28
- const $ = _c(2);
29
- let y;
28
+ const $ = _c(4);
29
+ let t0;
30
if ($[0] !== a) {
31
- const x = [a];
31
+ t0 = [a];
32
+ $[0] = a;
33
+ $[1] = t0;
34
+ } else {
35
+ t0 = $[1];
36
+ }
37
+ const x = t0;
38
+ let y;
39
+ if ($[2] !== x[0].a[1]) {
40
y = {};
41
42
y = x[0].a[1];
35
- $[0] = a;
36
- $[1] = y;
43
+ $[2] = x[0].a[1];
44
+ $[3] = y;
45
} else {
38
- y = $[1];
46
+ y = $[3];
47
}
48
return y;
49
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-function-alias-computed-load-iife.expect.md
+14
-6
@@ -24,17 +24,25 @@ export const FIXTURE_ENTRYPOINT = {
24
```javascript
25
import { c as _c } from "react/compiler-runtime";
26
function bar(a) {
27
- const $ = _c(2);
28
- let y;
27
+ const $ = _c(4);
28
+ let t0;
29
if ($[0] !== a) {
30
- const x = [a];
30
+ t0 = [a];
31
+ $[0] = a;
32
+ $[1] = t0;
33
+ } else {
34
+ t0 = $[1];
35
+ }
36
+ const x = t0;
37
+ let y;
38
+ if ($[2] !== x[0]) {
39
y = {};
40
41
y = x[0];
34
- $[0] = a;
35
- $[1] = y;
42
+ $[2] = x[0];
43
+ $[3] = y;
44
} else {
37
- y = $[1];
45
+ y = $[3];
46
}
47
return y;
48
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-impure-functions-in-render.expect.md
+1
-1
@@ -20,7 +20,7 @@ function Component() {
20
2 |
21
3 | function Component() {
22
> 4 | const date = Date.now();
23
- | ^^^^^^^^ InvalidReact: Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent). `Date.now` is an impure function whose results may change on every call (4:4)
23
+ | ^^^^^^^^^^ InvalidReact: Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent). `Date.now` is an impure function whose results may change on every call (4:4)
24
25
InvalidReact: Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent). `performance.now` is an impure function whose results may change on every call (5:5)
26
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-non-imported-reanimated-shared-value-writes.expect.md
+1
-1
@@ -27,7 +27,7 @@ function SomeComponent() {
27
9 | return (
28
10 | <Button
29
> 11 | onPress={() => (sharedVal.value = Math.random())}
30
- | ^^^^^^^^^ InvalidReact: Mutating a value returned from a function whose return value should not be mutated. Found mutation of `sharedVal` (11:11)
30
+ | ^^^^^^^^^ InvalidReact: This mutates a variable that React considers immutable. Found mutation of `sharedVal` (11:11)
31
12 | title="Randomize"
32
13 | />
33
14 | );
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.mutate-hook-argument.expect.md
+2
@@ -16,6 +16,8 @@ function useHook(a, b) {
16
1 | function useHook(a, b) {
17
> 2 | b.test = 1;
18
| ^ InvalidReact: Mutating component props or hook arguments is not allowed. Consider using a local variable instead (2:2)
19
+
20
+InvalidReact: Mutating component props or hook arguments is not allowed. Consider using a local variable instead (3:3)
21
3 | a.test = 2;
22
4 | }
23
5 |
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.not-useEffect-external-mutate.expect.md
+2
@@ -21,6 +21,8 @@ function Component(props) {
21
4 | foo(() => {
22
> 5 | x.a = 10;
23
| ^ InvalidReact: Writing to a variable defined outside a component or hook is not allowed. Consider using an effect (5:5)
24
+
25
+InvalidReact: Writing to a variable defined outside a component or hook is not allowed. Consider using an effect (6:6)
26
6 | x.a = 20;
27
7 | });
28
8 | }
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.reassignment-to-global-indirect.expect.md
+2
@@ -21,6 +21,8 @@ function Component() {
21
3 | // Cannot assign to globals
22
> 4 | someUnknownGlobal = true;
23
| ^^^^^^^^^^^^^^^^^ InvalidReact: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (4:4)
24
+
25
+InvalidReact: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (5:5)
26
5 | moduleLocal = true;
27
6 | };
28
7 | foo();
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.reassignment-to-global.expect.md
+2
@@ -18,6 +18,8 @@ function Component() {
18
2 | // Cannot assign to globals
19
> 3 | someUnknownGlobal = true;
20
| ^^^^^^^^^^^^^^^^^ InvalidReact: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (3:3)
21
+
22
+InvalidReact: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (4:4)
23
4 | moduleLocal = true;
24
5 | }
25
6 |
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-repro-named-function-with-shadowed-local-same-name.expect.md
+1
-1
@@ -22,7 +22,7 @@ function Component(props) {
22
7 | return hasErrors;
23
8 | }
24
> 9 | return hasErrors();
25
- | ^^^^^^^^^ Invariant: [hoisting] Expected value for identifier to be initialized. hasErrors_0$15 (9:9)
25
+ | ^^^^^^^^^ Invariant: [InferMutationAliasingEffects] Expected value kind to be initialized. <unknown> hasErrors_0$15:TFunction (9:9)
26
10 | }
27
11 |
28
```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/mutate-after-useeffect-optional-chain.expect.md
+1
-1
@@ -48,7 +48,7 @@ export const FIXTURE_ENTRYPOINT = {
48
## Logs
49
50
```
51
-{"kind":"CompileError","fnLoc":{"start":{"line":5,"column":0,"index":139},"end":{"line":12,"column":1,"index":384},"filename":"mutate-after-useeffect-optional-chain.ts"},"detail":{"reason":"This mutates a variable that React considers immutable","description":null,"loc":{"start":{"line":10,"column":2,"index":345},"end":{"line":10,"column":5,"index":348},"filename":"mutate-after-useeffect-optional-chain.ts","identifierName":"arr"},"suggestions":null,"severity":"InvalidReact"}}
51
+{"kind":"CompileError","fnLoc":{"start":{"line":5,"column":0,"index":139},"end":{"line":12,"column":1,"index":384},"filename":"mutate-after-useeffect-optional-chain.ts"},"detail":{"reason":"Updating a value used previously in an effect function or as an effect dependency is not allowed. Consider moving the mutation before calling useEffect()","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":10,"column":2,"index":345},"end":{"line":10,"column":5,"index":348},"filename":"mutate-after-useeffect-optional-chain.ts","identifierName":"arr"}}}
52
{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":9,"column":2,"index":304},"end":{"line":9,"column":39,"index":341},"filename":"mutate-after-useeffect-optional-chain.ts"},"decorations":[{"start":{"line":9,"column":24,"index":326},"end":{"line":9,"column":27,"index":329},"filename":"mutate-after-useeffect-optional-chain.ts","identifierName":"arr"}]}
53
{"kind":"CompileSuccess","fnLoc":{"start":{"line":5,"column":0,"index":139},"end":{"line":12,"column":1,"index":384},"filename":"mutate-after-useeffect-optional-chain.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
54
```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/mutate-after-useeffect-ref-access.expect.md
+1
-1
@@ -47,7 +47,7 @@ export const FIXTURE_ENTRYPOINT = {
47
## Logs
48
49
```
50
-{"kind":"CompileError","fnLoc":{"start":{"line":6,"column":0,"index":148},"end":{"line":11,"column":1,"index":311},"filename":"mutate-after-useeffect-ref-access.ts"},"detail":{"reason":"Mutating component props or hook arguments is not allowed. Consider using a local variable instead","description":null,"loc":{"start":{"line":9,"column":2,"index":269},"end":{"line":9,"column":16,"index":283},"filename":"mutate-after-useeffect-ref-access.ts"},"suggestions":null,"severity":"InvalidReact"}}
50
+{"kind":"CompileError","fnLoc":{"start":{"line":6,"column":0,"index":148},"end":{"line":11,"column":1,"index":311},"filename":"mutate-after-useeffect-ref-access.ts"},"detail":{"reason":"Mutating component props or hook arguments is not allowed. Consider using a local variable instead","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":9,"column":2,"index":269},"end":{"line":9,"column":16,"index":283},"filename":"mutate-after-useeffect-ref-access.ts"}}}
51
{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":8,"column":2,"index":227},"end":{"line":8,"column":40,"index":265},"filename":"mutate-after-useeffect-ref-access.ts"},"decorations":[{"start":{"line":8,"column":24,"index":249},"end":{"line":8,"column":30,"index":255},"filename":"mutate-after-useeffect-ref-access.ts","identifierName":"arrRef"}]}
52
{"kind":"CompileSuccess","fnLoc":{"start":{"line":6,"column":0,"index":148},"end":{"line":11,"column":1,"index":311},"filename":"mutate-after-useeffect-ref-access.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
53
```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/bailout-retry/mutate-after-useeffect.expect.md
+1
-1
@@ -47,7 +47,7 @@ export const FIXTURE_ENTRYPOINT = {
47
## Logs
48
49
```
50
-{"kind":"CompileError","fnLoc":{"start":{"line":4,"column":0,"index":101},"end":{"line":11,"column":1,"index":222},"filename":"mutate-after-useeffect.ts"},"detail":{"reason":"This mutates a variable that React considers immutable","description":null,"loc":{"start":{"line":9,"column":2,"index":194},"end":{"line":9,"column":5,"index":197},"filename":"mutate-after-useeffect.ts","identifierName":"arr"},"suggestions":null,"severity":"InvalidReact"}}
50
+{"kind":"CompileError","fnLoc":{"start":{"line":4,"column":0,"index":101},"end":{"line":11,"column":1,"index":222},"filename":"mutate-after-useeffect.ts"},"detail":{"reason":"Updating a value used previously in an effect function or as an effect dependency is not allowed. Consider moving the mutation before calling useEffect()","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":9,"column":2,"index":194},"end":{"line":9,"column":5,"index":197},"filename":"mutate-after-useeffect.ts","identifierName":"arr"}}}
51
{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":6,"column":2,"index":149},"end":{"line":8,"column":4,"index":190},"filename":"mutate-after-useeffect.ts"},"decorations":[{"start":{"line":7,"column":4,"index":171},"end":{"line":7,"column":7,"index":174},"filename":"mutate-after-useeffect.ts","identifierName":"arr"},{"start":{"line":7,"column":4,"index":171},"end":{"line":7,"column":7,"index":174},"filename":"mutate-after-useeffect.ts","identifierName":"arr"},{"start":{"line":7,"column":13,"index":180},"end":{"line":7,"column":16,"index":183},"filename":"mutate-after-useeffect.ts","identifierName":"foo"}]}
52
{"kind":"CompileSuccess","fnLoc":{"start":{"line":4,"column":0,"index":101},"end":{"line":11,"column":1,"index":222},"filename":"mutate-after-useeffect.ts"},"fnName":"Component","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
53
```
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/no-emit/retry-no-emit.expect.md
+1
-1
@@ -52,7 +52,7 @@ export const FIXTURE_ENTRYPOINT = {
52
## Logs
53
54
```
55
-{"kind":"CompileError","fnLoc":{"start":{"line":5,"column":0,"index":163},"end":{"line":13,"column":1,"index":357},"filename":"retry-no-emit.ts"},"detail":{"reason":"This mutates a variable that React considers immutable","description":null,"loc":{"start":{"line":11,"column":2,"index":320},"end":{"line":11,"column":6,"index":324},"filename":"retry-no-emit.ts","identifierName":"arr2"},"suggestions":null,"severity":"InvalidReact"}}
55
+{"kind":"CompileError","fnLoc":{"start":{"line":5,"column":0,"index":163},"end":{"line":13,"column":1,"index":357},"filename":"retry-no-emit.ts"},"detail":{"reason":"This mutates a variable that React considers immutable","description":null,"severity":"InvalidReact","suggestions":null,"loc":{"start":{"line":11,"column":2,"index":320},"end":{"line":11,"column":6,"index":324},"filename":"retry-no-emit.ts","identifierName":"arr2"}}}
56
{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":7,"column":2,"index":216},"end":{"line":7,"column":36,"index":250},"filename":"retry-no-emit.ts"},"decorations":[{"start":{"line":7,"column":31,"index":245},"end":{"line":7,"column":34,"index":248},"filename":"retry-no-emit.ts","identifierName":"arr"}]}
57
{"kind":"AutoDepsDecorations","fnLoc":{"start":{"line":10,"column":2,"index":274},"end":{"line":10,"column":44,"index":316},"filename":"retry-no-emit.ts"},"decorations":[{"start":{"line":10,"column":25,"index":297},"end":{"line":10,"column":29,"index":301},"filename":"retry-no-emit.ts","identifierName":"arr2"},{"start":{"line":10,"column":25,"index":297},"end":{"line":10,"column":29,"index":301},"filename":"retry-no-emit.ts","identifierName":"arr2"},{"start":{"line":10,"column":35,"index":307},"end":{"line":10,"column":42,"index":314},"filename":"retry-no-emit.ts","identifierName":"propVal"}]}
58
{"kind":"CompileSuccess","fnLoc":{"start":{"line":5,"column":0,"index":163},"end":{"line":13,"column":1,"index":357},"filename":"retry-no-emit.ts"},"fnName":"Foo","memoSlots":0,"memoBlocks":0,"memoValues":0,"prunedMemoBlocks":0,"prunedMemoValues":0}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-setState.expect.md
+14
-8
@@ -34,22 +34,28 @@ import { print } from "shared-runtime";
34
* setState types are not enough to determine to omit from deps. Must also take reactivity into account.
35
*/
36
function ReactiveRefInEffect(props) {
37
- const $ = _c(2);
37
+ const $ = _c(4);
38
const [, setState1] = useRef("initial value");
39
const [, setState2] = useRef("initial value");
40
let setState;
41
- if (props.foo) {
42
- setState = setState1;
41
+ if ($[0] !== props.foo) {
42
+ if (props.foo) {
43
+ setState = setState1;
44
+ } else {
45
+ setState = setState2;
46
+ }
47
+ $[0] = props.foo;
48
+ $[1] = setState;
49
} else {
44
- setState = setState2;
50
+ setState = $[1];
51
}
52
let t0;
47
- if ($[0] !== setState) {
53
+ if ($[2] !== setState) {
54
t0 = () => print(setState);
49
- $[0] = setState;
50
- $[1] = t0;
55
+ $[2] = setState;
56
+ $[3] = t0;
57
} else {
52
- t0 = $[1];
58
+ t0 = $[3];
59
}
60
useEffect(t0, [setState]);
61
}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/inner-function/nullable-objects/array-map-named-callback-cross-context.expect.md
+43
-38
@@ -57,62 +57,67 @@ import { Stringify } from "shared-runtime";
57
* - cb1 is not assumed to be called since it's only used as a call operand
58
*/
59
function useFoo(t0) {
60
- const $ = _c(13);
61
- const { arr1, arr2 } = t0;
60
+ const $ = _c(14);
61
+ let arr1;
62
+ let arr2;
63
let t1;
63
- if ($[0] !== arr1[0]) {
64
- t1 = (e) => arr1[0].value + e.value;
65
- $[0] = arr1[0];
66
- $[1] = t1;
64
+ if ($[0] !== t0) {
65
+ ({ arr1, arr2 } = t0);
66
+ let t2;
67
+ if ($[4] !== arr1[0]) {
68
+ t2 = (e) => arr1[0].value + e.value;
69
+ $[4] = arr1[0];
70
+ $[5] = t2;
71
+ } else {
72
+ t2 = $[5];
73
+ }
74
+ const cb1 = t2;
75
+ t1 = () => arr1.map(cb1);
76
+ $[0] = t0;
77
+ $[1] = arr1;
78
+ $[2] = arr2;
79
+ $[3] = t1;
80
} else {
68
- t1 = $[1];
81
+ arr1 = $[1];
82
+ arr2 = $[2];
83
+ t1 = $[3];
84
}
70
- const cb1 = t1;
85
+ const getArrMap1 = t1;
86
let t2;
72
- if ($[2] !== arr1 || $[3] !== cb1) {
73
- t2 = () => arr1.map(cb1);
74
- $[2] = arr1;
75
- $[3] = cb1;
76
- $[4] = t2;
87
+ if ($[6] !== arr2) {
88
+ t2 = (e_0) => arr2[0].value + e_0.value;
89
+ $[6] = arr2;
90
+ $[7] = t2;
91
} else {
78
- t2 = $[4];
92
+ t2 = $[7];
93
}
80
- const getArrMap1 = t2;
94
+ const cb2 = t2;
95
let t3;
82
- if ($[5] !== arr2) {
83
- t3 = (e_0) => arr2[0].value + e_0.value;
84
- $[5] = arr2;
85
- $[6] = t3;
96
+ if ($[8] !== arr1 || $[9] !== cb2) {
97
+ t3 = () => arr1.map(cb2);
98
+ $[8] = arr1;
99
+ $[9] = cb2;
100
+ $[10] = t3;
101
} else {
87
- t3 = $[6];
102
+ t3 = $[10];
103
}
89
- const cb2 = t3;
104
+ const getArrMap2 = t3;
105
let t4;
91
- if ($[7] !== arr1 || $[8] !== cb2) {
92
- t4 = () => arr1.map(cb2);
93
- $[7] = arr1;
94
- $[8] = cb2;
95
- $[9] = t4;
96
- } else {
97
- t4 = $[9];
98
- }
99
- const getArrMap2 = t4;
100
- let t5;
101
- if ($[10] !== getArrMap1 || $[11] !== getArrMap2) {
102
- t5 = (
106
+ if ($[11] !== getArrMap1 || $[12] !== getArrMap2) {
107
+ t4 = (
108
<Stringify
109
getArrMap1={getArrMap1}
110
getArrMap2={getArrMap2}
111
shouldInvokeFns={true}
112
/>
113
);
109
- $[10] = getArrMap1;
110
- $[11] = getArrMap2;
111
- $[12] = t5;
114
+ $[11] = getArrMap1;
115
+ $[12] = getArrMap2;
116
+ $[13] = t4;
117
} else {
113
- t5 = $[12];
118
+ t4 = $[13];
119
}
115
- return t5;
120
+ return t4;
121
}
122
123
export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-key-object-mutated-later.expect.md
+10
-26
@@ -27,34 +27,18 @@ import { c as _c } from "react/compiler-runtime";
27
import { identity, mutate } from "shared-runtime";
28
29
function Component(props) {
30
- const $ = _c(5);
31
- let t0;
32
- if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
33
- t0 = {};
34
- $[0] = t0;
30
+ const $ = _c(2);
31
+ let context;
32
+ if ($[0] !== props.value) {
33
+ const key = {};
34
+ context = { [key]: identity([props.value]) };
35
+
36
+ mutate(key);
37
+ $[0] = props.value;
38
+ $[1] = context;
39
} else {
36
- t0 = $[0];
40
+ context = $[1];
41
}
38
- const key = t0;
39
- let t1;
40
- if ($[1] !== props.value) {
41
- t1 = identity([props.value]);
42
- $[1] = props.value;
43
- $[2] = t1;
44
- } else {
45
- t1 = $[2];
46
- }
47
- let t2;
48
- if ($[3] !== t1) {
49
- t2 = { [key]: t1 };
50
- $[3] = t1;
51
- $[4] = t2;
52
- } else {
53
- t2 = $[4];
54
- }
55
- const context = t2;
56
-
57
- mutate(key);
42
return context;
43
}
44
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-member.expect.md
+13
-2
@@ -27,11 +27,22 @@ import { c as _c } from "react/compiler-runtime";
27
import { identity, mutate, mutateAndReturn } from "shared-runtime";
28
29
function Component(props) {
30
- const $ = _c(2);
30
+ const $ = _c(4);
31
let context;
32
if ($[0] !== props.value) {
33
const key = { a: "key" };
34
- context = { [key.a]: identity([props.value]) };
34
+
35
+ const t0 = key.a;
36
+ const t1 = identity([props.value]);
37
+ let t2;
38
+ if ($[2] !== t1) {
39
+ t2 = { [t0]: t1 };
40
+ $[2] = t1;
41
+ $[3] = t2;
42
+ } else {
43
+ t2 = $[3];
44
+ }
45
+ context = t2;
46
47
mutate(key);
48
$[0] = props.value;
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-deplist-controlflow.expect.md
+29
-22
@@ -40,39 +40,46 @@ import { useCallback } from "react";
40
import { Stringify } from "shared-runtime";
41
42
function Foo(t0) {
43
- const $ = _c(8);
43
+ const $ = _c(10);
44
const { arr1, arr2, foo } = t0;
45
- let getVal1;
45
let t1;
47
- if ($[0] !== arr1 || $[1] !== arr2 || $[2] !== foo) {
48
- const x = [arr1];
49
-
46
+ if ($[0] !== arr1) {
47
+ t1 = [arr1];
48
+ $[0] = arr1;
49
+ $[1] = t1;
50
+ } else {
51
+ t1 = $[1];
52
+ }
53
+ const x = t1;
54
+ let getVal1;
55
+ let t2;
56
+ if ($[2] !== arr2 || $[3] !== foo || $[4] !== x) {
57
let y = [];
58
59
getVal1 = _temp;
60
54
- t1 = () => [y];
61
+ t2 = () => [y];
62
foo ? (y = x.concat(arr2)) : y;
56
- $[0] = arr1;
57
- $[1] = arr2;
58
- $[2] = foo;
59
- $[3] = getVal1;
60
- $[4] = t1;
63
+ $[2] = arr2;
64
+ $[3] = foo;
65
+ $[4] = x;
66
+ $[5] = getVal1;
67
+ $[6] = t2;
68
} else {
62
- getVal1 = $[3];
63
- t1 = $[4];
69
+ getVal1 = $[5];
70
+ t2 = $[6];
71
}
65
- const getVal2 = t1;
66
- let t2;
67
- if ($[5] !== getVal1 || $[6] !== getVal2) {
68
- t2 = <Stringify val1={getVal1} val2={getVal2} shouldInvokeFns={true} />;
69
- $[5] = getVal1;
70
- $[6] = getVal2;
71
- $[7] = t2;
72
+ const getVal2 = t2;
73
+ let t3;
74
+ if ($[7] !== getVal1 || $[8] !== getVal2) {
75
+ t3 = <Stringify val1={getVal1} val2={getVal2} shouldInvokeFns={true} />;
76
+ $[7] = getVal1;
77
+ $[8] = getVal2;
78
+ $[9] = t3;
79
} else {
73
- t2 = $[7];
80
+ t3 = $[9];
81
}
75
- return t2;
82
+ return t3;
83
}
84
function _temp() {
85
return { x: 2 };
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-reordering-depslist-assignment.expect.md
+23
-16
@@ -36,31 +36,38 @@ import { Stringify } from "shared-runtime";
36
37
// We currently produce invalid output (incorrect scoping for `y` declaration)
38
function useFoo(arr1, arr2) {
39
- const $ = _c(5);
39
+ const $ = _c(7);
40
let t0;
41
- if ($[0] !== arr1 || $[1] !== arr2) {
42
- const x = [arr1];
43
-
44
- let y;
45
- t0 = () => ({ y });
46
-
47
- (y = x.concat(arr2)), y;
41
+ if ($[0] !== arr1) {
42
+ t0 = [arr1];
43
$[0] = arr1;
49
- $[1] = arr2;
50
- $[2] = t0;
44
+ $[1] = t0;
45
} else {
52
- t0 = $[2];
46
+ t0 = $[1];
47
}
54
- const getVal = t0;
48
+ const x = t0;
49
let t1;
56
- if ($[3] !== getVal) {
57
- t1 = <Stringify getVal={getVal} shouldInvokeFns={true} />;
58
- $[3] = getVal;
50
+ if ($[2] !== arr2 || $[3] !== x) {
51
+ let y;
52
+ t1 = () => ({ y });
53
+
54
+ (y = x.concat(arr2)), y;
55
+ $[2] = arr2;
56
+ $[3] = x;
57
$[4] = t1;
58
} else {
59
t1 = $[4];
60
}
63
- return t1;
61
+ const getVal = t1;
62
+ let t2;
63
+ if ($[5] !== getVal) {
64
+ t2 = <Stringify getVal={getVal} shouldInvokeFns={true} />;
65
+ $[5] = getVal;
66
+ $[6] = t2;
67
+ } else {
68
+ t2 = $[6];
69
+ }
70
+ return t2;
71
}
72
73
export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useMemo-reordering-depslist-assignment.expect.md
+23
-16
@@ -30,29 +30,36 @@ import { c as _c } from "react/compiler-runtime";
30
import { useMemo } from "react";
31
32
function useFoo(arr1, arr2) {
33
- const $ = _c(5);
33
+ const $ = _c(7);
34
+ let t0;
35
+ if ($[0] !== arr1) {
36
+ t0 = [arr1];
37
+ $[0] = arr1;
38
+ $[1] = t0;
39
+ } else {
40
+ t0 = $[1];
41
+ }
42
+ const x = t0;
43
let y;
35
- if ($[0] !== arr1 || $[1] !== arr2) {
36
- const x = [arr1];
37
-
44
+ if ($[2] !== arr2 || $[3] !== x) {
45
(y = x.concat(arr2)), y;
39
- $[0] = arr1;
40
- $[1] = arr2;
41
- $[2] = y;
46
+ $[2] = arr2;
47
+ $[3] = x;
48
+ $[4] = y;
49
} else {
43
- y = $[2];
50
+ y = $[4];
51
}
45
- let t0;
52
let t1;
47
- if ($[3] !== y) {
48
- t1 = { y };
49
- $[3] = y;
50
- $[4] = t1;
53
+ let t2;
54
+ if ($[5] !== y) {
55
+ t2 = { y };
56
+ $[5] = y;
57
+ $[6] = t2;
58
} else {
52
- t1 = $[4];
59
+ t2 = $[6];
60
}
54
- t0 = t1;
55
- return t0;
61
+ t1 = t2;
62
+ return t1;
63
}
64
65
export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/shared-hook-calls.expect.md
+45
-32
@@ -30,47 +30,60 @@ import { c as _c, useFire } from "react/compiler-runtime"; // @enableFire
30
import { fire } from "react";
31
32
function Component(t0) {
33
- const $ = _c(9);
34
- const { bar, baz } = t0;
35
- let t1;
36
- if ($[0] !== bar) {
37
- t1 = () => {
38
- console.log(bar);
39
- };
40
- $[0] = bar;
41
- $[1] = t1;
33
+ const $ = _c(13);
34
+ let bar;
35
+ let baz;
36
+ let foo;
37
+ if ($[0] !== t0) {
38
+ ({ bar, baz } = t0);
39
+ let t1;
40
+ if ($[4] !== bar) {
41
+ t1 = () => {
42
+ console.log(bar);
43
+ };
44
+ $[4] = bar;
45
+ $[5] = t1;
46
+ } else {
47
+ t1 = $[5];
48
+ }
49
+ foo = t1;
50
+ $[0] = t0;
51
+ $[1] = bar;
52
+ $[2] = baz;
53
+ $[3] = foo;
54
} else {
43
- t1 = $[1];
55
+ bar = $[1];
56
+ baz = $[2];
57
+ foo = $[3];
58
}
45
- const foo = t1;
46
- const t2 = useFire(foo);
47
- const t3 = useFire(baz);
48
- let t4;
49
- if ($[2] !== bar || $[3] !== t2 || $[4] !== t3) {
50
- t4 = () => {
59
+ const t1 = useFire(foo);
60
+ const t2 = useFire(baz);
61
+ let t3;
62
+ if ($[6] !== bar || $[7] !== t1 || $[8] !== t2) {
63
+ t3 = () => {
64
+ t1(bar);
65
t2(bar);
52
- t3(bar);
66
};
54
- $[2] = bar;
55
- $[3] = t2;
56
- $[4] = t3;
57
- $[5] = t4;
67
+ $[6] = bar;
68
+ $[7] = t1;
69
+ $[8] = t2;
70
+ $[9] = t3;
71
} else {
59
- t4 = $[5];
72
+ t3 = $[9];
73
}
61
- useEffect(t4);
62
- let t5;
63
- if ($[6] !== bar || $[7] !== t2) {
64
- t5 = () => {
65
- t2(bar);
74
+ useEffect(t3);
75
+ let t4;
76
+ if ($[10] !== bar || $[11] !== t1) {
77
+ t4 = () => {
78
+ t1(bar);
79
};
67
- $[6] = bar;
68
- $[7] = t2;
69
- $[8] = t5;
80
+ $[10] = bar;
81
+ $[11] = t1;
82
+ $[12] = t4;
83
} else {
71
- t5 = $[8];
84
+ t4 = $[12];
85
}
73
- useEffect(t5);
86
+ useEffect(t4);
87
return null;
88
}
89