From daab9e33b278d98db1eff5f20d72cea42ad0bbf4 Mon Sep 17 00:00:00 2001 From: Mofei Zhang Date: Tue, 19 Nov 2024 10:10:38 -0500 Subject: [PATCH] [compiler][rfc] enableTreatFunctionDepsAsConditional by default See https://github.com/facebook/react/issues/31551 for context We've rolled out internally with `enableTreatFunctionDepsAsConditional: false` and encountered no issues, but this is technically an unsound optimization as both flow and typescript have sources of unsoundness: - typing array accesses / other unknown keys as `TValue | undefined` (typescript's noUncheckedIndexedAccess) - explicit and inferred `any` - unsound typecasts Note that removing this optimization results in less granular dependencies for ~3% of files on a large Meta project ([link](https://www.internalfb.com/phabricator/paste/view/P1681742214)). --- .../src/HIR/Environment.ts | 15 +++++-- ...g-aliased-capture-aliased-mutate.expect.md | 4 +- .../bug-aliased-capture-mutate.expect.md | 4 +- ...g-function-member-expr-arguments.expect.md | 4 +- ...turing-function-member-expr-call.expect.md | 4 +- .../compiler/capturing-member-expr.expect.md | 4 +- ...ested-member-expr-in-nested-func.expect.md | 4 +- .../capturing-nested-member-expr.expect.md | 4 +- ...and-local-variables-with-default.expect.md | 4 +- ...ed-scope-declarations-and-locals.expect.md | 4 +- ...nction-expression-prototype-call.expect.md | 4 +- ...nvalid-useCallback-read-maybeRef.expect.md | 32 --------------- ...be-invalid-useMemo-read-maybeRef.expect.md | 32 --------------- ...nvalid-useCallback-read-maybeRef.expect.md | 38 ++++++++++++++++++ ...aybe-invalid-useCallback-read-maybeRef.ts} | 0 ...be-invalid-useMemo-read-maybeRef.expect.md | 40 +++++++++++++++++++ ...=> maybe-invalid-useMemo-read-maybeRef.ts} | 4 +- ...Callback-alias-property-load-dep.expect.md | 14 +++---- .../useCallback-alias-property-load-dep.ts | 6 +-- .../useCallback-infer-more-specific.expect.md | 4 +- ...r-function-uncond-access-hoisted.expect.md | 4 +- ...n-uncond-access-hoists-other-dep.expect.md | 4 +- ...function-uncond-access-local-var.expect.md | 4 +- ...uncond-optional-hoists-other-dep.expect.md | 4 +- ...function-uncond-access-local-var.expect.md | 4 +- ...er-nested-function-uncond-access.expect.md | 4 +- ...nfer-object-method-uncond-access.expect.md | 4 +- ...unction-uncond-optionals-hoisted.expect.md | 4 +- .../repro-invariant.expect.md | 4 +- ...l-dependency-on-context-variable.expect.md | 4 +- ...unction-uncond-optionals-hoisted.expect.md | 4 +- ...source-variables-nested-function.expect.md | 4 +- ...e-variables-nested-object-method.expect.md | 4 +- ...maybe-mutate-context-in-callback.expect.md | 4 +- ...context-in-callback-if-condition.expect.md | 4 +- ...Context-read-context-in-callback.expect.md | 4 +- .../useEffect-nested-lambdas.expect.md | 25 +++++------- 37 files changed, 165 insertions(+), 149 deletions(-) delete mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.maybe-invalid-useCallback-read-maybeRef.expect.md delete mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.maybe-invalid-useMemo-read-maybeRef.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/maybe-invalid-useCallback-read-maybeRef.expect.md rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/{error.maybe-invalid-useCallback-read-maybeRef.ts => maybe-invalid-useCallback-read-maybeRef.ts} (100%) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/maybe-invalid-useMemo-read-maybeRef.expect.md rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/{error.maybe-invalid-useMemo-read-maybeRef.ts => maybe-invalid-useMemo-read-maybeRef.ts} (67%) diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts index 855bc039ab..cea202f2c9 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts @@ -457,9 +457,10 @@ const EnvironmentConfigSchema = z.object({ throwUnknownException__testonly: z.boolean().default(false), /** - * Enables deps of a function epxression to be treated as conditional. This - * makes sure we don't load a dep when it's a property (to check if it has - * changed) and instead check the receiver. + * Enables deps of a function expression to be treated as conditional. This + * makes sure we don't hoist property loads from function expressions when we + * don't know that the property load source object is safe to access in the + * outer context * * This makes sure we don't end up throwing when the reciver is null. Consider * this code: @@ -475,8 +476,14 @@ const EnvironmentConfigSchema = z.object({ * * This does cause the memoization to now be coarse grained, which is * non-ideal. + * + * This is safe to toggle off for a codebase that has no sources of + * unsoundness. This includes: + * - typing array accesses / other unknown keys as TValue | undefined + * (typescript's noUncheckedIndexedAccess) + * - enabling and monitoring warnings for explicit and inferred `any` */ - enableTreatFunctionDepsAsConditional: z.boolean().default(false), + enableTreatFunctionDepsAsConditional: z.boolean().default(true), /** * When true, always act as though the dependencies of a memoized value diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-aliased-capture-aliased-mutate.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-aliased-capture-aliased-mutate.expect.md index d0ad9e2f9d..13adbc1c96 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-aliased-capture-aliased-mutate.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-aliased-capture-aliased-mutate.expect.md @@ -75,9 +75,9 @@ function useFoo(t0) { arrayPush(x, y); const y_alias = y; let t2; - if ($[3] !== y_alias.value) { + if ($[3] !== y_alias) { t2 = () => y_alias.value; - $[3] = y_alias.value; + $[3] = y_alias; $[4] = t2; } else { t2 = $[4]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-aliased-capture-mutate.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-aliased-capture-mutate.expect.md index c35efe6a16..ae60114253 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-aliased-capture-mutate.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-aliased-capture-mutate.expect.md @@ -56,9 +56,9 @@ function useFoo(t0) { setPropertyByKey(obj, "arr", arr); const obj_alias = obj; let t2; - if ($[2] !== obj_alias.arr.length) { + if ($[2] !== obj_alias) { t2 = () => obj_alias.arr.length; - $[2] = obj_alias.arr.length; + $[2] = obj_alias; $[3] = t2; } else { t2 = $[3]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-function-member-expr-arguments.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-function-member-expr-arguments.expect.md index 5a2c68b63c..d5e1f2e563 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-function-member-expr-arguments.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-function-member-expr-arguments.expect.md @@ -22,11 +22,11 @@ import { c as _c } from "react/compiler-runtime"; function Foo(props) { const $ = _c(2); let t0; - if ($[0] !== props.router.location) { + if ($[0] !== props.router) { t0 = (reason) => { log(props.router.location); }; - $[0] = props.router.location; + $[0] = props.router; $[1] = t0; } else { t0 = $[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-function-member-expr-call.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-function-member-expr-call.expect.md index cab9c9a500..621ad98de7 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-function-member-expr-call.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-function-member-expr-call.expect.md @@ -35,11 +35,11 @@ function component(t0) { } const poke = t1; let t2; - if ($[2] !== mutator.user) { + if ($[2] !== mutator) { t2 = () => { mutator.user.hide(); }; - $[2] = mutator.user; + $[2] = mutator; $[3] = t2; } else { t2 = $[3]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-member-expr.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-member-expr.expect.md index fcf42fac8c..c9d6b45656 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-member-expr.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-member-expr.expect.md @@ -34,11 +34,11 @@ function component(a) { } const z = t0; let t1; - if ($[2] !== z.a) { + if ($[2] !== z) { t1 = function () { console.log(z.a); }; - $[2] = z.a; + $[2] = z; $[3] = t1; } else { t1 = $[3]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-nested-member-expr-in-nested-func.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-nested-member-expr-in-nested-func.expect.md index e7d21da428..daf8d972cf 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-nested-member-expr-in-nested-func.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-nested-member-expr-in-nested-func.expect.md @@ -36,13 +36,13 @@ function component(a) { } const z = t0; let t1; - if ($[2] !== z.a.a) { + if ($[2] !== z) { t1 = function () { (function () { console.log(z.a.a); })(); }; - $[2] = z.a.a; + $[2] = z; $[3] = t1; } else { t1 = $[3]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-nested-member-expr.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-nested-member-expr.expect.md index f883378432..a5a6f7a321 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-nested-member-expr.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/capturing-nested-member-expr.expect.md @@ -34,11 +34,11 @@ function component(a) { } const z = t0; let t1; - if ($[2] !== z.a.a) { + if ($[2] !== z) { t1 = function () { console.log(z.a.a); }; - $[2] = z.a.a; + $[2] = z; $[3] = t1; } else { t1 = $[3]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-and-local-variables-with-default.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-and-local-variables-with-default.expect.md index 17dd0f8359..de029c0117 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-and-local-variables-with-default.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-and-local-variables-with-default.expect.md @@ -97,7 +97,7 @@ function Component(props) { } const urls = t5; let t6; - if ($[6] !== comments.length) { + if ($[6] !== comments) { t6 = (e) => { if (!comments.length) { return; @@ -105,7 +105,7 @@ function Component(props) { console.log(comments.length); }; - $[6] = comments.length; + $[6] = comments; $[7] = t6; } else { t6 = $[7]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-declarations-and-locals.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-declarations-and-locals.expect.md index f69149aba4..d9c493ae98 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-declarations-and-locals.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/destructuring-mixed-scope-declarations-and-locals.expect.md @@ -56,7 +56,7 @@ function Component(props) { const { media, comments, urls } = post; let t1; - if ($[2] !== comments.length) { + if ($[2] !== comments) { t1 = (e) => { if (!comments.length) { return; @@ -64,7 +64,7 @@ function Component(props) { console.log(comments.length); }; - $[2] = comments.length; + $[2] = comments; $[3] = t1; } else { t1 = $[3]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/function-expression-prototype-call.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/function-expression-prototype-call.expect.md index 5666876f00..2df5b90890 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/function-expression-prototype-call.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/function-expression-prototype-call.expect.md @@ -23,11 +23,11 @@ import { c as _c } from "react/compiler-runtime"; function Component(props) { const $ = _c(4); let t0; - if ($[0] !== props.name) { + if ($[0] !== props) { t0 = function () { return
{props.name}
; }; - $[0] = props.name; + $[0] = props; $[1] = t0; } else { t0 = $[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.maybe-invalid-useCallback-read-maybeRef.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.maybe-invalid-useCallback-read-maybeRef.expect.md deleted file mode 100644 index 87d4946b61..0000000000 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.maybe-invalid-useCallback-read-maybeRef.expect.md +++ /dev/null @@ -1,32 +0,0 @@ - -## Input - -```javascript -// @validatePreserveExistingMemoizationGuarantees -import {useCallback} from 'react'; - -function useHook(maybeRef) { - return useCallback(() => { - return [maybeRef.current]; - }, [maybeRef]); -} - -``` - - -## Error - -``` - 3 | - 4 | function useHook(maybeRef) { -> 5 | return useCallback(() => { - | ^^^^^^^ -> 6 | return [maybeRef.current]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -> 7 | }, [maybeRef]); - | ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (5:7) - 8 | } - 9 | -``` - - \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.maybe-invalid-useMemo-read-maybeRef.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.maybe-invalid-useMemo-read-maybeRef.expect.md deleted file mode 100644 index ce0b751851..0000000000 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.maybe-invalid-useMemo-read-maybeRef.expect.md +++ /dev/null @@ -1,32 +0,0 @@ - -## Input - -```javascript -// @validatePreserveExistingMemoizationGuarantees -import {useMemo} from 'react'; - -function useHook(maybeRef, shouldRead) { - return useMemo(() => { - return () => [maybeRef.current]; - }, [shouldRead, maybeRef]); -} - -``` - - -## Error - -``` - 3 | - 4 | function useHook(maybeRef, shouldRead) { -> 5 | return useMemo(() => { - | ^^^^^^^ -> 6 | return () => [maybeRef.current]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -> 7 | }, [shouldRead, maybeRef]); - | ^^^^ CannotPreserveMemoization: React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected (5:7) - 8 | } - 9 | -``` - - \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/maybe-invalid-useCallback-read-maybeRef.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/maybe-invalid-useCallback-read-maybeRef.expect.md new file mode 100644 index 0000000000..0ccfd1e43a --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/maybe-invalid-useCallback-read-maybeRef.expect.md @@ -0,0 +1,38 @@ + +## Input + +```javascript +// @validatePreserveExistingMemoizationGuarantees +import {useCallback} from 'react'; + +function useHook(maybeRef) { + return useCallback(() => { + return [maybeRef.current]; + }, [maybeRef]); +} + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees +import { useCallback } from "react"; + +function useHook(maybeRef) { + const $ = _c(2); + let t0; + if ($[0] !== maybeRef) { + t0 = () => [maybeRef.current]; + $[0] = maybeRef; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; +} + +``` + +### Eval output +(kind: exception) Fixture not implemented \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.maybe-invalid-useCallback-read-maybeRef.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/maybe-invalid-useCallback-read-maybeRef.ts similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.maybe-invalid-useCallback-read-maybeRef.ts rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/maybe-invalid-useCallback-read-maybeRef.ts diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/maybe-invalid-useMemo-read-maybeRef.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/maybe-invalid-useMemo-read-maybeRef.expect.md new file mode 100644 index 0000000000..a790a670aa --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/maybe-invalid-useMemo-read-maybeRef.expect.md @@ -0,0 +1,40 @@ + +## Input + +```javascript +// @validatePreserveExistingMemoizationGuarantees +import {useMemo} from 'react'; + +function useHook(maybeRef) { + return useMemo(() => { + return () => [maybeRef.current]; + }, [maybeRef]); +} + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; // @validatePreserveExistingMemoizationGuarantees +import { useMemo } from "react"; + +function useHook(maybeRef) { + const $ = _c(2); + let t0; + let t1; + if ($[0] !== maybeRef) { + t1 = () => [maybeRef.current]; + $[0] = maybeRef; + $[1] = t1; + } else { + t1 = $[1]; + } + t0 = t1; + return t0; +} + +``` + +### Eval output +(kind: exception) Fixture not implemented \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.maybe-invalid-useMemo-read-maybeRef.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/maybe-invalid-useMemo-read-maybeRef.ts similarity index 67% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.maybe-invalid-useMemo-read-maybeRef.ts rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/maybe-invalid-useMemo-read-maybeRef.ts index 1bf54a5aa5..36a7fd9a4c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/error.maybe-invalid-useMemo-read-maybeRef.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/maybe-invalid-useMemo-read-maybeRef.ts @@ -1,8 +1,8 @@ // @validatePreserveExistingMemoizationGuarantees import {useMemo} from 'react'; -function useHook(maybeRef, shouldRead) { +function useHook(maybeRef) { return useMemo(() => { return () => [maybeRef.current]; - }, [shouldRead, maybeRef]); + }, [maybeRef]); } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-alias-property-load-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-alias-property-load-dep.expect.md index 5fceb7ef81..e06704c30c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-alias-property-load-dep.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-alias-property-load-dep.expect.md @@ -9,13 +9,13 @@ import {sum} from 'shared-runtime'; function Component({propA, propB}) { const x = propB.x.y; return useCallback(() => { - return sum(propA.x, x); - }, [propA.x, x]); + return sum(propA, x); + }, [propA, x]); } export const FIXTURE_ENTRYPOINT = { fn: Component, - params: [{propA: {x: 2}, propB: {x: {y: 3}}}], + params: [{propA: 2, propB: {x: {y: 3}}}], }; ``` @@ -32,9 +32,9 @@ function Component(t0) { const { propA, propB } = t0; const x = propB.x.y; let t1; - if ($[0] !== propA.x || $[1] !== x) { - t1 = () => sum(propA.x, x); - $[0] = propA.x; + if ($[0] !== propA || $[1] !== x) { + t1 = () => sum(propA, x); + $[0] = propA; $[1] = x; $[2] = t1; } else { @@ -45,7 +45,7 @@ function Component(t0) { export const FIXTURE_ENTRYPOINT = { fn: Component, - params: [{ propA: { x: 2 }, propB: { x: { y: 3 } } }], + params: [{ propA: 2, propB: { x: { y: 3 } } }], }; ``` diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-alias-property-load-dep.ts b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-alias-property-load-dep.ts index be03a9ceaf..aa3481e269 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-alias-property-load-dep.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-alias-property-load-dep.ts @@ -5,11 +5,11 @@ import {sum} from 'shared-runtime'; function Component({propA, propB}) { const x = propB.x.y; return useCallback(() => { - return sum(propA.x, x); - }, [propA.x, x]); + return sum(propA, x); + }, [propA, x]); } export const FIXTURE_ENTRYPOINT = { fn: Component, - params: [{propA: {x: 2}, propB: {x: {y: 3}}}], + params: [{propA: 2, propB: {x: {y: 3}}}], }; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-more-specific.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-more-specific.expect.md index 7e57f29492..5c2192e35d 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-more-specific.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/preserve-memo-validation/useCallback-infer-more-specific.expect.md @@ -37,9 +37,9 @@ import { useCallback } from "react"; function useHook(x) { const $ = _c(2); let t0; - if ($[0] !== x.y.z) { + if ($[0] !== x) { t0 = () => [x.y.z]; - $[0] = x.y.z; + $[0] = x; $[1] = t0; } else { t0 = $[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-access-hoisted.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-access-hoisted.expect.md index 1ddc7495bc..9ddead2734 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-access-hoisted.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-access-hoisted.expect.md @@ -29,9 +29,9 @@ function useFoo(t0) { const $ = _c(2); const { a } = t0; let t1; - if ($[0] !== a.b.c) { + if ($[0] !== a) { t1 = a.b.c} shouldInvokeFns={true} />; - $[0] = a.b.c; + $[0] = a; $[1] = t1; } else { t1 = $[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-access-hoists-other-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-access-hoists-other-dep.expect.md index d82956e4a0..eab9491c47 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-access-hoists-other-dep.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-access-hoists-other-dep.expect.md @@ -51,12 +51,12 @@ function Foo(t0) { const fn = t1; useIdentity(null); let x; - if ($[2] !== a.b.c || $[3] !== cond) { + if ($[2] !== a || $[3] !== cond) { x = makeArray(); if (cond) { x.push(identity(a.b.c)); } - $[2] = a.b.c; + $[2] = a; $[3] = cond; $[4] = x; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-access-local-var.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-access-local-var.expect.md index 741a30d7de..2536322cf7 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-access-local-var.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-access-local-var.expect.md @@ -41,9 +41,9 @@ function useFoo(t0) { local = $[1]; } let t1; - if ($[2] !== local.b.c) { + if ($[2] !== local) { t1 = () => local.b.c; - $[2] = local.b.c; + $[2] = local; $[3] = t1; } else { t1 = $[3]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-optional-hoists-other-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-optional-hoists-other-dep.expect.md index c81e59ecea..7d8c1b32db 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-optional-hoists-other-dep.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-function-uncond-optional-hoists-other-dep.expect.md @@ -50,12 +50,12 @@ function Foo(t0) { const fn = t1; useIdentity(null); let arr; - if ($[2] !== a.b?.c.e || $[3] !== cond) { + if ($[2] !== a || $[3] !== cond) { arr = makeArray(); if (cond) { arr.push(identity(a.b?.c.e)); } - $[2] = a.b?.c.e; + $[2] = a; $[3] = cond; $[4] = arr; } else { diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-nested-function-uncond-access-local-var.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-nested-function-uncond-access-local-var.expect.md index ca65ce72bc..53d3d04531 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-nested-function-uncond-access-local-var.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-nested-function-uncond-access-local-var.expect.md @@ -41,9 +41,9 @@ function useFoo(t0) { local = $[1]; } let t1; - if ($[2] !== local.b.c) { + if ($[2] !== local) { t1 = () => [() => local.b.c]; - $[2] = local.b.c; + $[2] = local; $[3] = t1; } else { t1 = $[3]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-nested-function-uncond-access.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-nested-function-uncond-access.expect.md index 22b17977cb..e61e36d865 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-nested-function-uncond-access.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-nested-function-uncond-access.expect.md @@ -34,9 +34,9 @@ function useFoo(t0) { const $ = _c(4); const { a } = t0; let t1; - if ($[0] !== a.b.c) { + if ($[0] !== a) { t1 = () => () => ({ value: a.b.c }); - $[0] = a.b.c; + $[0] = a; $[1] = t1; } else { t1 = $[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-object-method-uncond-access.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-object-method-uncond-access.expect.md index 7d75470550..f8a8af1fd4 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-object-method-uncond-access.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/infer-object-method-uncond-access.expect.md @@ -34,13 +34,13 @@ function useFoo(t0) { const $ = _c(4); const { a } = t0; let t1; - if ($[0] !== a.b.c) { + if ($[0] !== a) { t1 = { fn() { return identity(a.b.c); }, }; - $[0] = a.b.c; + $[0] = a; $[1] = t1; } else { t1 = $[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/todo-infer-function-uncond-optionals-hoisted.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/todo-infer-function-uncond-optionals-hoisted.expect.md index ed56ff0681..883d4dc8d6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/todo-infer-function-uncond-optionals-hoisted.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/todo-infer-function-uncond-optionals-hoisted.expect.md @@ -34,9 +34,9 @@ function useFoo(t0) { const $ = _c(2); const { a } = t0; let t1; - if ($[0] !== a.b?.c.d?.e) { + if ($[0] !== a) { t1 = a.b?.c.d?.e} shouldInvokeFns={true} />; - $[0] = a.b?.c.d?.e; + $[0] = a; $[1] = t1; } else { t1 = $[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/repro-invariant.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/repro-invariant.expect.md index 73df2b615b..cdb9d67e36 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/repro-invariant.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/repro-invariant.expect.md @@ -29,9 +29,9 @@ function Foo(t0) { const $ = _c(5); const { data } = t0; let t1; - if ($[0] !== data.a.d) { + if ($[0] !== data.a) { t1 = () => data.a.d; - $[0] = data.a.d; + $[0] = data.a; $[1] = t1; } else { t1 = $[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-control-dependency-on-context-variable.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-control-dependency-on-context-variable.expect.md index 23cc7ee846..a8fa9105e8 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-control-dependency-on-context-variable.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-control-dependency-on-context-variable.expect.md @@ -51,7 +51,7 @@ import { identity } from "shared-runtime"; function Component(props) { const $ = _c(4); let x; - if ($[0] !== props.cond) { + if ($[0] !== props) { const f = () => { if (props.cond) { x = 1; @@ -62,7 +62,7 @@ function Component(props) { const f2 = identity(f); f2(); - $[0] = props.cond; + $[0] = props; $[1] = x; } else { x = $[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reduce-reactive-deps/todo-infer-function-uncond-optionals-hoisted.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reduce-reactive-deps/todo-infer-function-uncond-optionals-hoisted.expect.md index bb99a5d90f..1c65af0fe6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reduce-reactive-deps/todo-infer-function-uncond-optionals-hoisted.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reduce-reactive-deps/todo-infer-function-uncond-optionals-hoisted.expect.md @@ -31,9 +31,9 @@ function useFoo(t0) { const $ = _c(2); const { a } = t0; let t1; - if ($[0] !== a.b?.c.d?.e) { + if ($[0] !== a) { t1 = a.b?.c.d?.e} shouldInvokeFns={true} />; - $[0] = a.b?.c.d?.e; + $[0] = a; $[1] = t1; } else { t1 = $[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rename-source-variables-nested-function.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rename-source-variables-nested-function.expect.md index 3287997cf7..1957b3b0b2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rename-source-variables-nested-function.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rename-source-variables-nested-function.expect.md @@ -42,7 +42,7 @@ const t0 = "module_t0"; const c_0 = "module_c_0"; function useFoo(props) { const $0 = _c(4); - const c_00 = $0[0] !== props.value; + const c_00 = $0[0] !== props; let t1; if (c_00) { t1 = () => { @@ -57,7 +57,7 @@ function useFoo(props) { }; return b; }; - $0[0] = props.value; + $0[0] = props; $0[1] = t1; } else { t1 = $0[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rename-source-variables-nested-object-method.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rename-source-variables-nested-object-method.expect.md index d0f3d5dcfe..e406f3a7d7 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rename-source-variables-nested-object-method.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/rename-source-variables-nested-object-method.expect.md @@ -43,7 +43,7 @@ const t0 = "module_t0"; const c_0 = "module_c_0"; function useFoo(props) { const $0 = _c(2); - const c_00 = $0[0] !== props.value; + const c_00 = $0[0] !== props; let t1; if (c_00) { const a = { @@ -61,7 +61,7 @@ function useFoo(props) { }; t1 = a.foo().bar(); - $0[0] = props.value; + $0[0] = props; $0[1] = t1; } else { t1 = $0[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-maybe-mutate-context-in-callback.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-maybe-mutate-context-in-callback.expect.md index 0525a0f7cd..1170316958 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-maybe-mutate-context-in-callback.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-maybe-mutate-context-in-callback.expect.md @@ -41,11 +41,11 @@ function Component(props) { const $ = _c(5); const Foo = useContext(FooContext); let t0; - if ($[0] !== Foo.current) { + if ($[0] !== Foo) { t0 = () => { mutate(Foo.current); }; - $[0] = Foo.current; + $[0] = Foo; $[1] = t0; } else { t0 = $[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-read-context-in-callback-if-condition.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-read-context-in-callback-if-condition.expect.md index 1d09cbb359..bd45c13948 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-read-context-in-callback-if-condition.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-read-context-in-callback-if-condition.expect.md @@ -42,7 +42,7 @@ function Component(props) { const $ = _c(6); const foo = useContext(FooContext); let t0; - if ($[0] !== foo.current) { + if ($[0] !== foo) { t0 = () => { if (foo.current) { return {}; @@ -50,7 +50,7 @@ function Component(props) { return null; } }; - $[0] = foo.current; + $[0] = foo; $[1] = t0; } else { t0 = $[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-read-context-in-callback.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-read-context-in-callback.expect.md index e805b7f400..09dbbc230f 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-read-context-in-callback.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useContext-read-context-in-callback.expect.md @@ -34,11 +34,11 @@ function Component(props) { const $ = _c(5); const foo = useContext(FooContext); let t0; - if ($[0] !== foo.current) { + if ($[0] !== foo) { t0 = () => { console.log(foo.current); }; - $[0] = foo.current; + $[0] = foo; $[1] = t0; } else { t0 = $[1]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useEffect-nested-lambdas.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useEffect-nested-lambdas.expect.md index c3e115fa0d..0cce42e97a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useEffect-nested-lambdas.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useEffect-nested-lambdas.expect.md @@ -35,7 +35,7 @@ function Component(props) { import { c as _c } from "react/compiler-runtime"; // @enableTransitivelyFreezeFunctionExpressions:false function Component(props) { - const $ = _c(9); + const $ = _c(7); const item = useMutable(props.itemId); const dispatch = useDispatch(); useFreeze(dispatch); @@ -51,7 +51,8 @@ function Component(props) { } const exit = t0; let t1; - if ($[2] !== exit || $[3] !== item.value) { + let t2; + if ($[2] !== exit || $[3] !== item) { t1 = () => { const cleanup = GlobalEventEmitter.addListener("onInput", () => { if (item.value) { @@ -60,30 +61,24 @@ function Component(props) { }); return () => cleanup.remove(); }; + t2 = [exit, item]; $[2] = exit; - $[3] = item.value; + $[3] = item; $[4] = t1; + $[5] = t2; } else { t1 = $[4]; - } - let t2; - if ($[5] !== exit || $[6] !== item) { - t2 = [exit, item]; - $[5] = exit; - $[6] = item; - $[7] = t2; - } else { - t2 = $[7]; + t2 = $[5]; } useEffect(t1, t2); maybeMutate(item); let t3; - if ($[8] === Symbol.for("react.memo_cache_sentinel")) { + if ($[6] === Symbol.for("react.memo_cache_sentinel")) { t3 =
; - $[8] = t3; + $[6] = t3; } else { - t3 = $[8]; + t3 = $[6]; } return t3; }