Fix for destructuring with partial context variables
Joe Savona committed
Mar 22, 2024 at 14:32 UTC
f4ff1a28e714a2d013615a142257523ea9da17cf
4 files changed
+74
-36
compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts
+6
-1
@@ -3434,7 +3434,12 @@ function lowerAssignment(
3434
*/
3435
const forceTemporaries =
3436
kind === InstructionKind.Reassign &&
3437
- elements.some((element) => !element.isIdentifier());
3437
+ (elements.some((element) => !element.isIdentifier()) ||
3438
+ elements.some(
3439
+ (element) =>
3440
+ element.isIdentifier() &&
3441
+ getStoreKind(builder, element) !== "StoreLocal"
3442
+ ));
3443
for (let i = 0; i < elements.length; i++) {
3444
const element = elements[i];
3445
if (element.node == null) {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-incompatible-destructuring-kinds.expect.md
deleted
-35
@@ -1,35 +0,0 @@
1
-
2
-## Input
3
-
4
-```javascript
5
-import { useMemo } from "react";
6
-import { Stringify } from "shared-runtime";
7
-
8
-function Component({}) {
9
- let a = "a";
10
- let b = "";
11
- [a, b] = [null, null];
12
- return <Stringify a={a} b={b} onClick={() => a} />;
13
-}
14
-
15
-export const FIXTURE_ENTRYPOINT = {
16
- fn: Component,
17
- params: [{}],
18
-};
19
-
20
-```
21
-
22
-
23
-## Error
24
-
25
-```
26
- 5 | let a = "a";
27
- 6 | let b = "";
28
-> 7 | [a, b] = [null, null];
29
- | ^ [ReactForget] Invariant: Expected consistent kind for destructuring. Other places were 'Const' but 'store b$36[10:12]' is reassigned (7:7)
30
- 8 | return <Stringify a={a} b={b} onClick={() => a} />;
31
- 9 | }
32
- 10 |
33
-```
34
-
35
-
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/incompatible-destructuring-kinds.expect.md
new
+67
@@ -0,0 +1,67 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+import { useMemo } from "react";
6
+import { Stringify } from "shared-runtime";
7
+
8
+function Component({}) {
9
+ let a = "a";
10
+ let b = "";
11
+ [a, b] = [null, null];
12
+ // NOTE: reference `a` in a callback to force a context variable
13
+ return <Stringify a={a} b={b} onClick={() => a} />;
14
+}
15
+
16
+export const FIXTURE_ENTRYPOINT = {
17
+ fn: Component,
18
+ params: [{}],
19
+};
20
+
21
+```
22
+
23
+## Code
24
+
25
+```javascript
26
+import { useMemo, unstable_useMemoCache as useMemoCache } from "react";
27
+import { Stringify } from "shared-runtime";
28
+
29
+function Component(t0) {
30
+ const $ = useMemoCache(4);
31
+ let t1;
32
+ let a;
33
+ let b;
34
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
35
+ a = "a";
36
+
37
+ const [t2, t3] = [null, null];
38
+ t1 = t3;
39
+ a = t2;
40
+ $[0] = t1;
41
+ $[1] = a;
42
+ $[2] = b;
43
+ } else {
44
+ t1 = $[0];
45
+ a = $[1];
46
+ b = $[2];
47
+ }
48
+ b = t1;
49
+ let t2;
50
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
51
+ t2 = <Stringify a={a} b={b} onClick={() => a} />;
52
+ $[3] = t2;
53
+ } else {
54
+ t2 = $[3];
55
+ }
56
+ return t2;
57
+}
58
+
59
+export const FIXTURE_ENTRYPOINT = {
60
+ fn: Component,
61
+ params: [{}],
62
+};
63
+
64
+```
65
+
66
+### Eval output
67
+(kind: ok) <div>{"a":null,"b":"[[ cyclic ref *1 ]]","onClick":"[[ function params=0 ]]"}</div>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/incompatible-destructuring-kinds.js
renamed
+1
@@ -5,6 +5,7 @@ function Component({}) {
5
let a = "a";
6
let b = "";
7
[a, b] = [null, null];
8
+ // NOTE: reference `a` in a callback to force a context variable
9
return <Stringify a={a} b={b} onClick={() => a} />;
10
}
11