From 19557443c8c2f54571dbb1519403cf310ad6e68b Mon Sep 17 00:00:00 2001 From: mofeiZ <34200447+mofeiZ@users.noreply.github.com> Date: Wed, 22 Jan 2025 13:52:05 -0500 Subject: [PATCH 1/7] [compiler][repro] JSX escape sequences not printed correctly by @babel/generator (#32130) Repro for https://github.com/facebook/react/issues/32123 Note that this is only a bug when calling `@babel/generator:generate()` before transforming JSX. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32130). * #32131 * __->__ #32130 --- .../jsx-preserve-escape-character.expect.md | 57 +++++++++++++++++++ .../compiler/jsx-preserve-escape-character.js | 17 ++++++ 2 files changed, 74 insertions(+) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-preserve-escape-character.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-preserve-escape-character.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-preserve-escape-character.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-preserve-escape-character.expect.md new file mode 100644 index 0000000000000..6f8a86382d436 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-preserve-escape-character.expect.md @@ -0,0 +1,57 @@ + +## Input + +```javascript +/** + * Fixture showing `@babel/generator` bug with jsx attribute strings containing + * escape sequences. Note that this is only a problem when generating jsx + * literals. + * + * When using the jsx transform to correctly lower jsx into + * `React.createElement` calls, the escape sequences are preserved correctly + * (see evaluator output). + */ +function MyApp() { + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: MyApp, + params: [], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; /** + * Fixture showing `@babel/generator` bug with jsx attribute strings containing + * escape sequences. Note that this is only a problem when generating jsx + * literals. + * + * When using the jsx transform to correctly lower jsx into + * `React.createElement` calls, the escape sequences are preserved correctly + * (see evaluator output). + */ +function MyApp() { + const $ = _c(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = ; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; +} + +export const FIXTURE_ENTRYPOINT = { + fn: MyApp, + params: [], +}; + +``` + +### Eval output +(kind: ok) \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-preserve-escape-character.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-preserve-escape-character.js new file mode 100644 index 0000000000000..5a972a585becc --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-preserve-escape-character.js @@ -0,0 +1,17 @@ +/** + * Fixture showing `@babel/generator` bug with jsx attribute strings containing + * escape sequences. Note that this is only a problem when generating jsx + * literals. + * + * When using the jsx transform to correctly lower jsx into + * `React.createElement` calls, the escape sequences are preserved correctly + * (see evaluator output). + */ +function MyApp() { + return ; +} + +export const FIXTURE_ENTRYPOINT = { + fn: MyApp, + params: [], +}; From 7c864c98342e6e92a992ac32c1846f13eb1a314c Mon Sep 17 00:00:00 2001 From: mofeiZ <34200447+mofeiZ@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:22:35 -0500 Subject: [PATCH 2/7] [compiler][ez] Patch for JSX escape sequences in @babel/generator (#32131) Fall back to using JSXExpressionContainer for strings potentially containing escape sequences (a single backslash) to fix https://github.com/facebook/react/issues/32123. This is an extension of https://github.com/facebook/react/pull/29079 --- .../src/ReactiveScopes/CodegenReactiveFunction.ts | 2 +- .../jsx-preserve-escape-character.expect.md | 2 +- ...epro-propagate-type-of-ternary-nested.expect.md | 14 +++++++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts index 76135f96b4249..cf40d86abc552 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts @@ -2269,7 +2269,7 @@ function codegenInstructionValue( * https://en.wikipedia.org/wiki/List_of_Unicode_characters#Control_codes */ const STRING_REQUIRES_EXPR_CONTAINER_PATTERN = - /[\u{0000}-\u{001F}\u{007F}\u{0080}-\u{FFFF}]|"/u; + /[\u{0000}-\u{001F}\u{007F}\u{0080}-\u{FFFF}]|"|\\/u; function codegenJsxAttribute( cx: Context, attribute: JsxAttribute, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-preserve-escape-character.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-preserve-escape-character.expect.md index 6f8a86382d436..a539d92ed9141 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-preserve-escape-character.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/jsx-preserve-escape-character.expect.md @@ -38,7 +38,7 @@ function MyApp() { const $ = _c(1); let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = ; + t0 = ; $[0] = t0; } else { t0 = $[0]; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-propagate-type-of-ternary-nested.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-propagate-type-of-ternary-nested.expect.md index 609231ca8dab4..97109cfc4e2d1 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-propagate-type-of-ternary-nested.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-propagate-type-of-ternary-nested.expect.md @@ -42,15 +42,23 @@ function V0(t0) { gmhubcw {v1 === V3.V13 ? ( - + iawyneijcgamsfgrrjyvhjrrqvzexxwenxqoknnilmfloafyvnvkqbssqnxnexqvtcpvjysaiovjxyqrorqskfph ) : v16.v17("pyorztRC]EJzVuP^e") ? ( - + goprinbjmmjhfserfuqyluxcewpyjihektogc ) : ( - + yejarlvudihqdrdgpvahovggdnmgnueedxpbwbkdvvkdhqwrtoiual )} From b6b33bfb92c095160df7370fb488acb89c55b5ca Mon Sep 17 00:00:00 2001 From: mofeiZ <34200447+mofeiZ@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:34:08 -0500 Subject: [PATCH 3/7] [compiler][ez] rewrite invariant in InferReferenceEffects (#32093) Small patch to pass aliased context values into `Object|ArrayExpression`s --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32093). * #32099 * #32104 * #32098 * #32097 * #32096 * #32095 * #32094 * __->__ #32093 --- .../src/Inference/InferFunctionEffects.ts | 7 +- .../src/Inference/InferReferenceEffects.ts | 75 +++++++++++-------- 2 files changed, 49 insertions(+), 33 deletions(-) diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferFunctionEffects.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferFunctionEffects.ts index 0ae54839b6fa3..fe209924e4e08 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferFunctionEffects.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferFunctionEffects.ts @@ -41,11 +41,16 @@ function inferOperandEffect(state: State, place: Place): null | FunctionEffect { if (isRefOrRefValue(place.identifier)) { break; } else if (value.kind === ValueKind.Context) { + CompilerError.invariant(value.context.size > 0, { + reason: + "[InferFunctionEffects] Expected Context-kind value's capture list to be non-empty.", + loc: place.loc, + }); return { kind: 'ContextMutation', loc: place.loc, effect: place.effect, - places: value.context.size === 0 ? new Set([place]) : value.context, + places: value.context, }; } else if ( value.kind !== ValueKind.Mutable && diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferReferenceEffects.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferReferenceEffects.ts index 8cf30a9666e25..70395e58d930e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferReferenceEffects.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferReferenceEffects.ts @@ -857,17 +857,19 @@ function inferBlock( break; } case 'ArrayExpression': { - const valueKind: AbstractValue = hasContextRefOperand(state, instrValue) - ? { - kind: ValueKind.Context, - reason: new Set([ValueReason.Other]), - context: new Set(), - } - : { - kind: ValueKind.Mutable, - reason: new Set([ValueReason.Other]), - context: new Set(), - }; + const contextRefOperands = getContextRefOperand(state, instrValue); + const valueKind: AbstractValue = + contextRefOperands.length > 0 + ? { + kind: ValueKind.Context, + reason: new Set([ValueReason.Other]), + context: new Set(contextRefOperands), + } + : { + kind: ValueKind.Mutable, + reason: new Set([ValueReason.Other]), + context: new Set(), + }; continuation = { kind: 'initialize', valueKind, @@ -918,17 +920,19 @@ function inferBlock( break; } case 'ObjectExpression': { - const valueKind: AbstractValue = hasContextRefOperand(state, instrValue) - ? { - kind: ValueKind.Context, - reason: new Set([ValueReason.Other]), - context: new Set(), - } - : { - kind: ValueKind.Mutable, - reason: new Set([ValueReason.Other]), - context: new Set(), - }; + const contextRefOperands = getContextRefOperand(state, instrValue); + const valueKind: AbstractValue = + contextRefOperands.length > 0 + ? { + kind: ValueKind.Context, + reason: new Set([ValueReason.Other]), + context: new Set(contextRefOperands), + } + : { + kind: ValueKind.Mutable, + reason: new Set([ValueReason.Other]), + context: new Set(), + }; for (const property of instrValue.properties) { switch (property.kind) { @@ -1593,15 +1597,21 @@ function inferBlock( } case 'LoadLocal': { const lvalue = instr.lvalue; - const effect = - state.isDefined(lvalue) && - state.kind(lvalue).kind === ValueKind.Context - ? Effect.ConditionallyMutate - : Effect.Capture; + CompilerError.invariant( + !( + state.isDefined(lvalue) && + state.kind(lvalue).kind === ValueKind.Context + ), + { + reason: + '[InferReferenceEffects] Unexpected LoadLocal with context kind', + loc: lvalue.loc, + }, + ); state.referenceAndRecordEffects( freezeActions, instrValue.place, - effect, + Effect.Capture, ValueReason.Other, ); lvalue.effect = Effect.ConditionallyMutate; @@ -1932,19 +1942,20 @@ function inferBlock( ); } -function hasContextRefOperand( +function getContextRefOperand( state: InferenceState, instrValue: InstructionValue, -): boolean { +): Array { + const result = []; for (const place of eachInstructionValueOperand(instrValue)) { if ( state.isDefined(place) && state.kind(place).kind === ValueKind.Context ) { - return true; + result.push(place); } } - return false; + return result; } export function getFunctionCallSignature( From deba48a72795d1332fe1df1159fc6b73566667fe Mon Sep 17 00:00:00 2001 From: mofeiZ <34200447+mofeiZ@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:58:52 -0500 Subject: [PATCH 4/7] [compiler] Repro for invalid Array.map type (#32094) See test fixture --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32094). * #32099 * #32104 * #32098 * #32097 * #32096 * #32095 * __->__ #32094 * #32093 --- ...-invalid-mixedreadonly-map-shape.expect.md | 163 ++++++++++++++++++ .../bug-invalid-mixedreadonly-map-shape.js | 56 ++++++ .../packages/snap/src/SproutTodoFilter.ts | 1 + 3 files changed, 220 insertions(+) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.expect.md new file mode 100644 index 0000000000000..1418062c33458 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.expect.md @@ -0,0 +1,163 @@ + +## Input + +```javascript +import { + arrayPush, + identity, + makeArray, + Stringify, + useFragment, +} from 'shared-runtime'; + +/** + * Bug repro showing why it's invalid for function references to be annotated + * with a `Read` effect when that reference might lead to the function being + * invoked. + * + * Note that currently, `Array.map` is annotated to have `Read` effects on its + * operands. This is incorrect as function effects must be replayed when `map` + * is called + * - Read: non-aliasing data dependency + * - Capture: maybe-aliasing data dependency + * - ConditionallyMutate: maybe-aliasing data dependency; maybe-write / invoke + * but only if the value is mutable + * + * Invalid evaluator result: Found differences in evaluator results Non-forget + * (expected): (kind: ok) + *
{"x":[2,2,2],"count":3}
{"item":1}
+ *
{"x":[2,2,2],"count":4}
{"item":1}
+ * Forget: + * (kind: ok) + *
{"x":[2,2,2],"count":3}
{"item":1}
+ *
{"x":[2,2,2,2,2,2],"count":4}
{"item":1}
+ */ + +function Component({extraJsx}) { + const x = makeArray(); + const items = useFragment(); + const jsx = items.a.map((item, i) => { + arrayPush(x, 2); + return ; + }); + const offset = jsx.length; + for (let i = 0; i < extraJsx; i++) { + jsx.push(); + } + const count = jsx.length; + identity(count); + return ( + <> + + {jsx[0]} + + ); +} +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{extraJsx: 0}], + sequentialRenders: [{extraJsx: 0}, {extraJsx: 1}], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +import { + arrayPush, + identity, + makeArray, + Stringify, + useFragment, +} from "shared-runtime"; + +/** + * Bug repro showing why it's invalid for function references to be annotated + * with a `Read` effect when that reference might lead to the function being + * invoked. + * + * Note that currently, `Array.map` is annotated to have `Read` effects on its + * operands. This is incorrect as function effects must be replayed when `map` + * is called + * - Read: non-aliasing data dependency + * - Capture: maybe-aliasing data dependency + * - ConditionallyMutate: maybe-aliasing data dependency; maybe-write / invoke + * but only if the value is mutable + * + * Invalid evaluator result: Found differences in evaluator results Non-forget + * (expected): (kind: ok) + *
{"x":[2,2,2],"count":3}
{"item":1}
+ *
{"x":[2,2,2],"count":4}
{"item":1}
+ * Forget: + * (kind: ok) + *
{"x":[2,2,2],"count":3}
{"item":1}
+ *
{"x":[2,2,2,2,2,2],"count":4}
{"item":1}
+ */ + +function Component(t0) { + const $ = _c(9); + const { extraJsx } = t0; + let t1; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t1 = makeArray(); + $[0] = t1; + } else { + t1 = $[0]; + } + const x = t1; + const items = useFragment(); + let jsx; + if ($[1] !== extraJsx || $[2] !== items.a) { + jsx = items.a.map((item, i) => { + arrayPush(x, 2); + return ; + }); + const offset = jsx.length; + for (let i_0 = 0; i_0 < extraJsx; i_0++) { + jsx.push(); + } + $[1] = extraJsx; + $[2] = items.a; + $[3] = jsx; + } else { + jsx = $[3]; + } + + const count = jsx.length; + identity(count); + let t2; + if ($[4] !== count) { + t2 = ; + $[4] = count; + $[5] = t2; + } else { + t2 = $[5]; + } + const t3 = jsx[0]; + let t4; + if ($[6] !== t2 || $[7] !== t3) { + t4 = ( + <> + {t2} + {t3} + + ); + $[6] = t2; + $[7] = t3; + $[8] = t4; + } else { + t4 = $[8]; + } + return t4; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ extraJsx: 0 }], + sequentialRenders: [{ extraJsx: 0 }, { extraJsx: 1 }], +}; + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.js new file mode 100644 index 0000000000000..d038cf6cd38a1 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.js @@ -0,0 +1,56 @@ +import { + arrayPush, + identity, + makeArray, + Stringify, + useFragment, +} from 'shared-runtime'; + +/** + * Bug repro showing why it's invalid for function references to be annotated + * with a `Read` effect when that reference might lead to the function being + * invoked. + * + * Note that currently, `Array.map` is annotated to have `Read` effects on its + * operands. This is incorrect as function effects must be replayed when `map` + * is called + * - Read: non-aliasing data dependency + * - Capture: maybe-aliasing data dependency + * - ConditionallyMutate: maybe-aliasing data dependency; maybe-write / invoke + * but only if the value is mutable + * + * Invalid evaluator result: Found differences in evaluator results Non-forget + * (expected): (kind: ok) + *
{"x":[2,2,2],"count":3}
{"item":1}
+ *
{"x":[2,2,2],"count":4}
{"item":1}
+ * Forget: + * (kind: ok) + *
{"x":[2,2,2],"count":3}
{"item":1}
+ *
{"x":[2,2,2,2,2,2],"count":4}
{"item":1}
+ */ + +function Component({extraJsx}) { + const x = makeArray(); + const items = useFragment(); + const jsx = items.a.map((item, i) => { + arrayPush(x, 2); + return ; + }); + const offset = jsx.length; + for (let i = 0; i < extraJsx; i++) { + jsx.push(); + } + const count = jsx.length; + identity(count); + return ( + <> + + {jsx[0]} + + ); +} +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{extraJsx: 0}], + sequentialRenders: [{extraJsx: 0}, {extraJsx: 1}], +}; diff --git a/compiler/packages/snap/src/SproutTodoFilter.ts b/compiler/packages/snap/src/SproutTodoFilter.ts index 361070739630c..f363fd922e51a 100644 --- a/compiler/packages/snap/src/SproutTodoFilter.ts +++ b/compiler/packages/snap/src/SproutTodoFilter.ts @@ -486,6 +486,7 @@ const skipFilter = new Set([ 'bug-aliased-capture-mutate', 'bug-functiondecl-hoisting', 'bug-try-catch-maybe-null-dependency', + 'bug-invalid-mixedreadonly-map-shape', 'bug-type-inference-control-flow', 'reduce-reactive-deps/bug-infer-function-cond-access-not-hoisted', 'bug-invalid-phi-as-dependency', From b83090fca2d96283a5c6153abb65eaa5cc81c9ba Mon Sep 17 00:00:00 2001 From: mofeiZ <34200447+mofeiZ@users.noreply.github.com> Date: Wed, 22 Jan 2025 15:02:51 -0500 Subject: [PATCH 5/7] [compiler] Fix invalid Array.map type (#32095) See test fixture --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32095). * #32099 * #32104 * #32098 * #32097 * #32096 * __->__ #32095 * #32094 * #32093 --- .../src/HIR/ObjectShape.ts | 10 +- .../mixedreadonly-mutating-map.expect.md | 156 ++++++++++++++++++ .../compiler/mixedreadonly-mutating-map.js | 59 +++++++ 3 files changed, 224 insertions(+), 1 deletion(-) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mixedreadonly-mutating-map.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mixedreadonly-mutating-map.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts index 7c05c05531ae9..f396ae18b0461 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts @@ -549,8 +549,16 @@ addObject(BUILTIN_SHAPES, BuiltInMixedReadonlyId, [ [ 'map', addFunction(BUILTIN_SHAPES, [], { + /** + * Note `map`'s arguments are annotated as Effect.ConditionallyMutate as + * calling `.map(fn)` might invoke `fn`, which means replaying its + * effects. + * + * (Note that Effect.Read / Effect.Capture on a function type means + * potential data dependency or aliasing respectively.) + */ positionalParams: [], - restParam: Effect.Read, + restParam: Effect.ConditionallyMutate, returnType: {kind: 'Object', shapeId: BuiltInArrayId}, calleeEffect: Effect.ConditionallyMutate, returnValueKind: ValueKind.Mutable, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mixedreadonly-mutating-map.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mixedreadonly-mutating-map.expect.md new file mode 100644 index 0000000000000..4867388a864d2 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mixedreadonly-mutating-map.expect.md @@ -0,0 +1,156 @@ + +## Input + +```javascript +import { + arrayPush, + identity, + makeArray, + Stringify, + useFragment, +} from 'shared-runtime'; + +/** + * Bug repro showing why it's invalid for function references to be annotated + * with a `Read` effect when that reference might lead to the function being + * invoked. + * + * Note that currently, `Array.map` is annotated to have `Read` effects on its + * operands. This is incorrect as function effects must be replayed when `map` + * is called + * - Read: non-aliasing data dependency + * - Capture: maybe-aliasing data dependency + * - ConditionallyMutate: maybe-aliasing data dependency; maybe-write / invoke + * but only if the value is mutable + * + * Invalid evaluator result: Found differences in evaluator results Non-forget + * (expected): (kind: ok) + *
{"x":[2,2,2],"count":3}
{"item":1}
+ *
{"x":[2,2,2],"count":4}
{"item":1}
+ * Forget: + * (kind: ok) + *
{"x":[2,2,2],"count":3}
{"item":1}
+ *
{"x":[2,2,2,2,2,2],"count":4}
{"item":1}
+ */ + +function Component({extraJsx}) { + const x = makeArray(); + const items = useFragment(); + // This closure has the following effects that must be replayed: + // - MaybeFreeze / Capture of `items` + // - ConditionalMutate of x + const jsx = items.a.map((item, i) => { + arrayPush(x, 2); + return ; + }); + const offset = jsx.length; + for (let i = 0; i < extraJsx; i++) { + jsx.push(); + } + const count = jsx.length; + identity(count); + return ( + <> + + {jsx[0]} + + ); +} +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{extraJsx: 0}], + sequentialRenders: [{extraJsx: 0}, {extraJsx: 1}], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +import { + arrayPush, + identity, + makeArray, + Stringify, + useFragment, +} from "shared-runtime"; + +/** + * Bug repro showing why it's invalid for function references to be annotated + * with a `Read` effect when that reference might lead to the function being + * invoked. + * + * Note that currently, `Array.map` is annotated to have `Read` effects on its + * operands. This is incorrect as function effects must be replayed when `map` + * is called + * - Read: non-aliasing data dependency + * - Capture: maybe-aliasing data dependency + * - ConditionallyMutate: maybe-aliasing data dependency; maybe-write / invoke + * but only if the value is mutable + * + * Invalid evaluator result: Found differences in evaluator results Non-forget + * (expected): (kind: ok) + *
{"x":[2,2,2],"count":3}
{"item":1}
+ *
{"x":[2,2,2],"count":4}
{"item":1}
+ * Forget: + * (kind: ok) + *
{"x":[2,2,2],"count":3}
{"item":1}
+ *
{"x":[2,2,2,2,2,2],"count":4}
{"item":1}
+ */ + +function Component(t0) { + const $ = _c(6); + const { extraJsx } = t0; + const x = makeArray(); + const items = useFragment(); + + const jsx = items.a.map((item, i) => { + arrayPush(x, 2); + return ; + }); + const offset = jsx.length; + for (let i_0 = 0; i_0 < extraJsx; i_0++) { + jsx.push(); + } + + const count = jsx.length; + identity(count); + let t1; + if ($[0] !== count || $[1] !== x) { + t1 = ; + $[0] = count; + $[1] = x; + $[2] = t1; + } else { + t1 = $[2]; + } + const t2 = jsx[0]; + let t3; + if ($[3] !== t1 || $[4] !== t2) { + t3 = ( + <> + {t1} + {t2} + + ); + $[3] = t1; + $[4] = t2; + $[5] = t3; + } else { + t3 = $[5]; + } + return t3; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ extraJsx: 0 }], + sequentialRenders: [{ extraJsx: 0 }, { extraJsx: 1 }], +}; + +``` + +### Eval output +(kind: ok)
{"x":[2,2,2],"count":3}
{"item":1}
+
{"x":[2,2,2],"count":4}
{"item":1}
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mixedreadonly-mutating-map.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mixedreadonly-mutating-map.js new file mode 100644 index 0000000000000..858a4ab3dc693 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mixedreadonly-mutating-map.js @@ -0,0 +1,59 @@ +import { + arrayPush, + identity, + makeArray, + Stringify, + useFragment, +} from 'shared-runtime'; + +/** + * Bug repro showing why it's invalid for function references to be annotated + * with a `Read` effect when that reference might lead to the function being + * invoked. + * + * Note that currently, `Array.map` is annotated to have `Read` effects on its + * operands. This is incorrect as function effects must be replayed when `map` + * is called + * - Read: non-aliasing data dependency + * - Capture: maybe-aliasing data dependency + * - ConditionallyMutate: maybe-aliasing data dependency; maybe-write / invoke + * but only if the value is mutable + * + * Invalid evaluator result: Found differences in evaluator results Non-forget + * (expected): (kind: ok) + *
{"x":[2,2,2],"count":3}
{"item":1}
+ *
{"x":[2,2,2],"count":4}
{"item":1}
+ * Forget: + * (kind: ok) + *
{"x":[2,2,2],"count":3}
{"item":1}
+ *
{"x":[2,2,2,2,2,2],"count":4}
{"item":1}
+ */ + +function Component({extraJsx}) { + const x = makeArray(); + const items = useFragment(); + // This closure has the following effects that must be replayed: + // - MaybeFreeze / Capture of `items` + // - ConditionalMutate of x + const jsx = items.a.map((item, i) => { + arrayPush(x, 2); + return ; + }); + const offset = jsx.length; + for (let i = 0; i < extraJsx; i++) { + jsx.push(); + } + const count = jsx.length; + identity(count); + return ( + <> + + {jsx[0]} + + ); +} +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{extraJsx: 0}], + sequentialRenders: [{extraJsx: 0}, {extraJsx: 1}], +}; From a0b91fbd650f9398cca12fcda0c426c434eeb6d8 Mon Sep 17 00:00:00 2001 From: mofeiZ <34200447+mofeiZ@users.noreply.github.com> Date: Wed, 22 Jan 2025 16:21:53 -0500 Subject: [PATCH 6/7] [compiler][ez] Fix main (bad rebase / amend for #32095) (#32160) See title: this fixes test cases broken by https://github.com/facebook/react/pull/32095 adding instead of moving new test fixtures --- .../src/HIR/ObjectShape.ts | 4 +- ...-invalid-mixedreadonly-map-shape.expect.md | 163 ------------------ .../bug-invalid-mixedreadonly-map-shape.js | 56 ------ 3 files changed, 2 insertions(+), 221 deletions(-) delete mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.expect.md delete mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts index f396ae18b0461..f51768c586b72 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts @@ -569,7 +569,7 @@ addObject(BUILTIN_SHAPES, BuiltInMixedReadonlyId, [ 'flatMap', addFunction(BUILTIN_SHAPES, [], { positionalParams: [], - restParam: Effect.Read, + restParam: Effect.ConditionallyMutate, returnType: {kind: 'Object', shapeId: BuiltInArrayId}, calleeEffect: Effect.ConditionallyMutate, returnValueKind: ValueKind.Mutable, @@ -580,7 +580,7 @@ addObject(BUILTIN_SHAPES, BuiltInMixedReadonlyId, [ 'filter', addFunction(BUILTIN_SHAPES, [], { positionalParams: [], - restParam: Effect.Read, + restParam: Effect.ConditionallyMutate, returnType: {kind: 'Object', shapeId: BuiltInArrayId}, calleeEffect: Effect.ConditionallyMutate, returnValueKind: ValueKind.Mutable, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.expect.md deleted file mode 100644 index 1418062c33458..0000000000000 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.expect.md +++ /dev/null @@ -1,163 +0,0 @@ - -## Input - -```javascript -import { - arrayPush, - identity, - makeArray, - Stringify, - useFragment, -} from 'shared-runtime'; - -/** - * Bug repro showing why it's invalid for function references to be annotated - * with a `Read` effect when that reference might lead to the function being - * invoked. - * - * Note that currently, `Array.map` is annotated to have `Read` effects on its - * operands. This is incorrect as function effects must be replayed when `map` - * is called - * - Read: non-aliasing data dependency - * - Capture: maybe-aliasing data dependency - * - ConditionallyMutate: maybe-aliasing data dependency; maybe-write / invoke - * but only if the value is mutable - * - * Invalid evaluator result: Found differences in evaluator results Non-forget - * (expected): (kind: ok) - *
{"x":[2,2,2],"count":3}
{"item":1}
- *
{"x":[2,2,2],"count":4}
{"item":1}
- * Forget: - * (kind: ok) - *
{"x":[2,2,2],"count":3}
{"item":1}
- *
{"x":[2,2,2,2,2,2],"count":4}
{"item":1}
- */ - -function Component({extraJsx}) { - const x = makeArray(); - const items = useFragment(); - const jsx = items.a.map((item, i) => { - arrayPush(x, 2); - return ; - }); - const offset = jsx.length; - for (let i = 0; i < extraJsx; i++) { - jsx.push(); - } - const count = jsx.length; - identity(count); - return ( - <> - - {jsx[0]} - - ); -} -export const FIXTURE_ENTRYPOINT = { - fn: Component, - params: [{extraJsx: 0}], - sequentialRenders: [{extraJsx: 0}, {extraJsx: 1}], -}; - -``` - -## Code - -```javascript -import { c as _c } from "react/compiler-runtime"; -import { - arrayPush, - identity, - makeArray, - Stringify, - useFragment, -} from "shared-runtime"; - -/** - * Bug repro showing why it's invalid for function references to be annotated - * with a `Read` effect when that reference might lead to the function being - * invoked. - * - * Note that currently, `Array.map` is annotated to have `Read` effects on its - * operands. This is incorrect as function effects must be replayed when `map` - * is called - * - Read: non-aliasing data dependency - * - Capture: maybe-aliasing data dependency - * - ConditionallyMutate: maybe-aliasing data dependency; maybe-write / invoke - * but only if the value is mutable - * - * Invalid evaluator result: Found differences in evaluator results Non-forget - * (expected): (kind: ok) - *
{"x":[2,2,2],"count":3}
{"item":1}
- *
{"x":[2,2,2],"count":4}
{"item":1}
- * Forget: - * (kind: ok) - *
{"x":[2,2,2],"count":3}
{"item":1}
- *
{"x":[2,2,2,2,2,2],"count":4}
{"item":1}
- */ - -function Component(t0) { - const $ = _c(9); - const { extraJsx } = t0; - let t1; - if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t1 = makeArray(); - $[0] = t1; - } else { - t1 = $[0]; - } - const x = t1; - const items = useFragment(); - let jsx; - if ($[1] !== extraJsx || $[2] !== items.a) { - jsx = items.a.map((item, i) => { - arrayPush(x, 2); - return ; - }); - const offset = jsx.length; - for (let i_0 = 0; i_0 < extraJsx; i_0++) { - jsx.push(); - } - $[1] = extraJsx; - $[2] = items.a; - $[3] = jsx; - } else { - jsx = $[3]; - } - - const count = jsx.length; - identity(count); - let t2; - if ($[4] !== count) { - t2 = ; - $[4] = count; - $[5] = t2; - } else { - t2 = $[5]; - } - const t3 = jsx[0]; - let t4; - if ($[6] !== t2 || $[7] !== t3) { - t4 = ( - <> - {t2} - {t3} - - ); - $[6] = t2; - $[7] = t3; - $[8] = t4; - } else { - t4 = $[8]; - } - return t4; -} - -export const FIXTURE_ENTRYPOINT = { - fn: Component, - params: [{ extraJsx: 0 }], - sequentialRenders: [{ extraJsx: 0 }, { extraJsx: 1 }], -}; - -``` - \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.js deleted file mode 100644 index d038cf6cd38a1..0000000000000 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-mixedreadonly-map-shape.js +++ /dev/null @@ -1,56 +0,0 @@ -import { - arrayPush, - identity, - makeArray, - Stringify, - useFragment, -} from 'shared-runtime'; - -/** - * Bug repro showing why it's invalid for function references to be annotated - * with a `Read` effect when that reference might lead to the function being - * invoked. - * - * Note that currently, `Array.map` is annotated to have `Read` effects on its - * operands. This is incorrect as function effects must be replayed when `map` - * is called - * - Read: non-aliasing data dependency - * - Capture: maybe-aliasing data dependency - * - ConditionallyMutate: maybe-aliasing data dependency; maybe-write / invoke - * but only if the value is mutable - * - * Invalid evaluator result: Found differences in evaluator results Non-forget - * (expected): (kind: ok) - *
{"x":[2,2,2],"count":3}
{"item":1}
- *
{"x":[2,2,2],"count":4}
{"item":1}
- * Forget: - * (kind: ok) - *
{"x":[2,2,2],"count":3}
{"item":1}
- *
{"x":[2,2,2,2,2,2],"count":4}
{"item":1}
- */ - -function Component({extraJsx}) { - const x = makeArray(); - const items = useFragment(); - const jsx = items.a.map((item, i) => { - arrayPush(x, 2); - return ; - }); - const offset = jsx.length; - for (let i = 0; i < extraJsx; i++) { - jsx.push(); - } - const count = jsx.length; - identity(count); - return ( - <> - - {jsx[0]} - - ); -} -export const FIXTURE_ENTRYPOINT = { - fn: Component, - params: [{extraJsx: 0}], - sequentialRenders: [{extraJsx: 0}, {extraJsx: 1}], -}; From ae9017ceabb2a36a04c249ad5342e0b1af3e1a54 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Wed, 22 Jan 2025 17:09:41 -0500 Subject: [PATCH 7/7] Move effect dep inference tests to infer-effect-dependencies directory (#32161) Summary: Grouping them to make it easy to see that they are all related Test Plan: --- .../infer-deps-custom-config.expect.md | 0 .../{ => infer-effect-dependencies}/infer-deps-custom-config.js | 0 .../infer-effect-dependencies.expect.md | 0 .../{ => infer-effect-dependencies}/infer-effect-dependencies.js | 0 .../{ => infer-effect-dependencies}/nonreactive-dep.expect.md | 0 .../compiler/{ => infer-effect-dependencies}/nonreactive-dep.js | 0 .../nonreactive-ref-helper.expect.md | 0 .../{ => infer-effect-dependencies}/nonreactive-ref-helper.js | 0 .../{ => infer-effect-dependencies}/nonreactive-ref.expect.md | 0 .../compiler/{ => infer-effect-dependencies}/nonreactive-ref.js | 0 .../{ => infer-effect-dependencies}/outlined-function.expect.md | 0 .../compiler/{ => infer-effect-dependencies}/outlined-function.js | 0 .../pruned-nonreactive-obj.expect.md | 0 .../{ => infer-effect-dependencies}/pruned-nonreactive-obj.js | 0 .../reactive-memberexpr-merge.expect.md | 0 .../{ => infer-effect-dependencies}/reactive-memberexpr-merge.js | 0 .../{ => infer-effect-dependencies}/reactive-memberexpr.expect.md | 0 .../{ => infer-effect-dependencies}/reactive-memberexpr.js | 0 .../reactive-optional-chain.expect.md | 0 .../{ => infer-effect-dependencies}/reactive-optional-chain.js | 0 .../{ => infer-effect-dependencies}/reactive-variable.expect.md | 0 .../compiler/{ => infer-effect-dependencies}/reactive-variable.js | 0 .../todo-import-namespace-useEffect.expect.md | 0 .../todo-import-namespace-useEffect.js | 0 24 files changed, 0 insertions(+), 0 deletions(-) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/infer-deps-custom-config.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/infer-deps-custom-config.js (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/infer-effect-dependencies.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/infer-effect-dependencies.js (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/nonreactive-dep.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/nonreactive-dep.js (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/nonreactive-ref-helper.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/nonreactive-ref-helper.js (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/nonreactive-ref.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/nonreactive-ref.js (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/outlined-function.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/outlined-function.js (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/pruned-nonreactive-obj.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/pruned-nonreactive-obj.js (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/reactive-memberexpr-merge.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/reactive-memberexpr-merge.js (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/reactive-memberexpr.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/reactive-memberexpr.js (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/reactive-optional-chain.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/reactive-optional-chain.js (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/reactive-variable.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/reactive-variable.js (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/todo-import-namespace-useEffect.expect.md (100%) rename compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/{ => infer-effect-dependencies}/todo-import-namespace-useEffect.js (100%) diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-deps-custom-config.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/infer-deps-custom-config.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-deps-custom-config.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/infer-deps-custom-config.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-deps-custom-config.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/infer-deps-custom-config.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-deps-custom-config.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/infer-deps-custom-config.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/infer-effect-dependencies.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/infer-effect-dependencies.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/infer-effect-dependencies.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/infer-effect-dependencies.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/nonreactive-dep.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-dep.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/nonreactive-dep.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-dep.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/nonreactive-dep.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-dep.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/nonreactive-dep.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-dep.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/nonreactive-ref-helper.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-ref-helper.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/nonreactive-ref-helper.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-ref-helper.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/nonreactive-ref-helper.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-ref-helper.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/nonreactive-ref-helper.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-ref-helper.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/nonreactive-ref.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-ref.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/nonreactive-ref.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-ref.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/nonreactive-ref.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-ref.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/nonreactive-ref.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/nonreactive-ref.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/outlined-function.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/outlined-function.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/outlined-function.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/outlined-function.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/outlined-function.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/outlined-function.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/outlined-function.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/outlined-function.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/pruned-nonreactive-obj.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/pruned-nonreactive-obj.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/pruned-nonreactive-obj.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/pruned-nonreactive-obj.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/pruned-nonreactive-obj.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/pruned-nonreactive-obj.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/pruned-nonreactive-obj.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/pruned-nonreactive-obj.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-memberexpr-merge.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-memberexpr-merge.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-memberexpr-merge.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-memberexpr-merge.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-memberexpr-merge.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-memberexpr-merge.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-memberexpr-merge.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-memberexpr-merge.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-memberexpr.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-memberexpr.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-memberexpr.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-memberexpr.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-memberexpr.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-memberexpr.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-memberexpr.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-memberexpr.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-optional-chain.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-optional-chain.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-optional-chain.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-optional-chain.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-optional-chain.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-optional-chain.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-optional-chain.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-optional-chain.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-variable.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-variable.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-variable.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-variable.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-variable.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-variable.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/reactive-variable.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/reactive-variable.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo-import-namespace-useEffect.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/todo-import-namespace-useEffect.expect.md similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo-import-namespace-useEffect.expect.md rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/todo-import-namespace-useEffect.expect.md diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo-import-namespace-useEffect.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/todo-import-namespace-useEffect.js similarity index 100% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo-import-namespace-useEffect.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/todo-import-namespace-useEffect.js