From f4ff1a28e714a2d013615a142257523ea9da17cf Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Fri, 22 Mar 2024 14:32:50 -0700 Subject: [PATCH] Fix for destructuring with partial context variables --- .../src/HIR/BuildHIR.ts | 7 +- ...incompatible-destructuring-kinds.expect.md | 35 ---------- ...incompatible-destructuring-kinds.expect.md | 67 +++++++++++++++++++ ...js => incompatible-destructuring-kinds.js} | 1 + 4 files changed, 74 insertions(+), 36 deletions(-) delete mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-incompatible-destructuring-kinds.expect.md create mode 100644 compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/incompatible-destructuring-kinds.expect.md rename compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/{error.todo-incompatible-destructuring-kinds.js => incompatible-destructuring-kinds.js} (81%) diff --git a/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts index 33158cbbd6..e2f4a6fbe3 100644 --- a/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts @@ -3434,7 +3434,12 @@ function lowerAssignment( */ const forceTemporaries = kind === InstructionKind.Reassign && - elements.some((element) => !element.isIdentifier()); + (elements.some((element) => !element.isIdentifier()) || + elements.some( + (element) => + element.isIdentifier() && + getStoreKind(builder, element) !== "StoreLocal" + )); for (let i = 0; i < elements.length; i++) { const element = elements[i]; if (element.node == null) { diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-incompatible-destructuring-kinds.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-incompatible-destructuring-kinds.expect.md deleted file mode 100644 index cd038eff52..0000000000 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-incompatible-destructuring-kinds.expect.md +++ /dev/null @@ -1,35 +0,0 @@ - -## Input - -```javascript -import { useMemo } from "react"; -import { Stringify } from "shared-runtime"; - -function Component({}) { - let a = "a"; - let b = ""; - [a, b] = [null, null]; - return a} />; -} - -export const FIXTURE_ENTRYPOINT = { - fn: Component, - params: [{}], -}; - -``` - - -## Error - -``` - 5 | let a = "a"; - 6 | let b = ""; -> 7 | [a, b] = [null, null]; - | ^ [ReactForget] Invariant: Expected consistent kind for destructuring. Other places were 'Const' but 'store b$36[10:12]' is reassigned (7:7) - 8 | return a} />; - 9 | } - 10 | -``` - - \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/incompatible-destructuring-kinds.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/incompatible-destructuring-kinds.expect.md new file mode 100644 index 0000000000..82011dc03e --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/incompatible-destructuring-kinds.expect.md @@ -0,0 +1,67 @@ + +## Input + +```javascript +import { useMemo } from "react"; +import { Stringify } from "shared-runtime"; + +function Component({}) { + let a = "a"; + let b = ""; + [a, b] = [null, null]; + // NOTE: reference `a` in a callback to force a context variable + return a} />; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + +``` + +## Code + +```javascript +import { useMemo, unstable_useMemoCache as useMemoCache } from "react"; +import { Stringify } from "shared-runtime"; + +function Component(t0) { + const $ = useMemoCache(4); + let t1; + let a; + let b; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + a = "a"; + + const [t2, t3] = [null, null]; + t1 = t3; + a = t2; + $[0] = t1; + $[1] = a; + $[2] = b; + } else { + t1 = $[0]; + a = $[1]; + b = $[2]; + } + b = t1; + let t2; + if ($[3] === Symbol.for("react.memo_cache_sentinel")) { + t2 = a} />; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + +``` + +### Eval output +(kind: ok)
{"a":null,"b":"[[ cyclic ref *1 ]]","onClick":"[[ function params=0 ]]"}
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-incompatible-destructuring-kinds.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/incompatible-destructuring-kinds.js similarity index 81% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-incompatible-destructuring-kinds.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/incompatible-destructuring-kinds.js index 80ec7e3526..a77476c6b8 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-incompatible-destructuring-kinds.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/incompatible-destructuring-kinds.js @@ -5,6 +5,7 @@ function Component({}) { let a = "a"; let b = ""; [a, b] = [null, null]; + // NOTE: reference `a` in a callback to force a context variable return a} />; }