Skip to content

Commit 440d8c2

Browse files
committed
[compiler] Fix bug with reassigning function param in destructuring
Closes #33577, a bug with ExtractScopeDeclarationsFromDestructuring and codegen when a function param is reassigned.
1 parent cee7939 commit 440d8c2

File tree

4 files changed

+83
-5
lines changed

4 files changed

+83
-5
lines changed

compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -349,11 +349,9 @@ function codegenReactiveFunction(
349349
fn: ReactiveFunction,
350350
): Result<CodegenFunction, CompilerError> {
351351
for (const param of fn.params) {
352-
if (param.kind === 'Identifier') {
353-
cx.temp.set(param.identifier.declarationId, null);
354-
} else {
355-
cx.temp.set(param.place.identifier.declarationId, null);
356-
}
352+
const place = param.kind === 'Identifier' ? param : param.place;
353+
cx.temp.set(place.identifier.declarationId, null);
354+
cx.declare(place.identifier);
357355
}
358356

359357
const params = fn.params.map(param => convertParameter(param));

compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/ExtractScopeDeclarationsFromDestructuring.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ export function extractScopeDeclarationsFromDestructuring(
7979
fn: ReactiveFunction,
8080
): void {
8181
const state = new State(fn.env);
82+
for (const param of fn.params) {
83+
const place = param.kind === 'Identifier' ? param : param.place;
84+
state.declared.add(place.identifier.declarationId);
85+
}
8286
visitReactiveFunction(fn, new Visitor(), state);
8387
}
8488

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
2+
## Input
3+
4+
```javascript
5+
import {Stringify, useIdentity} from 'shared-runtime';
6+
7+
function Component({other, ...props}, ref) {
8+
[props, ref] = useIdentity([props, ref]);
9+
return <Stringify props={props} />;
10+
}
11+
12+
export const FIXTURE_ENTRYPOINT = {
13+
fn: Component,
14+
params: [{a: 0, b: 'hello', children: <div>Hello</div>}],
15+
};
16+
17+
```
18+
19+
## Code
20+
21+
```javascript
22+
import { c as _c } from "react/compiler-runtime";
23+
import { Stringify, useIdentity } from "shared-runtime";
24+
25+
function Component(t0, ref) {
26+
const $ = _c(7);
27+
let props;
28+
if ($[0] !== t0) {
29+
let { other, ...t1 } = t0;
30+
props = t1;
31+
$[0] = t0;
32+
$[1] = props;
33+
} else {
34+
props = $[1];
35+
}
36+
let t1;
37+
if ($[2] !== props || $[3] !== ref) {
38+
t1 = [props, ref];
39+
$[2] = props;
40+
$[3] = ref;
41+
$[4] = t1;
42+
} else {
43+
t1 = $[4];
44+
}
45+
[props, ref] = useIdentity(t1);
46+
let t2;
47+
if ($[5] !== props) {
48+
t2 = <Stringify props={props} />;
49+
$[5] = props;
50+
$[6] = t2;
51+
} else {
52+
t2 = $[6];
53+
}
54+
return t2;
55+
}
56+
57+
export const FIXTURE_ENTRYPOINT = {
58+
fn: Component,
59+
params: [{ a: 0, b: "hello", children: <div>Hello</div> }],
60+
};
61+
62+
```
63+
64+
### Eval output
65+
(kind: ok) <div>{"props":{"a":0,"b":"hello","children":{"type":"div","key":null,"props":{"children":"Hello"},"_owner":"[[ cyclic ref *3 ]]","_store":{}}}}</div>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import {Stringify, useIdentity} from 'shared-runtime';
2+
3+
function Component({other, ...props}, ref) {
4+
[props, ref] = useIdentity([props, ref]);
5+
return <Stringify props={props} />;
6+
}
7+
8+
export const FIXTURE_ENTRYPOINT = {
9+
fn: Component,
10+
params: [{a: 0, b: 'hello', children: <div>Hello</div>}],
11+
};

0 commit comments

Comments
 (0)