Repro of for loop with context variable iterator variable

`let` bindings of context variables are lowered to a DeclareContext + 
StoreContext, which breaks codegen for `for` loops which expect that all 
statements of the init block will lower to variable declarations. The two 
instructions produce a variable declaration and a reassignment.
This commit is contained in:
Joe Savona
2024-03-22 09:15:29 -07:00
parent 7dc08d79be
commit bc516409a6
2 changed files with 45 additions and 0 deletions
@@ -0,0 +1,35 @@
## Input
```javascript
function Component() {
const data = useData();
const items = [];
// NOTE: `i` is a context variable because it's reassigned and also referenced
// within a closure, the `onClick` handler of each item
for (let i = MIN; i <= MAX; i += INCREMENT) {
items.push(<Stringify key={i} onClick={() => data.set(i)} />);
}
return items;
}
```
## Error
```
4 | // NOTE: `i` is a context variable because it's reassigned and also referenced
5 | // within a closure, the `onClick` handler of each item
> 6 | for (let i = MIN; i <= MAX; i += INCREMENT) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 7 | items.push(<Stringify key={i} onClick={() => data.set(i)} />);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 8 | }
| ^^^^ [ReactForget] Invariant: Expected a variable declaration (6:8)
9 | return items;
10 | }
11 |
```
@@ -0,0 +1,10 @@
function Component() {
const data = useData();
const items = [];
// NOTE: `i` is a context variable because it's reassigned and also referenced
// within a closure, the `onClick` handler of each item
for (let i = MIN; i <= MAX; i += INCREMENT) {
items.push(<Stringify key={i} onClick={() => data.set(i)} />);
}
return items;
}