Skip to content

Commit 8e10196

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents 38f28c2 + b4a8d29 commit 8e10196

File tree

12 files changed

+189
-131
lines changed

12 files changed

+189
-131
lines changed

compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,7 @@ export type StartMemoize = {
826826
* emitting diagnostics with a suggested replacement
827827
*/
828828
depsLoc: SourceLocation | null;
829+
hasInvalidDeps?: true;
829830
loc: SourceLocation;
830831
};
831832
export type FinishMemoize = {

compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateExhaustiveDependencies.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ export function validateExhaustiveDependencies(fn: HIRFunction): void {
143143
);
144144
if (diagnostic != null) {
145145
fn.env.recordError(diagnostic);
146+
startMemo.hasInvalidDeps = true;
146147
}
147148
}
148149

compiler/packages/babel-plugin-react-compiler/src/Validation/ValidatePreservedManualMemoization.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -486,16 +486,25 @@ class Visitor extends ReactiveFunctionVisitor<VisitorState> {
486486
ids.add(value.place.identifier);
487487
}
488488
if (value.kind === 'StartMemoize') {
489-
let depsFromSource: Array<ManualMemoDependency> | null = null;
490-
if (value.deps != null) {
491-
depsFromSource = value.deps;
492-
}
493489
CompilerError.invariant(state.manualMemoState == null, {
494490
reason: 'Unexpected nested StartMemoize instructions',
495491
description: `Bad manual memoization ids: ${state.manualMemoState?.manualMemoId}, ${value.manualMemoId}`,
496492
loc: value.loc,
497493
});
498494

495+
if (value.hasInvalidDeps === true) {
496+
/*
497+
* ValidateExhaustiveDependencies already reported an error for this
498+
* memo block, skip validation to avoid duplicate errors
499+
*/
500+
return;
501+
}
502+
503+
let depsFromSource: Array<ManualMemoDependency> | null = null;
504+
if (value.deps != null) {
505+
depsFromSource = value.deps;
506+
}
507+
499508
state.manualMemoState = {
500509
loc: instruction.loc,
501510
decls: new Set(),
@@ -547,12 +556,15 @@ class Visitor extends ReactiveFunctionVisitor<VisitorState> {
547556
}
548557
}
549558
if (value.kind === 'FinishMemoize') {
559+
if (state.manualMemoState == null) {
560+
// StartMemoize had invalid deps, skip validation
561+
return;
562+
}
550563
CompilerError.invariant(
551-
state.manualMemoState != null &&
552-
state.manualMemoState.manualMemoId === value.manualMemoId,
564+
state.manualMemoState.manualMemoId === value.manualMemoId,
553565
{
554566
reason: 'Unexpected mismatch between StartMemoize and FinishMemoize',
555-
description: `Encountered StartMemoize id=${state.manualMemoState?.manualMemoId} followed by FinishMemoize id=${value.manualMemoId}`,
567+
description: `Encountered StartMemoize id=${state.manualMemoState.manualMemoId} followed by FinishMemoize id=${value.manualMemoId}`,
556568
loc: value.loc,
557569
},
558570
);

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-ReactUseMemo-async-callback.expect.md

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function component(a, b) {
1515
## Error
1616

1717
```
18-
Found 3 errors:
18+
Found 2 errors:
1919
2020
Error: useMemo() callbacks may not be async or generator functions
2121
@@ -47,22 +47,6 @@ error.invalid-ReactUseMemo-async-callback.ts:3:10
4747
6 | }
4848
4949
Inferred dependencies: `[a]`
50-
51-
Compilation Skipped: Existing memoization could not be preserved
52-
53-
React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `a`, but the source dependencies were []. Inferred dependency not present in source.
54-
55-
error.invalid-ReactUseMemo-async-callback.ts:2:24
56-
1 | function component(a, b) {
57-
> 2 | let x = React.useMemo(async () => {
58-
| ^^^^^^^^^^^^^
59-
> 3 | await a;
60-
| ^^^^^^^^^^^^
61-
> 4 | }, []);
62-
| ^^^^ Could not preserve existing manual memoization
63-
5 | return x;
64-
6 | }
65-
7 |
6650
```
6751
6852

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-useMemo-async-callback.expect.md

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function component(a, b) {
1515
## Error
1616

1717
```
18-
Found 3 errors:
18+
Found 2 errors:
1919
2020
Error: useMemo() callbacks may not be async or generator functions
2121
@@ -47,22 +47,6 @@ error.invalid-useMemo-async-callback.ts:3:10
4747
6 | }
4848
4949
Inferred dependencies: `[a]`
50-
51-
Compilation Skipped: Existing memoization could not be preserved
52-
53-
React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `a`, but the source dependencies were []. Inferred dependency not present in source.
54-
55-
error.invalid-useMemo-async-callback.ts:2:18
56-
1 | function component(a, b) {
57-
> 2 | let x = useMemo(async () => {
58-
| ^^^^^^^^^^^^^
59-
> 3 | await a;
60-
| ^^^^^^^^^^^^
61-
> 4 | }, []);
62-
| ^^^^ Could not preserve existing manual memoization
63-
5 | return x;
64-
6 | }
65-
7 |
6650
```
6751
6852

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-useMemo-callback-args.expect.md

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function component(a, b) {
1313
## Error
1414

1515
```
16-
Found 3 errors:
16+
Found 2 errors:
1717
1818
Error: useMemo() callbacks may not accept parameters
1919
@@ -40,18 +40,6 @@ error.invalid-useMemo-callback-args.ts:2:23
4040
5 |
4141
4242
Inferred dependencies: `[a]`
43-
44-
Compilation Skipped: Existing memoization could not be preserved
45-
46-
React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `a`, but the source dependencies were []. Inferred dependency not present in source.
47-
48-
error.invalid-useMemo-callback-args.ts:2:18
49-
1 | function component(a, b) {
50-
> 2 | let x = useMemo(c => a, []);
51-
| ^^^^^^ Could not preserve existing manual memoization
52-
3 | return x;
53-
4 | }
54-
5 |
5543
```
5644
5745

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-exhaustive-deps.expect.md

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function Component({x, y, z}) {
5151
## Error
5252
5353
```
54-
Found 6 errors:
54+
Found 4 errors:
5555

5656
Error: Found missing/extra memoization dependencies
5757

@@ -157,48 +157,6 @@ error.invalid-exhaustive-deps.ts:37:13
157157
40 | }, []);
158158

159159
Inferred dependencies: `[ref]`
160-
161-
Compilation Skipped: Existing memoization could not be preserved
162-
163-
React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `x.y.z.a.b`, but the source dependencies were [x?.y.z.a?.b.z]. Inferred different dependency than source.
164-
165-
error.invalid-exhaustive-deps.ts:14:20
166-
12 | // ok, not our job to type check nullability
167-
13 | }, [x.y.z.a]);
168-
> 14 | const c = useMemo(() => {
169-
| ^^^^^^^
170-
> 15 | return x?.y.z.a?.b;
171-
| ^^^^^^^^^^^^^^^^^^^^^^^
172-
> 16 | // error: too precise
173-
| ^^^^^^^^^^^^^^^^^^^^^^^
174-
> 17 | }, [x?.y.z.a?.b.z]);
175-
| ^^^^ Could not preserve existing manual memoization
176-
18 | const d = useMemo(() => {
177-
19 | return x?.y?.[(console.log(y), z?.b)];
178-
20 | // ok
179-
180-
Compilation Skipped: Existing memoization could not be preserved
181-
182-
React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `ref`, but the source dependencies were []. Inferred dependency not present in source.
183-
184-
error.invalid-exhaustive-deps.ts:35:21
185-
33 | const ref2 = useRef(null);
186-
34 | const ref = z ? ref1 : ref2;
187-
> 35 | const cb = useMemo(() => {
188-
| ^^^^^^^
189-
> 36 | return () => {
190-
| ^^^^^^^^^^^^^^^^^^
191-
> 37 | return ref.current;
192-
| ^^^^^^^^^^^^^^^^^^
193-
> 38 | };
194-
| ^^^^^^^^^^^^^^^^^^
195-
> 39 | // error: ref is a stable type but reactive
196-
| ^^^^^^^^^^^^^^^^^^
197-
> 40 | }, []);
198-
| ^^^^ Could not preserve existing manual memoization
199-
41 | return <Stringify results={[a, b, c, d, e, f, cb]} />;
200-
42 | }
201-
43 |
202160
```
203161
204162

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/exhaustive-deps/error.invalid-missing-nonreactive-dep-unmemoized.expect.md

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function useHook() {
2222
## Error
2323

2424
```
25-
Found 2 errors:
25+
Found 1 error:
2626
2727
Error: Found missing memoization dependencies
2828
@@ -38,19 +38,6 @@ error.invalid-missing-nonreactive-dep-unmemoized.ts:11:31
3838
14 |
3939
4040
Inferred dependencies: `[object]`
41-
42-
Compilation Skipped: Existing memoization could not be preserved
43-
44-
React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `object`, but the source dependencies were []. Inferred dependency not present in source.
45-
46-
error.invalid-missing-nonreactive-dep-unmemoized.ts:11:24
47-
9 | useIdentity();
48-
10 | object.x = 0;
49-
> 11 | const array = useMemo(() => [object], []);
50-
| ^^^^^^^^^^^^^^ Could not preserve existing manual memoization
51-
12 | return array;
52-
13 | }
53-
14 |
5441
```
5542
5643

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.useMemo-unrelated-mutation-in-depslist.expect.md

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ function useFoo(input1) {
3030
## Error
3131

3232
```
33-
Found 2 errors:
33+
Found 1 error:
3434
3535
Error: Found missing memoization dependencies
3636
@@ -46,23 +46,6 @@ error.useMemo-unrelated-mutation-in-depslist.ts:18:14
4646
21 | }
4747
4848
Inferred dependencies: `[x, y]`
49-
50-
Compilation Skipped: Existing memoization could not be preserved
51-
52-
React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected. The inferred dependency was `input1`, but the source dependencies were [y]. Inferred different dependency than source.
53-
54-
error.useMemo-unrelated-mutation-in-depslist.ts:16:27
55-
14 | const x = {};
56-
15 | const y = [input1];
57-
> 16 | const memoized = useMemo(() => {
58-
| ^^^^^^^
59-
> 17 | return [y];
60-
| ^^^^^^^^^^^^^^^
61-
> 18 | }, [(mutate(x), y)]);
62-
| ^^^^ Could not preserve existing manual memoization
63-
19 |
64-
20 | return [x, memoized];
65-
21 | }
6649
```
6750
6851

0 commit comments

Comments
 (0)