From 5ab54718a52d738dcbd03fcb43a556993b445ed4 Mon Sep 17 00:00:00 2001 From: Joseph Savona <6425824+josephsavona@users.noreply.github.com> Date: Thu, 16 May 2024 17:29:05 -0700 Subject: [PATCH] compiler: merge reactive scopes across const StoreLocal (#29095) @jbonta nerd-sniped me into making this optimization during conference prep, posting this as a PR now that keynote is over. Consider these two cases: ```javascript export default function MyApp1({ count }) { const cb = () => count; return
Hello World
; } export default function MyApp2({ count }) { return
count}>Hello World
; } ``` Previously, the former would create two reactive scopes (one for `cb`, one for the div) while the latter would only have a single scope for the `div` and its inline callback. The reason we created separate scopes before is that there's a `StoreLocal 'cb' = t0` instruction in-between, and i had conservatively implemented the merging pass to not allow intervening StoreLocal instructions. The observation is that intervening StoreLocals are fine _if_ the assigned variable's last usage is the next scope. We already have a check that the intervening lvalues are last-used at/before the next scope, so it's trivial to extend this to support StoreLocal. Note that we already don't merge scopes if there are intervening terminals, so we don't have to worry about things like conditional StoreLocal, conditional access of the resulting value, etc. --- ...rgeReactiveScopesThatInvalidateTogether.ts | 29 +++++++ .../alias-nested-member-path.expect.md | 17 ++-- .../array-map-frozen-array-noAlias.expect.md | 15 +--- .../compiler/array-map-frozen-array.expect.md | 15 +--- ...le-array-mutating-lambda-noAlias.expect.md | 20 ++--- ...ap-mutable-array-mutating-lambda.expect.md | 20 ++--- ...-into-function-expression-global.expect.md | 16 ++-- ...ng-scopes-store-const-used-later.expect.md | 70 ++++++++++++++++ ...erlapping-scopes-store-const-used-later.js | 14 ++++ ...s-with-intermediate-reassignment.expect.md | 80 +++++++++++++++++++ ...g-scopes-with-intermediate-reassignment.js | 19 +++++ .../compiler/for-of-continue.expect.md | 17 ++-- ...ing-recursive-call-within-lambda.expect.md | 16 ++-- .../compiler/hoisting-within-lambda.expect.md | 16 ++-- .../jsx-local-tag-in-lambda.expect.md | 16 ++-- .../jsx-memberexpr-tag-in-lambda.expect.md | 16 ++-- .../maybe-mutate-object-in-callback.expect.md | 32 +++----- ...ange-shared-inner-outer-function.expect.md | 16 ++-- .../fixtures/compiler/ssa-property.expect.md | 17 ++-- .../compiler/ssa-reassign-in-rval.expect.md | 20 ++--- ...catch-within-function-expression.expect.md | 16 ++-- .../compiler/type-test-polymorphic.expect.md | 18 ++--- 22 files changed, 304 insertions(+), 211 deletions(-) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-store-const-used-later.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-store-const-used-later.js create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-with-intermediate-reassignment.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-with-intermediate-reassignment.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts index 46f9b80ac9..495d4945df 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/MergeReactiveScopesThatInvalidateTogether.ts @@ -9,6 +9,7 @@ import { CompilerError } from ".."; import { IdentifierId, InstructionId, + InstructionKind, Place, ReactiveBlock, ReactiveFunction, @@ -20,6 +21,7 @@ import { ReactiveStatement, makeInstructionId, } from "../HIR"; +import { eachInstructionLValue } from "../HIR/visitors"; import { assertExhaustive } from "../Utils/utils"; import { printReactiveScopeSummary } from "./PrintReactiveFunction"; import { @@ -186,6 +188,33 @@ class Transform extends ReactiveFunctionTransform item); + const y = x.map((item) => item); + t1 = [x, y]; $[1] = t1; } else { t1 = $[1]; } - const y = t1; - let t2; - if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - t2 = [x, y]; - $[2] = t2; - } else { - t2 = $[2]; - } - return t2; + return t1; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-map-frozen-array.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-map-frozen-array.expect.md index fcc611025b..375556bbea 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-map-frozen-array.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-map-frozen-array.expect.md @@ -22,7 +22,7 @@ export const FIXTURE_ENTRYPOINT = { ```javascript import { c as _c } from "react/compiler-runtime"; function Component(props) { - const $ = _c(3); + const $ = _c(2); let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { t0 = []; @@ -33,20 +33,13 @@ function Component(props) { const x = t0; let t1; if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t1 = x.map((item) => item); + const y = x.map((item) => item); + t1 = [x, y]; $[1] = t1; } else { t1 = $[1]; } - const y = t1; - let t2; - if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - t2 = [x, y]; - $[2] = t2; - } else { - t2 = $[2]; - } - return t2; + return t1; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-map-mutable-array-mutating-lambda-noAlias.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-map-mutable-array-mutating-lambda-noAlias.expect.md index e8ac88343f..96f3b935e1 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-map-mutable-array-mutating-lambda-noAlias.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-map-mutable-array-mutating-lambda-noAlias.expect.md @@ -24,30 +24,20 @@ export const FIXTURE_ENTRYPOINT = { ```javascript import { c as _c } from "react/compiler-runtime"; function Component(props) { - const $ = _c(3); + const $ = _c(1); let t0; - let x; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - x = []; - t0 = x.map((item) => { + const x = []; + const y = x.map((item) => { item.updated = true; return item; }); + t0 = [x, y]; $[0] = t0; - $[1] = x; } else { t0 = $[0]; - x = $[1]; } - const y = t0; - let t1; - if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - t1 = [x, y]; - $[2] = t1; - } else { - t1 = $[2]; - } - return t1; + return t0; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-map-mutable-array-mutating-lambda.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-map-mutable-array-mutating-lambda.expect.md index e8ac88343f..96f3b935e1 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-map-mutable-array-mutating-lambda.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/array-map-mutable-array-mutating-lambda.expect.md @@ -24,30 +24,20 @@ export const FIXTURE_ENTRYPOINT = { ```javascript import { c as _c } from "react/compiler-runtime"; function Component(props) { - const $ = _c(3); + const $ = _c(1); let t0; - let x; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - x = []; - t0 = x.map((item) => { + const x = []; + const y = x.map((item) => { item.updated = true; return item; }); + t0 = [x, y]; $[0] = t0; - $[1] = x; } else { t0 = $[0]; - x = $[1]; } - const y = t0; - let t1; - if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - t1 = [x, y]; - $[2] = t1; - } else { - t1 = $[2]; - } - return t1; + return t0; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/const-propagation-into-function-expression-global.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/const-propagation-into-function-expression-global.expect.md index ff45ef6e28..e42ea8ce93 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/const-propagation-into-function-expression-global.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/const-propagation-into-function-expression-global.expect.md @@ -18,23 +18,17 @@ function foo() { ```javascript import { c as _c } from "react/compiler-runtime"; function foo() { - const $ = _c(2); + const $ = _c(1); let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = () => ; + const getJSX = () => ; + + t0 = getJSX(); $[0] = t0; } else { t0 = $[0]; } - const getJSX = t0; - let t1; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t1 = getJSX(); - $[1] = t1; - } else { - t1 = $[1]; - } - const result = t1; + const result = t0; return result; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-store-const-used-later.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-store-const-used-later.expect.md new file mode 100644 index 0000000000..ccbd69e840 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-store-const-used-later.expect.md @@ -0,0 +1,70 @@ + +## Input + +```javascript +import { Stringify, makeObject_Primitives } from "shared-runtime"; + +function Component(props) { + const array = [props.count]; + const x = makeObject_Primitives(); + const element =
{array}
; + console.log(x); + return
{element}
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ count: 42 }], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +import { Stringify, makeObject_Primitives } from "shared-runtime"; + +function Component(props) { + const $ = _c(6); + let t0; + if ($[0] !== props.count) { + t0 = [props.count]; + $[0] = props.count; + $[1] = t0; + } else { + t0 = $[1]; + } + const array = t0; + const x = makeObject_Primitives(); + let t1; + if ($[2] !== array) { + t1 =
{array}
; + $[2] = array; + $[3] = t1; + } else { + t1 = $[3]; + } + const element = t1; + console.log(x); + let t2; + if ($[4] !== element) { + t2 =
{element}
; + $[4] = element; + $[5] = t2; + } else { + t2 = $[5]; + } + return t2; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ count: 42 }], +}; + +``` + +### Eval output +(kind: ok)
42
+logs: [{ a: 0, b: 'value1', c: true }] \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-store-const-used-later.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-store-const-used-later.js new file mode 100644 index 0000000000..d55d863a83 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-store-const-used-later.js @@ -0,0 +1,14 @@ +import { Stringify, makeObject_Primitives } from "shared-runtime"; + +function Component(props) { + const array = [props.count]; + const x = makeObject_Primitives(); + const element =
{array}
; + console.log(x); + return
{element}
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ count: 42 }], +}; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-with-intermediate-reassignment.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-with-intermediate-reassignment.expect.md new file mode 100644 index 0000000000..7325cd29d3 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-with-intermediate-reassignment.expect.md @@ -0,0 +1,80 @@ + +## Input + +```javascript +import { Stringify } from "shared-runtime"; + +function Component(props) { + let x; + const array = [props.count]; + x = array; + const element =
{array}
; + return ( +
+ {element} + {x} +
+ ); +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ count: 42 }], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +import { Stringify } from "shared-runtime"; + +function Component(props) { + const $ = _c(7); + let x; + let t0; + if ($[0] !== props.count) { + t0 = [props.count]; + $[0] = props.count; + $[1] = t0; + } else { + t0 = $[1]; + } + const array = t0; + x = array; + let t1; + if ($[2] !== array) { + t1 =
{array}
; + $[2] = array; + $[3] = t1; + } else { + t1 = $[3]; + } + const element = t1; + let t2; + if ($[4] !== element || $[5] !== x) { + t2 = ( +
+ {element} + {x} +
+ ); + $[4] = element; + $[5] = x; + $[6] = t2; + } else { + t2 = $[6]; + } + return t2; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ count: 42 }], +}; + +``` + +### Eval output +(kind: ok)
42
42
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-with-intermediate-reassignment.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-with-intermediate-reassignment.js new file mode 100644 index 0000000000..a506886853 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/dont-merge-overlapping-scopes-with-intermediate-reassignment.js @@ -0,0 +1,19 @@ +import { Stringify } from "shared-runtime"; + +function Component(props) { + let x; + const array = [props.count]; + x = array; + const element =
{array}
; + return ( +
+ {element} + {x} +
+ ); +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ count: 42 }], +}; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-of-continue.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-of-continue.expect.md index f88bfab8f6..d51627d164 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-of-continue.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-of-continue.expect.md @@ -27,17 +27,10 @@ export const FIXTURE_ENTRYPOINT = { ```javascript import { c as _c } from "react/compiler-runtime"; function Component() { - const $ = _c(2); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = [0, 1, 2, 3]; - $[0] = t0; - } else { - t0 = $[0]; - } - const x = t0; + const $ = _c(1); let ret; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const x = [0, 1, 2, 3]; ret = []; for (const item of x) { if (item === 0) { @@ -46,9 +39,9 @@ function Component() { ret.push(item / 2); } - $[1] = ret; + $[0] = ret; } else { - ret = $[1]; + ret = $[0]; } return ret; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-recursive-call-within-lambda.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-recursive-call-within-lambda.expect.md index 8d87130a29..a7cf6bcc1e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-recursive-call-within-lambda.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-recursive-call-within-lambda.expect.md @@ -27,10 +27,10 @@ export const FIXTURE_ENTRYPOINT = { ```javascript import { c as _c } from "react/compiler-runtime"; function Foo(t0) { - const $ = _c(2); + const $ = _c(1); let t1; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t1 = (val) => { + const outer = (val) => { const fact = (x) => { if (x <= 0) { return 1; @@ -39,19 +39,13 @@ function Foo(t0) { }; return fact(val); }; + + t1 = outer(3); $[0] = t1; } else { t1 = $[0]; } - const outer = t1; - let t2; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t2 = outer(3); - $[1] = t2; - } else { - t2 = $[1]; - } - return t2; + return t1; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-within-lambda.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-within-lambda.expect.md index d255ff008e..1baf31aa9b 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-within-lambda.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-within-lambda.expect.md @@ -25,28 +25,22 @@ export const FIXTURE_ENTRYPOINT = { ```javascript import { c as _c } from "react/compiler-runtime"; function Component(t0) { - const $ = _c(2); + const $ = _c(1); let t1; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t1 = () => { + const outer = () => { const inner = () => x; const x = 3; return inner(); }; + + t1 =
{outer()}
; $[0] = t1; } else { t1 = $[0]; } - const outer = t1; - let t2; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t2 =
{outer()}
; - $[1] = t2; - } else { - t2 = $[1]; - } - return t2; + return t1; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-local-tag-in-lambda.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-local-tag-in-lambda.expect.md index b4dba441ce..7a1e546df2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-local-tag-in-lambda.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-local-tag-in-lambda.expect.md @@ -24,23 +24,17 @@ export const FIXTURE_ENTRYPOINT = { import { c as _c } from "react/compiler-runtime"; import { Stringify } from "shared-runtime"; function useFoo() { - const $ = _c(2); + const $ = _c(1); let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = () => ; + const callback = () => ; + + t0 = callback(); $[0] = t0; } else { t0 = $[0]; } - const callback = t0; - let t1; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t1 = callback(); - $[1] = t1; - } else { - t1 = $[1]; - } - return t1; + return t0; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-memberexpr-tag-in-lambda.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-memberexpr-tag-in-lambda.expect.md index 0fdc43b323..a5dd678d30 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-memberexpr-tag-in-lambda.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-memberexpr-tag-in-lambda.expect.md @@ -24,24 +24,18 @@ export const FIXTURE_ENTRYPOINT = { import { c as _c } from "react/compiler-runtime"; import * as SharedRuntime from "shared-runtime"; function useFoo() { - const $ = _c(2); + const $ = _c(1); const MyLocal = SharedRuntime; let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = () => ; + const callback = () => ; + + t0 = callback(); $[0] = t0; } else { t0 = $[0]; } - const callback = t0; - let t1; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t1 = callback(); - $[1] = t1; - } else { - t1 = $[1]; - } - return t1; + return t0; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/maybe-mutate-object-in-callback.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/maybe-mutate-object-in-callback.expect.md index 54b367923e..69317c462e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/maybe-mutate-object-in-callback.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/maybe-mutate-object-in-callback.expect.md @@ -32,34 +32,28 @@ import { c as _c } from "react/compiler-runtime"; const { mutate } = require("shared-runtime"); function Component(props) { - const $ = _c(4); + const $ = _c(3); let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = {}; + const object = {}; + + t0 = () => { + mutate(object); + }; $[0] = t0; } else { t0 = $[0]; } - const object = t0; + const onClick = t0; let t1; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t1 = () => { - mutate(object); - }; - $[1] = t1; + if ($[1] !== props.children) { + t1 = {props.children}; + $[1] = props.children; + $[2] = t1; } else { - t1 = $[1]; + t1 = $[2]; } - const onClick = t1; - let t2; - if ($[2] !== props.children) { - t2 = {props.children}; - $[2] = props.children; - $[3] = t2; - } else { - t2 = $[3]; - } - return t2; + return t1; } function Foo(t0) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutable-range-shared-inner-outer-function.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutable-range-shared-inner-outer-function.expect.md index 58cc981be3..583148ceb7 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutable-range-shared-inner-outer-function.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutable-range-shared-inner-outer-function.expect.md @@ -34,12 +34,12 @@ export const FIXTURE_ENTRYPOINT = { import { c as _c } from "react/compiler-runtime"; // @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions let cond = true; function Component(props) { - const $ = _c(2); + const $ = _c(1); let a; let b; let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = () => { + const f = () => { if (cond) { a = {}; b = []; @@ -51,19 +51,13 @@ function Component(props) { a.property = true; b.push(false); }; + + t0 =
; $[0] = t0; } else { t0 = $[0]; } - const f = t0; - let t1; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t1 =
; - $[1] = t1; - } else { - t1 = $[1]; - } - return t1; + return t0; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-property.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-property.expect.md index b1c4736741..565313fc0d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-property.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-property.expect.md @@ -22,22 +22,15 @@ export const FIXTURE_ENTRYPOINT = { ```javascript import { c as _c } from "react/compiler-runtime"; function foo() { - const $ = _c(2); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = []; - $[0] = t0; - } else { - t0 = $[0]; - } - const x = t0; + const $ = _c(1); let y; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const x = []; y = {}; y.x = x; - $[1] = y; + $[0] = y; } else { - y = $[1]; + y = $[0]; } return y; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-reassign-in-rval.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-reassign-in-rval.expect.md index 7288c2008c..1457ad3fa2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-reassign-in-rval.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/ssa-reassign-in-rval.expect.md @@ -16,27 +16,17 @@ function Component() { ```javascript import { c as _c } from "react/compiler-runtime"; // Forget should call the original x (x = foo()) to compute result function Component() { - const $ = _c(3); + const $ = _c(1); let t0; - let x; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - x = foo(); - t0 = x((x = bar()), 5); + let x = foo(); + const result = x((x = bar()), 5); + t0 = [result, x]; $[0] = t0; - $[1] = x; } else { t0 = $[0]; - x = $[1]; } - const result = t0; - let t1; - if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - t1 = [result, x]; - $[2] = t1; - } else { - t1 = $[2]; - } - return t1; + return t0; } ``` diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/try-catch-within-function-expression.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/try-catch-within-function-expression.expect.md index 8c4074c946..4e9dbd5fed 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/try-catch-within-function-expression.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/try-catch-within-function-expression.expect.md @@ -25,29 +25,23 @@ export const FIXTURE_ENTRYPOINT = { ```javascript import { c as _c } from "react/compiler-runtime"; function Component(props) { - const $ = _c(2); + const $ = _c(1); let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = () => { + const callback = () => { try { return []; } catch (t1) { return; } }; + + t0 = callback(); $[0] = t0; } else { t0 = $[0]; } - const callback = t0; - let t1; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t1 = callback(); - $[1] = t1; - } else { - t1 = $[1]; - } - return t1; + return t0; } export const FIXTURE_ENTRYPOINT = { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/type-test-polymorphic.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/type-test-polymorphic.expect.md index 70d1b53939..d100dadffe 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/type-test-polymorphic.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/type-test-polymorphic.expect.md @@ -24,26 +24,20 @@ function component() { ```javascript import { c as _c } from "react/compiler-runtime"; function component() { - const $ = _c(2); + const $ = _c(1); const p = makePrimitive(); - let t0; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = {}; - $[0] = t0; - } else { - t0 = $[0]; - } - const o = t0; let x; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + const o = {}; + x = {}; x.t = p; x.t = o; - $[1] = x; + $[0] = x; } else { - x = $[1]; + x = $[0]; } const y = x.t; return y;