mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Fix invariant on mutable context values
ghstack-source-id: cb105318bf66d876a546b1c52e28286839d30032 Pull Request resolved: https://github.com/facebook/react-forget/pull/2904
This commit is contained in:
@@ -1640,17 +1640,6 @@ function inferBlock(
|
||||
const lvalue = instr.lvalue;
|
||||
lvalue.effect = Effect.ConditionallyMutate;
|
||||
const valueKind = state.kind(instrValue.place);
|
||||
CompilerError.invariant(
|
||||
valueKind.kind === ValueKind.Mutable ||
|
||||
valueKind.kind === ValueKind.Context,
|
||||
{
|
||||
reason:
|
||||
"[InferReferenceEffects] Context variables are always mutable.",
|
||||
description: null,
|
||||
loc: instrValue.loc,
|
||||
suggestions: null,
|
||||
}
|
||||
);
|
||||
state.initialize(instrValue, valueKind);
|
||||
state.define(lvalue, instrValue);
|
||||
continue;
|
||||
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
// @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
|
||||
function Component(props) {
|
||||
const [_state, setState] = useState();
|
||||
const a = () => {
|
||||
return b();
|
||||
};
|
||||
const b = () => {
|
||||
return (
|
||||
<>
|
||||
<div onClick={() => onClick(true)} />
|
||||
<div onClick={() => onClick(false)} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
const onClick = (value) => {
|
||||
setState(value);
|
||||
};
|
||||
|
||||
return <div>{a()}</div>;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPONT = {
|
||||
fn: Component,
|
||||
props: [{}],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Error
|
||||
|
||||
```
|
||||
9 | <>
|
||||
10 | <div onClick={() => onClick(true)} />
|
||||
> 11 | <div onClick={() => onClick(false)} />
|
||||
| ^^^^^^^ Invariant: [InferReferenceEffects] Context variables are always mutable. (11:11)
|
||||
12 | </>
|
||||
13 | );
|
||||
14 | };
|
||||
```
|
||||
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
|
||||
## Input
|
||||
|
||||
```javascript
|
||||
import { useState } from "react";
|
||||
|
||||
function Component(props) {
|
||||
const [_state, setState] = useState();
|
||||
const a = () => {
|
||||
return b();
|
||||
};
|
||||
const b = () => {
|
||||
return (
|
||||
<>
|
||||
<div onClick={() => onClick(true)}>a</div>
|
||||
<div onClick={() => onClick(false)}>b</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
const onClick = (value) => {
|
||||
setState(value);
|
||||
};
|
||||
|
||||
return <div>{a()}</div>;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{}],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
## Code
|
||||
|
||||
```javascript
|
||||
import { useState, unstable_useMemoCache as useMemoCache } from "react";
|
||||
|
||||
function Component(props) {
|
||||
const $ = useMemoCache(1);
|
||||
const [_state, setState] = useState();
|
||||
let t0;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
const a = () => b();
|
||||
|
||||
const b = () => (
|
||||
<>
|
||||
<div onClick={() => onClick(true)}>a</div>
|
||||
<div onClick={() => onClick(false)}>b</div>
|
||||
</>
|
||||
);
|
||||
|
||||
const onClick = (value) => {
|
||||
setState(value);
|
||||
};
|
||||
|
||||
t0 = <div>{a()}</div>;
|
||||
$[0] = t0;
|
||||
} else {
|
||||
t0 = $[0];
|
||||
}
|
||||
return t0;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
params: [{}],
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
### Eval output
|
||||
(kind: ok) <div><div>a</div><div>b</div></div>
|
||||
+6
-5
@@ -1,4 +1,5 @@
|
||||
// @enableAssumeHooksFollowRulesOfReact @enableTransitivelyFreezeFunctionExpressions
|
||||
import { useState } from "react";
|
||||
|
||||
function Component(props) {
|
||||
const [_state, setState] = useState();
|
||||
const a = () => {
|
||||
@@ -7,8 +8,8 @@ function Component(props) {
|
||||
const b = () => {
|
||||
return (
|
||||
<>
|
||||
<div onClick={() => onClick(true)} />
|
||||
<div onClick={() => onClick(false)} />
|
||||
<div onClick={() => onClick(true)}>a</div>
|
||||
<div onClick={() => onClick(false)}>b</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -19,7 +20,7 @@ function Component(props) {
|
||||
return <div>{a()}</div>;
|
||||
}
|
||||
|
||||
export const FIXTURE_ENTRYPONT = {
|
||||
export const FIXTURE_ENTRYPOINT = {
|
||||
fn: Component,
|
||||
props: [{}],
|
||||
params: [{}],
|
||||
};
|
||||
Reference in New Issue
Block a user