Skip to content

Commit a8f5c4e

Browse files
committed
[compiler] patch: retain UpdateExpression for globals
ghstack-source-id: aff6606f85698ccda13d1deffb6faa9d91f9821a Pull Request resolved: #30471
1 parent 2a9274a commit a8f5c4e

7 files changed

+67
-56
lines changed

compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts

+32-21
Original file line numberDiff line numberDiff line change
@@ -1934,7 +1934,6 @@ function lowerExpression(
19341934
switch (leftNode.type) {
19351935
case 'Identifier': {
19361936
const leftExpr = left as NodePath<t.Identifier>;
1937-
const identifier = lowerIdentifier(builder, leftExpr);
19381937
const leftPlace = lowerExpressionToTemporary(builder, leftExpr);
19391938
const right = lowerExpressionToTemporary(builder, expr.get('right'));
19401939
const binaryPlace = lowerValueToTemporary(builder, {
@@ -1944,30 +1943,42 @@ function lowerExpression(
19441943
right,
19451944
loc: exprLoc,
19461945
});
1947-
const kind = getStoreKind(builder, leftExpr);
1948-
if (kind === 'StoreLocal') {
1949-
lowerValueToTemporary(builder, {
1950-
kind: 'StoreLocal',
1951-
lvalue: {
1952-
place: {...identifier},
1953-
kind: InstructionKind.Reassign,
1954-
},
1955-
value: {...binaryPlace},
1956-
type: null,
1957-
loc: exprLoc,
1958-
});
1959-
return {kind: 'LoadLocal', place: identifier, loc: exprLoc};
1946+
const binding = builder.resolveIdentifier(leftExpr);
1947+
if (binding.kind === 'Identifier') {
1948+
const identifier = lowerIdentifier(builder, leftExpr);
1949+
const kind = getStoreKind(builder, leftExpr);
1950+
if (kind === 'StoreLocal') {
1951+
lowerValueToTemporary(builder, {
1952+
kind: 'StoreLocal',
1953+
lvalue: {
1954+
place: {...identifier},
1955+
kind: InstructionKind.Reassign,
1956+
},
1957+
value: {...binaryPlace},
1958+
type: null,
1959+
loc: exprLoc,
1960+
});
1961+
return {kind: 'LoadLocal', place: identifier, loc: exprLoc};
1962+
} else {
1963+
lowerValueToTemporary(builder, {
1964+
kind: 'StoreContext',
1965+
lvalue: {
1966+
place: {...identifier},
1967+
kind: InstructionKind.Reassign,
1968+
},
1969+
value: {...binaryPlace},
1970+
loc: exprLoc,
1971+
});
1972+
return {kind: 'LoadContext', place: identifier, loc: exprLoc};
1973+
}
19601974
} else {
1961-
lowerValueToTemporary(builder, {
1962-
kind: 'StoreContext',
1963-
lvalue: {
1964-
place: {...identifier},
1965-
kind: InstructionKind.Reassign,
1966-
},
1975+
const temporary = lowerValueToTemporary(builder, {
1976+
kind: 'StoreGlobal',
1977+
name: leftExpr.node.name,
19671978
value: {...binaryPlace},
19681979
loc: exprLoc,
19691980
});
1970-
return {kind: 'LoadContext', place: identifier, loc: exprLoc};
1981+
return {kind: 'LoadLocal', place: temporary, loc: temporary.loc};
19711982
}
19721983
}
19731984
case 'MemberExpression': {

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-invalid-update-global-should-bailout.expect.md

-32
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
## Input
3+
4+
```javascript
5+
let renderCount = 0;
6+
function useFoo() {
7+
renderCount += 1;
8+
return renderCount;
9+
}
10+
11+
export const FIXTURE_ENTRYPOINT = {
12+
fn: useFoo,
13+
params: [],
14+
};
15+
16+
```
17+
18+
19+
## Error
20+
21+
```
22+
1 | let renderCount = 0;
23+
2 | function useFoo() {
24+
> 3 | renderCount += 1;
25+
| ^^^^^^^^^^^^^^^^ InvalidReact: Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render) (3:3)
26+
4 | return renderCount;
27+
5 | }
28+
6 |
29+
```
30+
31+
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ function Foo() {
4040
return t0;
4141
}
4242
function _temp() {
43+
renderCount = renderCount + 1;
4344
return renderCount;
4445
}
4546

@@ -49,4 +50,6 @@ export const FIXTURE_ENTRYPOINT = {
4950
};
5051

5152
```
52-
53+
54+
### Eval output
55+
(kind: ok) <div>{"cb":{"kind":"Function","result":1},"shouldInvokeFns":true}</div>

compiler/packages/snap/src/SproutTodoFilter.ts

-2
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,6 @@ const skipFilter = new Set([
484484
'rules-of-hooks/rules-of-hooks-69521d94fa03',
485485

486486
// bugs
487-
'bug-invalid-update-global-should-bailout',
488-
'bug-update-global-in-callback',
489487
'bug-invalid-hoisting-functionexpr',
490488
'original-reactive-scopes-fork/bug-nonmutating-capture-in-unsplittable-memo-block',
491489
'original-reactive-scopes-fork/bug-hoisted-declaration-with-scope',

0 commit comments

Comments
 (0)