mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[compiler] remove invariant to account for backedges (#32417)
Fixes https://github.com/facebook/react/issues/32269, see comments for details. Added test fixture for repro
This commit is contained in:
+7
-11
@@ -1598,18 +1598,14 @@ function inferBlock(
|
||||
break;
|
||||
}
|
||||
case 'LoadLocal': {
|
||||
/**
|
||||
* Due to backedges in the CFG, we may revisit LoadLocal lvalues
|
||||
* multiple times. Unlike StoreLocal which may reassign to existing
|
||||
* identifiers, LoadLocal always evaluates to store a new temporary.
|
||||
* This means that we should always model LoadLocal as a Capture effect
|
||||
* on the rvalue.
|
||||
*/
|
||||
const lvalue = instr.lvalue;
|
||||
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,
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
import {Stringify} from 'shared-runtime';
|
||||
|
||||
function Foo({userIds}) {
|
||||
return (
|
||||
<Stringify
|
||||
fn={() => {
|
||||
const arr = [];
|
||||
|
||||
for (const selectedUser of userIds) {
|
||||
arr.push(selectedUser);
|
||||
}
|
||||
return arr;
|
||||
}}
|
||||
shouldInvokeFns={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [{userIds: [1, 2, 3]}],
|
||||
sequentialRenders: [{userIds: [1, 2, 4]}],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import { Stringify } from "shared-runtime";
|
||||
|
||||
function Foo(t0) {
|
||||
const $ = _c(2);
|
||||
const { userIds } = t0;
|
||||
let t1;
|
||||
if ($[0] !== userIds) {
|
||||
t1 = (
|
||||
<Stringify
|
||||
fn={() => {
|
||||
const arr = [];
|
||||
for (const selectedUser of userIds) {
|
||||
arr.push(selectedUser);
|
||||
}
|
||||
return arr;
|
||||
}}
|
||||
shouldInvokeFns={true}
|
||||
/>
|
||||
);
|
||||
$[0] = userIds;
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
return t1;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [{ userIds: [1, 2, 3] }],
|
||||
sequentialRenders: [{ userIds: [1, 2, 4] }],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
### Eval output
|
||||
(kind: ok) <div>{"fn":{"kind":"Function","result":[1,2,4]},"shouldInvokeFns":true}</div>
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import {Stringify} from 'shared-runtime';
|
||||
|
||||
function Foo({userIds}) {
|
||||
return (
|
||||
<Stringify
|
||||
fn={() => {
|
||||
const arr = [];
|
||||
|
||||
for (const selectedUser of userIds) {
|
||||
arr.push(selectedUser);
|
||||
}
|
||||
return arr;
|
||||
}}
|
||||
shouldInvokeFns={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Foo,
|
||||
params: [{userIds: [1, 2, 3]}],
|
||||
sequentialRenders: [{userIds: [1, 2, 4]}],
|
||||
};
|
||||
Reference in New Issue
Block a user