Skip to content

Commit

Permalink
[compiler] Allow type cast expressions with refs (facebook#31871)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
josephsavona authored Dec 20, 2024
1 parent de82912 commit 6a3d6a4
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,14 @@ function validateNoRefAccessInRenderImpl(
);
break;
}
case 'TypeCastExpression': {
env.set(
instr.lvalue.identifier.id,
env.get(instr.value.value.identifier.id) ??
refTypeOfType(instr.lvalue),
);
break;
}
case 'LoadContext':
case 'LoadLocal': {
env.set(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

## Input

```javascript
import {useRef} from 'react';

function useArrayOfRef() {
const ref = useRef(null);
const callback = value => {
ref.current = value;
};
return [callback] as const;
}

export const FIXTURE_ENTRYPOINT = {
fn: () => {
useArrayOfRef();
return 'ok';
},
params: [{}],
};

```

## Code

```javascript
import { c as _c } from "react/compiler-runtime";
import { useRef } from "react";

function useArrayOfRef() {
const $ = _c(1);
const ref = useRef(null);
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
const callback = (value) => {
ref.current = value;
};

t0 = [callback];
$[0] = t0;
} else {
t0 = $[0];
}
return t0 as const;
}

export const FIXTURE_ENTRYPOINT = {
fn: () => {
useArrayOfRef();
return "ok";
},

params: [{}],
};

```
### Eval output
(kind: ok) "ok"
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {useRef} from 'react';

function useArrayOfRef() {
const ref = useRef(null);
const callback = value => {
ref.current = value;
};
return [callback] as const;
}

export const FIXTURE_ENTRYPOINT = {
fn: () => {
useArrayOfRef();
return 'ok';
},
params: [{}],
};

0 comments on commit 6a3d6a4

Please sign in to comment.