@samitouri / QOS-React-1 / commits / b211d7023c

[compiler] Add repros for various invariants (#34099)

We received some bug reports about invariants reported by the compiler in their codebase. Adding them as repros. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34099). * #34100 * __->__ #34099

lauren committed Aug 4, 2025 at 14:36 UTC b211d7023c2f142aa21296bccba1de212d700c09
16 files changed +402
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-infer-mutation-aliasing-effects.expect.md new
+46
@@ -0,0 +1,46 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import {useCallback, useRef} from 'react';
6 +
7 +export default function useThunkDispatch(state, dispatch, extraArg) {
8 + const stateRef = useRef(state);
9 + stateRef.current = state;
10 +
11 + return useCallback(
12 + function thunk(action) {
13 + if (typeof action === 'function') {
14 + return action(thunk, () => stateRef.current, extraArg);
15 + } else {
16 + dispatch(action);
17 + return undefined;
18 + }
19 + },
20 + [dispatch, extraArg]
21 + );
22 +}
23 +
24 +```
25 +
26 +
27 +## Error
28 +
29 +```
30 +Found 1 error:
31 +
32 +Invariant: [InferMutationAliasingEffects] Expected value kind to be initialized
33 +
34 +<unknown> thunk$14.
35 +
36 +error.bug-infer-mutation-aliasing-effects.ts:10:22
37 + 8 | function thunk(action) {
38 + 9 | if (typeof action === 'function') {
39 +> 10 | return action(thunk, () => stateRef.current, extraArg);
40 + | ^^^^^ [InferMutationAliasingEffects] Expected value kind to be initialized
41 + 11 | } else {
42 + 12 | dispatch(action);
43 + 13 | return undefined;
44 +```
45 +
46 +
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-infer-mutation-aliasing-effects.js new
+18
@@ -0,0 +1,18 @@
1 +import {useCallback, useRef} from 'react';
2 +
3 +export default function useThunkDispatch(state, dispatch, extraArg) {
4 + const stateRef = useRef(state);
5 + stateRef.current = state;
6 +
7 + return useCallback(
8 + function thunk(action) {
9 + if (typeof action === 'function') {
10 + return action(thunk, () => stateRef.current, extraArg);
11 + } else {
12 + dispatch(action);
13 + return undefined;
14 + }
15 + },
16 + [dispatch, extraArg]
17 + );
18 +}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-invariant-codegen-methodcall.expect.md new
+31
@@ -0,0 +1,31 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +const YearsAndMonthsSince = () => {
6 + const diff = foo();
7 + const months = Math.floor(diff.bar());
8 + return <>{months}</>;
9 +};
10 +
11 +```
12 +
13 +
14 +## Error
15 +
16 +```
17 +Found 1 error:
18 +
19 +Invariant: [Codegen] Internal error: MethodCall::property must be an unpromoted + unmemoized MemberExpression. Got a `Identifier`
20 +
21 +error.bug-invariant-codegen-methodcall.ts:3:17
22 + 1 | const YearsAndMonthsSince = () => {
23 + 2 | const diff = foo();
24 +> 3 | const months = Math.floor(diff.bar());
25 + | ^^^^^^^^^^ [Codegen] Internal error: MethodCall::property must be an unpromoted + unmemoized MemberExpression. Got a `Identifier`
26 + 4 | return <>{months}</>;
27 + 5 | };
28 + 6 |
29 +```
30 +
31 +
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-invariant-codegen-methodcall.js new
+5
@@ -0,0 +1,5 @@
1 +const YearsAndMonthsSince = () => {
2 + const diff = foo();
3 + const months = Math.floor(diff.bar());
4 + return <>{months}</>;
5 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-invariant-couldnt-find-binding-for-decl.expect.md new
+37
@@ -0,0 +1,37 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import {useEffect} from 'react';
6 +
7 +export function Foo() {
8 + useEffect(() => {
9 + try {
10 + // do something
11 + } catch ({status}) {
12 + // do something
13 + }
14 + }, []);
15 +}
16 +
17 +```
18 +
19 +
20 +## Error
21 +
22 +```
23 +Found 1 error:
24 +
25 +Invariant: (BuildHIR::lowerAssignment) Could not find binding for declaration.
26 +
27 +error.bug-invariant-couldnt-find-binding-for-decl.ts:7:14
28 + 5 | try {
29 + 6 | // do something
30 +> 7 | } catch ({status}) {
31 + | ^^^^^^ (BuildHIR::lowerAssignment) Could not find binding for declaration.
32 + 8 | // do something
33 + 9 | }
34 + 10 | }, []);
35 +```
36 +
37 +
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-invariant-couldnt-find-binding-for-decl.js new
+11
@@ -0,0 +1,11 @@
1 +import {useEffect} from 'react';
2 +
3 +export function Foo() {
4 + useEffect(() => {
5 + try {
6 + // do something
7 + } catch ({status}) {
8 + // do something
9 + }
10 + }, []);
11 +}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-invariant-expected-break-target.expect.md new
+32
@@ -0,0 +1,32 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import {useMemo} from 'react';
6 +
7 +export default function useFoo(text) {
8 + return useMemo(() => {
9 + try {
10 + let formattedText = '';
11 + try {
12 + formattedText = format(text);
13 + } catch {
14 + console.log('error');
15 + }
16 + return formattedText || '';
17 + } catch (e) {}
18 + }, [text]);
19 +}
20 +
21 +```
22 +
23 +
24 +## Error
25 +
26 +```
27 +Found 1 error:
28 +
29 +Invariant: Expected a break target
30 +```
31 +
32 +
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-invariant-expected-break-target.js new
+15
@@ -0,0 +1,15 @@
1 +import {useMemo} from 'react';
2 +
3 +export default function useFoo(text) {
4 + return useMemo(() => {
5 + try {
6 + let formattedText = '';
7 + try {
8 + formattedText = format(text);
9 + } catch {
10 + console.log('error');
11 + }
12 + return formattedText || '';
13 + } catch (e) {}
14 + }, [text]);
15 +}
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-invariant-expected-consistent-destructuring.expect.md new
+44
@@ -0,0 +1,44 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import {useMemo} from 'react';
6 +import {useFoo, formatB, Baz} from './lib';
7 +
8 +export const Example = ({data}) => {
9 + let a;
10 + let b;
11 +
12 + if (data) {
13 + ({a, b} = data);
14 + }
15 +
16 + const foo = useFoo(a);
17 + const bar = useMemo(() => formatB(b), [b]);
18 +
19 + return <Baz foo={foo} bar={bar} />;
20 +};
21 +
22 +```
23 +
24 +
25 +## Error
26 +
27 +```
28 +Found 1 error:
29 +
30 +Invariant: Expected consistent kind for destructuring
31 +
32 +Other places were `Reassign` but 'mutate? #t8$46[7:9]{reactive}' is const.
33 +
34 +error.bug-invariant-expected-consistent-destructuring.ts:9:9
35 + 7 |
36 + 8 | if (data) {
37 +> 9 | ({a, b} = data);
38 + | ^ Expected consistent kind for destructuring
39 + 10 | }
40 + 11 |
41 + 12 | const foo = useFoo(a);
42 +```
43 +
44 +
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-invariant-expected-consistent-destructuring.js new
+16
@@ -0,0 +1,16 @@
1 +import {useMemo} from 'react';
2 +import {useFoo, formatB, Baz} from './lib';
3 +
4 +export const Example = ({data}) => {
5 + let a;
6 + let b;
7 +
8 + if (data) {
9 + ({a, b} = data);
10 + }
11 +
12 + const foo = useFoo(a);
13 + const bar = useMemo(() => formatB(b), [b]);
14 +
15 + return <Baz foo={foo} bar={bar} />;
16 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-invariant-local-or-context-references.expect.md new
+46
@@ -0,0 +1,46 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import {useState} from 'react';
6 +import {bar} from './bar';
7 +
8 +export const useFoot = () => {
9 + const [, setState] = useState(null);
10 + try {
11 + const {data} = bar();
12 + setState({
13 + data,
14 + error: null,
15 + });
16 + } catch (err) {
17 + setState(_prevState => ({
18 + loading: false,
19 + error: err,
20 + }));
21 + }
22 +};
23 +
24 +```
25 +
26 +
27 +## Error
28 +
29 +```
30 +Found 1 error:
31 +
32 +Invariant: Expected all references to a variable to be consistently local or context references
33 +
34 +Identifier <unknown> err$7 is referenced as a context variable, but was previously referenced as a [object Object] variable.
35 +
36 +error.bug-invariant-local-or-context-references.ts:15:13
37 + 13 | setState(_prevState => ({
38 + 14 | loading: false,
39 +> 15 | error: err,
40 + | ^^^ Expected all references to a variable to be consistently local or context references
41 + 16 | }));
42 + 17 | }
43 + 18 | };
44 +```
45 +
46 +
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-invariant-local-or-context-references.js new
+18
@@ -0,0 +1,18 @@
1 +import {useState} from 'react';
2 +import {bar} from './bar';
3 +
4 +export const useFoot = () => {
5 + const [, setState] = useState(null);
6 + try {
7 + const {data} = bar();
8 + setState({
9 + data,
10 + error: null,
11 + });
12 + } catch (err) {
13 + setState(_prevState => ({
14 + loading: false,
15 + error: err,
16 + }));
17 + }
18 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-invariant-unexpected-terminal-in-optional.expect.md new
+34
@@ -0,0 +1,34 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +const Foo = ({json}) => {
6 + try {
7 + const foo = JSON.parse(json)?.foo;
8 + return <span>{foo}</span>;
9 + } catch {
10 + return null;
11 + }
12 +};
13 +
14 +```
15 +
16 +
17 +## Error
18 +
19 +```
20 +Found 1 error:
21 +
22 +Invariant: Unexpected terminal in optional
23 +
24 +error.bug-invariant-unexpected-terminal-in-optional.ts:3:16
25 + 1 | const Foo = ({json}) => {
26 + 2 | try {
27 +> 3 | const foo = JSON.parse(json)?.foo;
28 + | ^^^^ Unexpected terminal in optional
29 + 4 | return <span>{foo}</span>;
30 + 5 | } catch {
31 + 6 | return null;
32 +```
33 +
34 +
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-invariant-unexpected-terminal-in-optional.js new
+8
@@ -0,0 +1,8 @@
1 +const Foo = ({json}) => {
2 + try {
3 + const foo = JSON.parse(json)?.foo;
4 + return <span>{foo}</span>;
5 + } catch {
6 + return null;
7 + }
8 +};
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-invariant-unnamed-temporary.expect.md new
+30
@@ -0,0 +1,30 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import Bar from './Bar';
6 +
7 +export function Foo() {
8 + return (
9 + <Bar
10 + renderer={(...props) => {
11 + return <span {...props}>{displayValue}</span>;
12 + }}
13 + />
14 + );
15 +}
16 +
17 +```
18 +
19 +
20 +## Error
21 +
22 +```
23 +Found 1 error:
24 +
25 +Invariant: Expected temporaries to be promoted to named identifiers in an earlier pass
26 +
27 +identifier 15 is unnamed.
28 +```
29 +
30 +
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.bug-invariant-unnamed-temporary.js new
+11
@@ -0,0 +1,11 @@
1 +import Bar from './Bar';
2 +
3 +export function Foo() {
4 + return (
5 + <Bar
6 + renderer={(...props) => {
7 + return <span {...props}>{displayValue}</span>;
8 + }}
9 + />
10 + );
11 +}