@samitouri / QOS-React / commits / f4ff1a28e7

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