From 0e7cdebb32817de0e0bbee3b362f0959e36c959c Mon Sep 17 00:00:00 2001
From: Joseph Savona <6425824+josephsavona@users.noreply.github.com>
Date: Wed, 18 Jun 2025 15:43:33 -0700
Subject: [PATCH] [compiler] Repro for case of lost precision in new inference
(#33522)
In comparing compilation output of the old/new inference models I found
this case (heavily distilled into a fixture). Roughly speaking the
scenario is:
* Create a mutable object `x`
* Extract part of that object and pass it to a hook/jsx so that _part_
becomes frozen
* Mutate `x`, even indirectly.
In the old model we can still independently memoize the value from the
middle step, since we assume that part of the larger value is not
changing. In the new model, the mutation from the later step effectively
overrides the freeze effect in step 2, and considers the value to have
changed later anyway.
We've already rolled out and vetted the previous behavior, confirming
that the heuristic of "that part of the mutable object is fozen now" is
generally safe. I'll fix in a follow-up.
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33522).
* #33571
* #33558
* #33547
* #33543
* #33533
* #33532
* #33530
* #33526
* __->__ #33522
* #33518
---
...jsx-captures-value-mutated-later.expect.md | 53 +++++++++++++++++++
.../repro-jsx-captures-value-mutated-later.js | 15 ++++++
2 files changed, 68 insertions(+)
create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-jsx-captures-value-mutated-later.expect.md
create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-jsx-captures-value-mutated-later.js
diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-jsx-captures-value-mutated-later.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-jsx-captures-value-mutated-later.expect.md
new file mode 100644
index 0000000000..109219e03a
--- /dev/null
+++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-jsx-captures-value-mutated-later.expect.md
@@ -0,0 +1,53 @@
+
+## Input
+
+```javascript
+// @flow @enableNewMutationAliasingModel
+
+import {identity, Stringify, useFragment} from 'shared-runtime';
+
+component Example() {
+ const data = useFragment();
+
+ const {a, b} = identity(data);
+
+ const el = ;
+
+ identity(a.at(0));
+
+ return ;
+}
+
+```
+
+## Code
+
+```javascript
+import { c as _c } from "react/compiler-runtime";
+
+import { identity, Stringify, useFragment } from "shared-runtime";
+
+function Example() {
+ const $ = _c(2);
+ const data = useFragment();
+ let t0;
+ if ($[0] !== data) {
+ const { a, b } = identity(data);
+
+ const el = ;
+
+ identity(a.at(0));
+
+ t0 = ;
+ $[0] = data;
+ $[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/new-mutability/repro-jsx-captures-value-mutated-later.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-jsx-captures-value-mutated-later.js
new file mode 100644
index 0000000000..7ab6dbc30a
--- /dev/null
+++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/new-mutability/repro-jsx-captures-value-mutated-later.js
@@ -0,0 +1,15 @@
+// @flow @enableNewMutationAliasingModel
+
+import {identity, Stringify, useFragment} from 'shared-runtime';
+
+component Example() {
+ const data = useFragment();
+
+ const {a, b} = identity(data);
+
+ const el = ;
+
+ identity(a.at(0));
+
+ return ;
+}