Skip to content

Class with *[Symbol.iterator]() generator method hangs in for...of (and growing RSS to OOM) #448

Description

@proggeramlug

Summary

A class that implements *[Symbol.iterator]() as a generator method, when iterated via for…of, runs an infinite loop allocating until OOM. Surfaced by test-files/test_gap_symbols.ts — the binary climbs to 5+ GB RSS before being killed.

Minimal repro

class Fibonacci {
  limit: number;
  constructor(limit: number) { this.limit = limit; }

  *[Symbol.iterator](): Generator<number> {
    let a = 0;
    let b = 1;
    let count = 0;
    while (count < this.limit) {
      yield a;
      [a, b] = [b, a + b];
      count++;
    }
  }
}

const fibs: number[] = [];
for (const f of new Fibonacci(7)) {
  fibs.push(f);
}
console.log(fibs.join(","));

Expected (node --experimental-strip-types): 0,1,1,2,3,5,8
Observed: hangs forever, RSS climbs to 5+ GB before kill.

Notes

  • Plain top-level generator functions iterated via for…of work fine — only the class-method form with *[Symbol.iterator]() triggers the loop.
  • Plausibly related to v0.5.503's class-method dispatch work (#446) but verified to also hang on v0.5.498 (git checkout HEAD~5 -- crates/), so this is pre-existing.
  • The full test (test-files/test_gap_symbols.ts) reproduces; lines 1–50 (Symbol creation, Symbol.for, computed property keys) all work — only the Fibonacci block at lines 51–73 hangs.

Why this matters

The class implements iterable via *[Symbol.iterator]() pattern is the canonical way to make user classes work with for…of, spread, destructuring, and Array.from. It's listed in CLAUDE.md as a supported feature.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions