Skip to content

[Bug]: Array destructuring rest pattern not included in binding_identifiers, causing ReferenceError in scope-hoisted output #9105

@dbartholomae

Description

@dbartholomae

Reproduction link or steps

// lib.js
export const stages = { a: "1", b: "2", c: "3" };

// main.js
import { stages } from "./lib";
const values = Object.values(stages);
const [first, ...rest] = values;
if (!first) throw new Error("empty");
export const all = [first, ...rest];

REPL

Bundle with scope hoisting enabled (e.g. via Vite 8's Storybook build). The generated output hoists first but not rest, causing a ReferenceError at runtime.

What is expected?

The rest variable from const [first, ...rest] = values should be declared in the hoisted var statement, just like first is.

What is actually happening?

Generated output (simplified):

var first, all, init_Main = __esmMin((() => {
  //  ↑ `rest` is missing from the var declaration
  [first, ...rest] = Object.values(stages);
  // ReferenceError: rest is not defined
}));

Root cause

PR #3374 (fixing #3331) added rest element handling to ObjectPattern in binding_identifiers() but did not apply the same fix to ArrayPattern:

https://github.com/rolldown/rolldown/blob/v1.0.0-rc.15/crates/rolldown_ecmascript_utils/src/extensions/ast_ext/binding_pattern_ext.rs#L33-L35

BindingPattern::ArrayPattern(arr_pat) => {
  // ← No arr_pat.rest handling
  stack.extend(arr_pat.elements.iter().flatten().rev());
}
BindingPattern::ObjectPattern(obj_pat) => {
  if let Some(obj_pat) = &obj_pat.rest {
    stack.push(&obj_pat.argument);  // ← rest IS handled
  }
  stack.extend(obj_pat.properties.iter().map(|prop| &prop.value).rev());
}

Suggested fix

Add the same rest handling to the ArrayPattern arm:

BindingPattern::ArrayPattern(arr_pat) => {
  if let Some(rest) = &arr_pat.rest {
    stack.push(&rest.argument);
  }
  stack.extend(arr_pat.elements.iter().flatten().rev());
}

I've verified locally that building Rolldown from source with this patch fixes the issue — rest then appears in the hoisted var declaration and the bundle runs without errors.

System Info

rolldown: 1.0.0-rc.15 (via Vite 8.0.8)
Node.js: v22.x
OS: macOS (darwin-arm64)

Any additional comments?

Encountered via a Chromatic/Storybook build where const [first, ...rest] = array at module top level caused ReferenceError: rest is not defined in the scope-hoisted output.

Metadata

Metadata

Type

Priority

None yet

Effort

None yet

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions