Summary
In compiled mode, arrow functions written inside a generator (function*) body are miscompiled. Two symptoms, both pre-existing (reproduce on origin/main / 0952d442), interpreter is correct:
1. Arrow passed as an array-method callback → TypeError: ... callback is not callable
function* g() { yield [1, 2, 3].map(x => x * 2).join(","); }
console.log(g().next().value);
// interp: 2,4,6
// compiled: Unhandled exception. TypeError: Array.prototype.map callback is not callable
// at $Runtime.ArrayMap(...) at <gen>d__0.MoveNext()
2. A closure created and invoked inside a generator body → Non-static method requires a target
function* gen() {
const fns: any[] = [];
for (let k = 0; k < 3; k++) { fns.push(() => k); }
let out = "";
for (let i = 0; i < fns.length; i++) { out += fns[i](); }
yield out;
}
console.log(gen().next().value);
// interp: 012
// compiled: Unhandled exception. System.Reflection.TargetException: Non-static method requires a target.
A non-capturing arrow stored in a local and called directly does work (const f = () => 42; yield f(); yields 42), so the breakage is specific to arrows emitted as callback arguments / capturing closures within the generator MoveNext state machine.
Likely area
GeneratorMoveNextEmitter arrow-function emission (Compilation/GeneratorMoveNextEmitter.*). The $TSFunction wrapping the arrow appears to be produced without a valid target/method binding inside the generator state machine (mirrors the kind of state-machine arrow-emission parity gaps tracked for async emitters).
Notes
Found while adding cross-mode regression tests for #649 (closures capturing a for (let …) loop variable). The per-iteration binding itself is correct in generators; this is an orthogonal generator-body arrow-emission bug. Top-level function* declared in a loop capturing the loop var (the #622 repro) is unaffected because its .map runs at top level, not inside a generator body.
Summary
In compiled mode, arrow functions written inside a generator (
function*) body are miscompiled. Two symptoms, both pre-existing (reproduce onorigin/main/0952d442), interpreter is correct:1. Arrow passed as an array-method callback →
TypeError: ... callback is not callable2. A closure created and invoked inside a generator body →
Non-static method requires a targetA non-capturing arrow stored in a local and called directly does work (
const f = () => 42; yield f();yields 42), so the breakage is specific to arrows emitted as callback arguments / capturing closures within the generatorMoveNextstate machine.Likely area
GeneratorMoveNextEmitterarrow-function emission (Compilation/GeneratorMoveNextEmitter.*). The$TSFunctionwrapping the arrow appears to be produced without a valid target/method binding inside the generator state machine (mirrors the kind of state-machine arrow-emission parity gaps tracked for async emitters).Notes
Found while adding cross-mode regression tests for #649 (closures capturing a
for (let …)loop variable). The per-iteration binding itself is correct in generators; this is an orthogonal generator-body arrow-emission bug. Top-levelfunction*declared in a loop capturing the loop var (the #622 repro) is unaffected because its.mapruns at top level, not inside a generator body.