dillon1000/react

Commit

[compiler] Fix for edge cases of mutation of potentially frozen values (#33984)

Fixes two related cases of mutation of potentially frozen values.

The first is method calls on frozen values. Previously, we modeled
unknown function calls as potentially aliasing their receiver+args into
the return value. If the receiver or argument were known to be frozen,
then we would downgrade the `Alias` effect into an `ImmutableCapture`.
However, within a function expression it's possible to call a function
using a frozen value as an argument (that gets `Alias`-ed into the
return) but where we don't have the context locally to know that the
value is frozen.

This results in cases like this:

```js
const frozen = useContext(...);
useEffect(() => {
  frozen.method().property = true;
  ^^^^^^^^^^^^^^^^^^^^^^^^ cannot mutate frozen value
}, [...]);
```

Within the function we would infer:

```
t0 = MethodCall ...
  Create t0 = mutable
  Alias t0 <- frozen
t1 = PropertyStore ...
  Mutate t0
```

And then transitively infer the function expression as having a `Mutate
'frozen'` effect, which when evaluated against the outer context
(`frozen` is frozen) is an error.

The fix is to model unknown function calls as _maybe_ aliasing their
receiver/args in the return, and then considering mutations of a
maybe-aliased value to only be a conditional mutation of the source:


```
t0 = MethodCall ...
  Create t0 = mutable
  MaybeAlias t0 <- frozen // maybe alias now
t1 = PropertyStore ...
  Mutate t0
```

Then, the `Mutate t0` turns into a `MutateConditional 'frozen'`, which
just gets ignored when we process the outer context.

The second, related fix is for known mutation of phis that may be a
frozen value. The previous inference model correctly recorded these as
errors, the new model does not. We now correctly report a validation
error for this case in the new model.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33984).
* #33993
* #33991
* __->__ #33984
Browse files
Changed paths17 files
First-parent comparison
M compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts ModifiedM compiler/packages/babel-plugin-react-compiler/src/Inference/AliasingEffects.ts ModifiedM compiler/packages/babel-plugin-react-compiler/src/Inference/AnalyseFunctions.ts ModifiedM compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingEffects.ts ModifiedM compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingRanges.ts ModifiedM compiler/packages/babel-plugin-react-compiler/src/Inference/MUTABILITY_ALIASING_MODEL.md ModifiedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-mutate-phi-which-could-be-frozen.expect.md AddedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-mutate-phi-which-could-be-frozen.js AddedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-for-loop-with-context-variable-iterator.expect.md AddedR compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-loop-with-context-variable-iterator.js →compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-for-loop-with-context-variable-iterator.js RenamedD compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/for-loop-with-context-variable-iterator.expect.md DeletedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-function-call-with-frozen-argument-in-function-expression.expect.md AddedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-function-call-with-frozen-argument-in-function-expression.js AddedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-method-call-on-frozen-value-in-function-expression.expect.md AddedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-method-call-on-frozen-value-in-function-expression.js AddedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-method-call-on-frozen-value-is-allowed.expect.md AddedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-mutate-result-of-method-call-on-frozen-value-is-allowed.js Added
Patch

Files changed

Rendering syntax-highlighted changes…