Skip to content

Commit

Permalink
[compiler] remove invariant to account for backedges (#32417)
Browse files Browse the repository at this point in the history
Fixes #32269, see comments for
details.

Added test fixture for repro
  • Loading branch information
mofeiZ authored Feb 19, 2025
1 parent a84862d commit fcb4e0f
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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]}],
};

0 comments on commit fcb4e0f

Please sign in to comment.