Skip to content

await in a switch inside a labeled for-of hangs at runtime #9198

Description

@proggeramlug

An await inside a switch nested in a labeled for…of loop compiles, then hangs forever at runtime.

async function f(xs: number[]) {
  const out: string[] = [];
  outer: for (const x of xs) {
    switch (x % 4) {
      case 0: out.push("z" + x); break;
      case 1: await Promise.resolve(); out.push("a" + x); break;
      case 2: if (x > 5) break outer; out.push("b" + x); break;
      default: await Promise.resolve(); if (x > 10) continue outer; out.push("d" + x);
    }
    out.push("|");
  }
  return out.join("");
}
(async () => { console.log(await f([0,1,2,3,4,5,6,7,11,12])); })();
result
node 26.5.1 z0|a1|b2|d3|z4|a5|
perry hangs; killed at 20 s, process in state R at ~14% CPU (spinning, not blocked)

The loop label is doing the work here: the same body without outer: and without break outer/continue outer terminates. Both abrupt completions target the enclosing labeled loop from inside a switch that also contains an await, so the case bodies are split across generator states.

Confirmed pre-existing on main, by rebuilding the compiler with crates/perry-transform/src/generator/linearize.rs reverted to main and re-running: identical hang, exit 124 both ways. Found while auditing #9189, which is adjacent (it routes labeled breaks through yielding switches, #9186) but does not address this — its own case is a labeled switch, not a labeled for…of containing one.

Sibling: the async-generator form fails differently and is 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