Skip to content

break label out of a switch in an async generator throws TypeError reading 'done' #9199

Description

@proggeramlug

A break label targeting a labeled for…of from inside a switch, in an async generator, throws instead of breaking.

async function* gen(xs: number[]) {
  loop: for (const x of xs) {
    switch (x) { case 1: yield "y1"; break; case 2: break loop; default: yield "d" + x; }
  }
}
(async () => { const acc: string[] = []; for await (const v of gen([1,3,2,4])) acc.push(v); console.log(acc.join(",")); })();
result
node 26.5.1 y1,d3
perry Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'done')

The done read failing points at the async-iterator protocol: the labeled break appears to leave the generator state machine without producing a well-formed iterator result, so for await reads .done off undefined. The plain break in case 1 is fine — it is the labeled one that targets the enclosing for…of that fails.

Confirmed pre-existing on main by reverting crates/perry-transform/src/generator/linearize.rs to main and rebuilding: identical error, exit 1 both ways. Found while auditing #9189; that PR fixes the labeled-switch case (#9186) and this async-generator shape is not in its scope.

Sibling: the async function form with a labeled for…of hangs rather than throwing, filed separately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed defect or regression

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions