Repro for undefined "hoisted" variable from type alias

We inadvertently think the type annotation on the function expression param is 
an identifier and create a LoadLocal for it, which fails. This happens to trip 
up on the InferReferenceEffects initialization check, which we had assumed would 
only fire for invalid hoisting cases (hence the specific error message).
This commit is contained in:
Joe Savona
2024-03-21 14:11:04 -07:00
parent 241b35463c
commit 4bc676d3db
8 changed files with 199 additions and 0 deletions
@@ -0,0 +1,30 @@
## Input
```javascript
// @flow @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
type Bar = string;
function TypeAliasUsedAsAnnotation() {
type Foo = Bar;
const fun = (f: Foo) => {
console.log(f);
};
fun("hello, world");
}
```
## Error
```
3 | function TypeAliasUsedAsAnnotation() {
4 | type Foo = Bar;
> 5 | const fun = (f: Foo) => {
| ^^^ [ReactForget] Invariant: [hoisting] Expected value for identifier to be initialized. Foo$0 (5:5)
6 | console.log(f);
7 | };
8 | fun("hello, world");
```
@@ -0,0 +1,9 @@
// @flow @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
type Bar = string;
function TypeAliasUsedAsAnnotation() {
type Foo = Bar;
const fun = (f: Foo) => {
console.log(f);
};
fun("hello, world");
}
@@ -0,0 +1,31 @@
## Input
```javascript
// @flow @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
type Bar = string;
function TypeAliasUsedAsAnnotation() {
type Foo = Bar;
const fun = (f) => {
let g: Foo = f;
console.log(g);
};
fun("hello, world");
}
```
## Error
```
4 | type Foo = Bar;
5 | const fun = (f) => {
> 6 | let g: Foo = f;
| ^^^ [ReactForget] Invariant: [hoisting] Expected value for identifier to be initialized. Foo$0 (6:6)
7 | console.log(g);
8 | };
9 | fun("hello, world");
```
@@ -0,0 +1,10 @@
// @flow @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
type Bar = string;
function TypeAliasUsedAsAnnotation() {
type Foo = Bar;
const fun = (f) => {
let g: Foo = f;
console.log(g);
};
fun("hello, world");
}
@@ -0,0 +1,44 @@
## Input
```javascript
// @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
type Bar = string;
function TypeAliasUsedAsParamAnnotation() {
type Foo = Bar;
const fun = (f: Foo) => {
console.log(f);
};
fun("hello, world");
}
export const FIXTURE_ENTRYPOINT = {
fn: TypeAliasUsedAsParamAnnotation,
params: [],
};
```
## Code
```javascript
// @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
type Bar = string;
function TypeAliasUsedAsParamAnnotation() {
const fun = (f) => {
console.log(f);
};
fun("hello, world");
}
export const FIXTURE_ENTRYPOINT = {
fn: TypeAliasUsedAsParamAnnotation,
params: [],
};
```
### Eval output
(kind: ok)
logs: ['hello, world']
@@ -0,0 +1,14 @@
// @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
type Bar = string;
function TypeAliasUsedAsParamAnnotation() {
type Foo = Bar;
const fun = (f: Foo) => {
console.log(f);
};
fun("hello, world");
}
export const FIXTURE_ENTRYPOINT = {
fn: TypeAliasUsedAsParamAnnotation,
params: [],
};
@@ -0,0 +1,46 @@
## Input
```javascript
// @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
type Bar = string;
function TypeAliasUsedAsVariableAnnotation() {
type Foo = Bar;
const fun = (f) => {
let g: Foo = f;
console.log(g);
};
fun("hello, world");
}
export const FIXTURE_ENTRYPOINT = {
fn: TypeAliasUsedAsVariableAnnotation,
params: [],
};
```
## Code
```javascript
// @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
type Bar = string;
function TypeAliasUsedAsVariableAnnotation() {
const fun = (f) => {
const g = f;
console.log(g);
};
fun("hello, world");
}
export const FIXTURE_ENTRYPOINT = {
fn: TypeAliasUsedAsVariableAnnotation,
params: [],
};
```
### Eval output
(kind: ok)
logs: ['hello, world']
@@ -0,0 +1,15 @@
// @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
type Bar = string;
function TypeAliasUsedAsVariableAnnotation() {
type Foo = Bar;
const fun = (f) => {
let g: Foo = f;
console.log(g);
};
fun("hello, world");
}
export const FIXTURE_ENTRYPOINT = {
fn: TypeAliasUsedAsVariableAnnotation,
params: [],
};