[compiler] Fix merging of queued states in InferReferenceEffects

Fixes a bug found by mofeiZ in #29878. When we merge queued states, if the new state does not introduce changes relative to the queued state we should use the queued state, not the new state.

ghstack-source-id: c59f69de15
Pull Request resolved: https://github.com/facebook/react/pull/29879
This commit is contained in:
Joe Savona
2024-06-12 14:49:13 -07:00
parent 195d5bb99e
commit 55fdcf87bd
3 changed files with 82 additions and 2 deletions

View File

@@ -201,7 +201,7 @@ export default function inferReferenceEffects(
let queuedState = queuedStates.get(blockId);
if (queuedState != null) {
// merge the queued states for this block
state = queuedState.merge(state) ?? state;
state = queuedState.merge(state) ?? queuedState;
queuedStates.set(blockId, state);
} else {
/*
@@ -765,7 +765,7 @@ class InferenceState {
result.values[id] = { kind, value: printMixedHIR(value) };
}
for (const [variable, values] of this.#variables) {
result.variables[variable] = [...values].map(identify);
result.variables[`$${variable}`] = [...values].map(identify);
}
return result;
}

View File

@@ -0,0 +1,61 @@
## Input
```javascript
import { arrayPush } from "shared-runtime";
function Foo(cond) {
let x = null;
if (cond) {
x = [];
} else {
}
// Here, x = phi(x$null, x$[]) should receive a ValueKind of Mutable
arrayPush(x, 2);
return x;
}
export const FIXTURE_ENTRYPOINT = {
fn: Foo,
params: [{ cond: true }],
sequentialRenders: [{ cond: true }, { cond: true }],
};
```
## Code
```javascript
import { c as _c } from "react/compiler-runtime";
import { arrayPush } from "shared-runtime";
function Foo(cond) {
const $ = _c(2);
let x;
if ($[0] !== cond) {
x = null;
if (cond) {
x = [];
}
arrayPush(x, 2);
$[0] = cond;
$[1] = x;
} else {
x = $[1];
}
return x;
}
export const FIXTURE_ENTRYPOINT = {
fn: Foo,
params: [{ cond: true }],
sequentialRenders: [{ cond: true }, { cond: true }],
};
```
### Eval output
(kind: ok) [2]
[2]

View File

@@ -0,0 +1,19 @@
import { arrayPush } from "shared-runtime";
function Foo(cond) {
let x = null;
if (cond) {
x = [];
} else {
}
// Here, x = phi(x$null, x$[]) should receive a ValueKind of Mutable
arrayPush(x, 2);
return x;
}
export const FIXTURE_ENTRYPOINT = {
fn: Foo,
params: [{ cond: true }],
sequentialRenders: [{ cond: true }, { cond: true }],
};