dillon1000/react

Commit

[compiler][bugfix] Fix hoisting of let declarations (#32724)

(Found when compiling Meta React code)

Let variable declarations and reassignments are currently rewritten to
`StoreLocal <varName>` instructions, which each translates to a new
`const varName` declaration in codegen.

```js
// Example input
function useHook() {
  const getX = () => x;
  let x = CONSTANT1;
  if (cond) {
    x += CONSTANT2;
  }
  return <Stringify getX={getX} />
}

// Compiled output, prior to this PR
import { c as _c } from "react/compiler-runtime";
function useHook() {
  const $ = _c(1);
  let t0;
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
    const getX = () => x;
    let x = CONSTANT1;
    if (cond) {
      let x = x + CONSTANT2;
      x;
    }

    t0 = <Stringify getX={getX} />;
    $[0] = t0;
  } else {
    t0 = $[0];
  }
  return t0;
}
```

This also manifests as a babel internal error when replacing the
original function declaration with the compiler output. The below
compilation output fails with `Duplicate declaration "x" (This is an
error on an internal node. Probably an internal error.)`.
```js
// example input
let x = CONSTANT1;
if (cond) {
  x += CONSTANT2;
  x = CONSTANT3;
}

// current output
let x = CONSTANT1;
if (playheadDragState) {
  let x = x + CONSTANT2
  x;
  let x = CONSTANT3;
}
```
Browse files
Changed paths13 files
First-parent comparison
M compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/PruneHoistedContexts.ts ModifiedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-invalid-tdz-let.expect.md AddedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-invalid-tdz-let.js AddedM compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-nested-let-declaration-2.expect.md ModifiedM compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-nested-let-declaration.expect.md ModifiedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-reassigned-let-declaration.expect.md AddedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-reassigned-let-declaration.js AddedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-reassigned-twice-let-declaration.expect.md AddedA compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-reassigned-twice-let-declaration.js AddedM compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/hoisting-simple-let-declaration.expect.md ModifiedM compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/mutate-captured-arg-separately.expect.md ModifiedM compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/recursive-function-expression.expect.md ModifiedM compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/recursive-function-expression.js Modified
Patch

Files changed

Rendering syntax-highlighted changes…