Skip to content

Commit 6a3d6a4

Browse files
authored
[compiler] Allow type cast expressions with refs (facebook#31871)
We report a false positive for the combination of a ref-accessing function placed inside an array which is they type-cast. Here we teach ref validation about type casts. I also tried other variants like `return ref as const` but those already worked. Closes facebook#31864
1 parent de82912 commit 6a3d6a4

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed

compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccesInRender.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,14 @@ function validateNoRefAccessInRenderImpl(
305305
);
306306
break;
307307
}
308+
case 'TypeCastExpression': {
309+
env.set(
310+
instr.lvalue.identifier.id,
311+
env.get(instr.value.value.identifier.id) ??
312+
refTypeOfType(instr.lvalue),
313+
);
314+
break;
315+
}
308316
case 'LoadContext':
309317
case 'LoadLocal': {
310318
env.set(
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
2+
## Input
3+
4+
```javascript
5+
import {useRef} from 'react';
6+
7+
function useArrayOfRef() {
8+
const ref = useRef(null);
9+
const callback = value => {
10+
ref.current = value;
11+
};
12+
return [callback] as const;
13+
}
14+
15+
export const FIXTURE_ENTRYPOINT = {
16+
fn: () => {
17+
useArrayOfRef();
18+
return 'ok';
19+
},
20+
params: [{}],
21+
};
22+
23+
```
24+
25+
## Code
26+
27+
```javascript
28+
import { c as _c } from "react/compiler-runtime";
29+
import { useRef } from "react";
30+
31+
function useArrayOfRef() {
32+
const $ = _c(1);
33+
const ref = useRef(null);
34+
let t0;
35+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
36+
const callback = (value) => {
37+
ref.current = value;
38+
};
39+
40+
t0 = [callback];
41+
$[0] = t0;
42+
} else {
43+
t0 = $[0];
44+
}
45+
return t0 as const;
46+
}
47+
48+
export const FIXTURE_ENTRYPOINT = {
49+
fn: () => {
50+
useArrayOfRef();
51+
return "ok";
52+
},
53+
54+
params: [{}],
55+
};
56+
57+
```
58+
59+
### Eval output
60+
(kind: ok) "ok"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import {useRef} from 'react';
2+
3+
function useArrayOfRef() {
4+
const ref = useRef(null);
5+
const callback = value => {
6+
ref.current = value;
7+
};
8+
return [callback] as const;
9+
}
10+
11+
export const FIXTURE_ENTRYPOINT = {
12+
fn: () => {
13+
useArrayOfRef();
14+
return 'ok';
15+
},
16+
params: [{}],
17+
};

0 commit comments

Comments
 (0)