mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[hir] Use a stable identity for undefined value
InferReferenceEffects uses object identity to merge states, which breaks when we create a new object to model `undefined`. Two value objects representing `undefined` are not equal due to referential equality. Instead, let's use a singleton to represent `undefined` value.
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
BlockId,
|
||||
CallExpression,
|
||||
Effect,
|
||||
GeneratedSource,
|
||||
HIRFunction,
|
||||
IdentifierId,
|
||||
InstructionKind,
|
||||
@@ -39,6 +40,12 @@ import {
|
||||
} from "../HIR/visitors";
|
||||
import { assertExhaustive } from "../Utils/utils";
|
||||
|
||||
const UndefinedValue: InstructionValue = {
|
||||
kind: "Primitive",
|
||||
loc: GeneratedSource,
|
||||
value: undefined,
|
||||
};
|
||||
|
||||
/**
|
||||
* For every usage of a value in the given function, infers the effect or action
|
||||
* taken at that reference. Each reference is inferred as exactly one of:
|
||||
@@ -933,11 +940,7 @@ function inferBlock(
|
||||
continue;
|
||||
}
|
||||
case "DeclareLocal": {
|
||||
const value: InstructionValue = {
|
||||
kind: "Primitive",
|
||||
loc: instrValue.loc,
|
||||
value: undefined,
|
||||
};
|
||||
const value = UndefinedValue;
|
||||
state.initialize(
|
||||
value,
|
||||
// Catch params may be aliased to mutable values
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function useFoo() {
|
||||
for (let i = 0; i <= 5; i++) {
|
||||
let color;
|
||||
if (isSelected) {
|
||||
color = isCurrent ? "#FFCC22" : "#FF5050";
|
||||
} else {
|
||||
color = isCurrent ? "#CCFF03" : "#CCCCCC";
|
||||
}
|
||||
console.log(color);
|
||||
}
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
params: [],
|
||||
fn: useFoo,
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function useFoo() {
|
||||
for (let i = 0; i <= 5; i++) {
|
||||
let color = undefined;
|
||||
if (isSelected) {
|
||||
color = isCurrent ? "#FFCC22" : "#FF5050";
|
||||
} else {
|
||||
color = isCurrent ? "#CCFF03" : "#CCCCCC";
|
||||
}
|
||||
|
||||
console.log(color);
|
||||
}
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
params: [],
|
||||
fn: useFoo,
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
function useFoo() {
|
||||
for (let i = 0; i <= 5; i++) {
|
||||
let color;
|
||||
if (isSelected) {
|
||||
color = isCurrent ? "#FFCC22" : "#FF5050";
|
||||
} else {
|
||||
color = isCurrent ? "#CCFF03" : "#CCCCCC";
|
||||
}
|
||||
console.log(color);
|
||||
}
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
params: [],
|
||||
fn: useFoo,
|
||||
};
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
function useFoo() {
|
||||
while (1) {
|
||||
let foo;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
function useFoo() {
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
function useFoo() {
|
||||
while (1) {
|
||||
let foo;
|
||||
}
|
||||
}
|
||||
@@ -461,6 +461,7 @@ const skipFilter = new Set([
|
||||
"fbtparam-with-jsx-fragment-value",
|
||||
"fbt-preserve-jsxtext",
|
||||
"useContext-mutable-value",
|
||||
"loop-unused-let",
|
||||
]);
|
||||
|
||||
export default skipFilter;
|
||||
|
||||
Reference in New Issue
Block a user