Skip to content

Commit 97b9414

Browse files
committed
[compiler] Fix for false positive mutation of destructured spread object (#33786)
When destructuring, spread creates a new mutable object that _captures_ part of the original rvalue. This new value is safe to modify. When making this change I realized that we weren't inferring array pattern spread as creating an array (in type inference) so I also added that here. DiffTrain build for [448f781](448f781)
1 parent 49e4c08 commit 97b9414

35 files changed

+149
-91
lines changed

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

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19110,6 +19110,44 @@ function* eachPatternOperand(pattern) {
1911019110
}
1911119111
}
1911219112
}
19113+
function* eachPatternItem(pattern) {
19114+
switch (pattern.kind) {
19115+
case 'ArrayPattern': {
19116+
for (const item of pattern.items) {
19117+
if (item.kind === 'Identifier') {
19118+
yield item;
19119+
}
19120+
else if (item.kind === 'Spread') {
19121+
yield item;
19122+
}
19123+
else if (item.kind === 'Hole') {
19124+
continue;
19125+
}
19126+
else {
19127+
assertExhaustive$1(item, `Unexpected item kind \`${item.kind}\``);
19128+
}
19129+
}
19130+
break;
19131+
}
19132+
case 'ObjectPattern': {
19133+
for (const property of pattern.properties) {
19134+
if (property.kind === 'ObjectProperty') {
19135+
yield property.place;
19136+
}
19137+
else if (property.kind === 'Spread') {
19138+
yield property;
19139+
}
19140+
else {
19141+
assertExhaustive$1(property, `Unexpected item kind \`${property.kind}\``);
19142+
}
19143+
}
19144+
break;
19145+
}
19146+
default: {
19147+
assertExhaustive$1(pattern, `Unexpected pattern kind \`${pattern.kind}\``);
19148+
}
19149+
}
19150+
}
1911319151
function mapInstructionLValues(instr, fn) {
1911419152
switch (instr.value.kind) {
1911519153
case 'DeclareLocal':
@@ -41879,20 +41917,34 @@ function computeSignatureForInstruction(context, env, instr) {
4187941917
break;
4188041918
}
4188141919
case 'Destructure': {
41882-
for (const patternLValue of eachInstructionValueLValue(value)) {
41883-
if (isPrimitiveType(patternLValue.identifier)) {
41920+
for (const patternItem of eachPatternItem(value.lvalue.pattern)) {
41921+
const place = patternItem.kind === 'Identifier' ? patternItem : patternItem.place;
41922+
if (isPrimitiveType(place.identifier)) {
4188441923
effects.push({
4188541924
kind: 'Create',
41886-
into: patternLValue,
41925+
into: place,
4188741926
value: ValueKind.Primitive,
4188841927
reason: ValueReason.Other,
4188941928
});
4189041929
}
41891-
else {
41930+
else if (patternItem.kind === 'Identifier') {
4189241931
effects.push({
4189341932
kind: 'CreateFrom',
4189441933
from: value.value,
41895-
into: patternLValue,
41934+
into: place,
41935+
});
41936+
}
41937+
else {
41938+
effects.push({
41939+
kind: 'Create',
41940+
into: place,
41941+
reason: ValueReason.Other,
41942+
value: ValueKind.Mutable,
41943+
});
41944+
effects.push({
41945+
kind: 'Capture',
41946+
from: value.value,
41947+
into: place,
4189641948
});
4189741949
}
4189841950
}
@@ -46561,6 +46613,12 @@ function* generateInstructionTypes(env, names, instr) {
4656146613
},
4656246614
});
4656346615
}
46616+
else if (item.kind === 'Spread') {
46617+
yield equation(item.place.identifier.type, {
46618+
kind: 'Object',
46619+
shapeId: BuiltInArrayId,
46620+
});
46621+
}
4656446622
else {
4656546623
break;
4656646624
}

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4f34cc4a2e1198493375867d1876509ae9771aee
1+
448f781a52d62042341d2411d1352d705ce2cbfe
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4f34cc4a2e1198493375867d1876509ae9771aee
1+
448f781a52d62042341d2411d1352d705ce2cbfe

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1434,7 +1434,7 @@ __DEV__ &&
14341434
exports.useTransition = function () {
14351435
return resolveDispatcher().useTransition();
14361436
};
1437-
exports.version = "19.2.0-www-classic-4f34cc4a-20250724";
1437+
exports.version = "19.2.0-www-classic-448f781a-20250724";
14381438
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
14391439
"function" ===
14401440
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
@@ -1434,7 +1434,7 @@ __DEV__ &&
14341434
exports.useTransition = function () {
14351435
return resolveDispatcher().useTransition();
14361436
};
1437-
exports.version = "19.2.0-www-modern-4f34cc4a-20250724";
1437+
exports.version = "19.2.0-www-modern-448f781a-20250724";
14381438
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
14391439
"function" ===
14401440
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
@@ -610,4 +610,4 @@ exports.useSyncExternalStore = function (
610610
exports.useTransition = function () {
611611
return ReactSharedInternals.H.useTransition();
612612
};
613-
exports.version = "19.2.0-www-classic-4f34cc4a-20250724";
613+
exports.version = "19.2.0-www-classic-448f781a-20250724";

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,4 +610,4 @@ exports.useSyncExternalStore = function (
610610
exports.useTransition = function () {
611611
return ReactSharedInternals.H.useTransition();
612612
};
613-
exports.version = "19.2.0-www-modern-4f34cc4a-20250724";
613+
exports.version = "19.2.0-www-modern-448f781a-20250724";

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ exports.useSyncExternalStore = function (
614614
exports.useTransition = function () {
615615
return ReactSharedInternals.H.useTransition();
616616
};
617-
exports.version = "19.2.0-www-classic-4f34cc4a-20250724";
617+
exports.version = "19.2.0-www-classic-448f781a-20250724";
618618
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
619619
"function" ===
620620
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
@@ -614,7 +614,7 @@ exports.useSyncExternalStore = function (
614614
exports.useTransition = function () {
615615
return ReactSharedInternals.H.useTransition();
616616
};
617-
exports.version = "19.2.0-www-modern-4f34cc4a-20250724";
617+
exports.version = "19.2.0-www-modern-448f781a-20250724";
618618
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
619619
"function" ===
620620
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
@@ -19299,10 +19299,10 @@ __DEV__ &&
1929919299
(function () {
1930019300
var internals = {
1930119301
bundleType: 1,
19302-
version: "19.2.0-www-classic-4f34cc4a-20250724",
19302+
version: "19.2.0-www-classic-448f781a-20250724",
1930319303
rendererPackageName: "react-art",
1930419304
currentDispatcherRef: ReactSharedInternals,
19305-
reconcilerVersion: "19.2.0-www-classic-4f34cc4a-20250724"
19305+
reconcilerVersion: "19.2.0-www-classic-448f781a-20250724"
1930619306
};
1930719307
internals.overrideHookState = overrideHookState;
1930819308
internals.overrideHookStateDeletePath = overrideHookStateDeletePath;
@@ -19336,7 +19336,7 @@ __DEV__ &&
1933619336
exports.Shape = Shape;
1933719337
exports.Surface = Surface;
1933819338
exports.Text = Text;
19339-
exports.version = "19.2.0-www-classic-4f34cc4a-20250724";
19339+
exports.version = "19.2.0-www-classic-448f781a-20250724";
1934019340
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
1934119341
"function" ===
1934219342
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

0 commit comments

Comments
 (0)