Fix missing memoization of scope-less variable being reassigned
Joe Savona committed
Jun 7, 2023 at 22:15 UTC
8192cd253d340554d151f853ed80626ce63dbca2
4 files changed
+98
-7
compiler/forget/packages/babel-plugin-react-forget/src/ReactiveScopes/PropagateScopeDependencies.ts
+3
-6
@@ -419,15 +419,12 @@ class Context {
419
* current one as a {@link ReactiveScope.reassignments}
420
*/
421
visitReassignment(place: Place): void {
422
- const declaration = this.#declarations.get(place.identifier.id);
422
if (
423
this.currentScope.value != null &&
425
- place.identifier.scope != null &&
426
- declaration !== undefined &&
427
- declaration.scope.value !== place.identifier.scope &&
424
!Array.from(this.currentScope.value.reassignments).some(
429
- (ident) => ident.id === place.identifier.id
430
- )
425
+ (identifier) => identifier.id === place.identifier.id
426
+ ) &&
427
+ this.#checkValidDependency({ identifier: place.identifier, path: [] })
428
) {
429
this.currentScope.value.reassignments.add(place.identifier);
430
}
compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-reassign-to-variable-without-mutable-range.expect.md
new
+81
@@ -0,0 +1,81 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @debug
6
+function Component(a, b) {
7
+ let x = [];
8
+ let y = [];
9
+ let z = foo(a);
10
+ if (FLAG) {
11
+ x = bar(z);
12
+ y = baz(b);
13
+ }
14
+ return [x, y];
15
+}
16
+
17
+```
18
+
19
+## Code
20
+
21
+```javascript
22
+import { unstable_useMemoCache as useMemoCache } from "react"; // @debug
23
+function Component(a, b) {
24
+ const $ = useMemoCache(11);
25
+ let t0;
26
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
27
+ t0 = [];
28
+ $[0] = t0;
29
+ } else {
30
+ t0 = $[0];
31
+ }
32
+ let x = t0;
33
+ let t1;
34
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
35
+ t1 = [];
36
+ $[1] = t1;
37
+ } else {
38
+ t1 = $[1];
39
+ }
40
+ let y = t1;
41
+ const c_2 = $[2] !== a;
42
+ const c_3 = $[3] !== b;
43
+ if (c_2 || c_3) {
44
+ const z = foo(a);
45
+ if (FLAG) {
46
+ x = bar(z);
47
+ const c_6 = $[6] !== b;
48
+ let t2;
49
+ if (c_6) {
50
+ t2 = baz(b);
51
+ $[6] = b;
52
+ $[7] = t2;
53
+ } else {
54
+ t2 = $[7];
55
+ }
56
+ y = t2;
57
+ }
58
+ $[2] = a;
59
+ $[3] = b;
60
+ $[4] = x;
61
+ $[5] = y;
62
+ } else {
63
+ x = $[4];
64
+ y = $[5];
65
+ }
66
+ const c_8 = $[8] !== x;
67
+ const c_9 = $[9] !== y;
68
+ let t3;
69
+ if (c_8 || c_9) {
70
+ t3 = [x, y];
71
+ $[8] = x;
72
+ $[9] = y;
73
+ $[10] = t3;
74
+ } else {
75
+ t3 = $[10];
76
+ }
77
+ return t3;
78
+}
79
+
80
+```
81
+
\ No newline at end of file
compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-reassign-to-variable-without-mutable-range.js
new
+11
@@ -0,0 +1,11 @@
1
+// @debug
2
+function Component(a, b) {
3
+ let x = [];
4
+ let y = [];
5
+ let z = foo(a);
6
+ if (FLAG) {
7
+ x = bar(z);
8
+ y = baz(b);
9
+ }
10
+ return [x, y];
11
+}
compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ssa-cascading-eliminated-phis.expect.md
+3
-1
@@ -25,7 +25,7 @@ function Component(props) {
25
```javascript
26
import { unstable_useMemoCache as useMemoCache } from "react";
27
function Component(props) {
28
- const $ = useMemoCache(2);
28
+ const $ = useMemoCache(3);
29
let x = 0;
30
const c_0 = $[0] !== props;
31
let values;
@@ -45,8 +45,10 @@ function Component(props) {
45
values.push(x);
46
$[0] = props;
47
$[1] = values;
48
+ $[2] = x;
49
} else {
50
values = $[1];
51
+ x = $[2];
52
}
53
return values;
54
}