Skip to content

Commit fe816b4

Browse files
committed
[compiler][bugfix] expand StoreContext to const / let / function variants (#32747)
```js function Component() { useEffect(() => { let hasCleanedUp = false; document.addEventListener(..., () => hasCleanedUp ? foo() : bar()); // effect return values shouldn't be typed as frozen return () => { hasCleanedUp = true; } }; } ``` ### Problem `PruneHoistedContexts` currently strips hoisted declarations and rewrites the first `StoreContext` reassignment to a declaration. For example, in the following example, instruction 0 is removed while a synthetic `DeclareContext let` is inserted before instruction 1. ```js // source const cb = () => x; // reference that causes x to be hoisted let x = 4; x = 5; // React Compiler IR [0] DeclareContext HoistedLet 'x' ... [1] StoreContext reassign 'x' = 4 [2] StoreContext reassign 'x' = 5 ``` Currently, we don't account for `DeclareContext let`. As a result, we're rewriting to insert duplicate declarations. ```js // source const cb = () => x; // reference that causes x to be hoisted let x; x = 5; // React Compiler IR [0] DeclareContext HoistedLet 'x' ... [1] DeclareContext Let 'x' [2] StoreContext reassign 'x' = 5 ``` ### Solution Instead of always lowering context variables to a DeclareContext followed by a StoreContext reassign, we can keep `kind: 'Const' | 'Let' | 'Reassign' | etc` on StoreContext. Pros: - retain more information in HIR, so we can codegen easily `const` and `let` context variable declarations back - pruning hoisted `DeclareContext` instructions is simple. Cons: - passes are more verbose as we need to check for both `DeclareContext` and `StoreContext` declarations ~(note: also see alternative implementation in #32745 ### Testing Context variables are tricky. I synced and diffed changes in a large meta codebase and feel pretty confident about landing this. About 0.01% of compiled files changed. Among these changes, ~25% were [direct bugfixes](https://www.internalfb.com/phabricator/paste/view/P1800029094). The [other changes](https://www.internalfb.com/phabricator/paste/view/P1800028575) were primarily due to changed (corrected) mutable ranges from #33047. I tried to represent most interesting changes in new test fixtures ` DiffTrain build for [9d795d3](9d795d3)
1 parent b8dcf8d commit fe816b4

35 files changed

+292
-266
lines changed

compiled/eslint-plugin-react-hooks/index.js

Lines changed: 206 additions & 180 deletions
Large diffs are not rendered by default.

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
12f4cb85c5847758ece81fc95b7eaedc1fb9ebd0
1+
9d795d3808f3202b36740a7a8eb60567bd7f6d90
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
12f4cb85c5847758ece81fc95b7eaedc1fb9ebd0
1+
9d795d3808f3202b36740a7a8eb60567bd7f6d90

compiled/facebook-www/React-dev.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1538,7 +1538,7 @@ __DEV__ &&
15381538
exports.useTransition = function () {
15391539
return resolveDispatcher().useTransition();
15401540
};
1541-
exports.version = "19.2.0-www-classic-12f4cb85-20250430";
1541+
exports.version = "19.2.0-www-classic-9d795d38-20250430";
15421542
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
15431543
"function" ===
15441544
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/React-dev.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1538,7 +1538,7 @@ __DEV__ &&
15381538
exports.useTransition = function () {
15391539
return resolveDispatcher().useTransition();
15401540
};
1541-
exports.version = "19.2.0-www-modern-12f4cb85-20250430";
1541+
exports.version = "19.2.0-www-modern-9d795d38-20250430";
15421542
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
15431543
"function" ===
15441544
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/React-prod.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,4 +636,4 @@ exports.useSyncExternalStore = function (
636636
exports.useTransition = function () {
637637
return ReactSharedInternals.H.useTransition();
638638
};
639-
exports.version = "19.2.0-www-classic-12f4cb85-20250430";
639+
exports.version = "19.2.0-www-classic-9d795d38-20250430";

compiled/facebook-www/React-prod.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,4 +636,4 @@ exports.useSyncExternalStore = function (
636636
exports.useTransition = function () {
637637
return ReactSharedInternals.H.useTransition();
638638
};
639-
exports.version = "19.2.0-www-modern-12f4cb85-20250430";
639+
exports.version = "19.2.0-www-modern-9d795d38-20250430";

compiled/facebook-www/React-profiling.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ exports.useSyncExternalStore = function (
640640
exports.useTransition = function () {
641641
return ReactSharedInternals.H.useTransition();
642642
};
643-
exports.version = "19.2.0-www-classic-12f4cb85-20250430";
643+
exports.version = "19.2.0-www-classic-9d795d38-20250430";
644644
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
645645
"function" ===
646646
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/React-profiling.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ exports.useSyncExternalStore = function (
640640
exports.useTransition = function () {
641641
return ReactSharedInternals.H.useTransition();
642642
};
643-
exports.version = "19.2.0-www-modern-12f4cb85-20250430";
643+
exports.version = "19.2.0-www-modern-9d795d38-20250430";
644644
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
645645
"function" ===
646646
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/ReactART-dev.classic.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19014,10 +19014,10 @@ __DEV__ &&
1901419014
(function () {
1901519015
var internals = {
1901619016
bundleType: 1,
19017-
version: "19.2.0-www-classic-12f4cb85-20250430",
19017+
version: "19.2.0-www-classic-9d795d38-20250430",
1901819018
rendererPackageName: "react-art",
1901919019
currentDispatcherRef: ReactSharedInternals,
19020-
reconcilerVersion: "19.2.0-www-classic-12f4cb85-20250430"
19020+
reconcilerVersion: "19.2.0-www-classic-9d795d38-20250430"
1902119021
};
1902219022
internals.overrideHookState = overrideHookState;
1902319023
internals.overrideHookStateDeletePath = overrideHookStateDeletePath;
@@ -19051,7 +19051,7 @@ __DEV__ &&
1905119051
exports.Shape = Shape;
1905219052
exports.Surface = Surface;
1905319053
exports.Text = Text;
19054-
exports.version = "19.2.0-www-classic-12f4cb85-20250430";
19054+
exports.version = "19.2.0-www-classic-9d795d38-20250430";
1905519055
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
1905619056
"function" ===
1905719057
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

0 commit comments

Comments
 (0)