Async-generator yield* delegation drops .return() / .throw() abrupt resume
Split out of #5703 after a worker confirmed its residual was mis-scoped: ~10 of the 11 cases on #5703 are not the #5662 class-expression regression. They are an async-generator delegation gap that reproduces identically for class statements, plain async function*, and instance methods — the class-expression form is irrelevant. (The language/statements/class copies merely bucket as diff instead of runtime-fail because an async-test failure still exits 0.)
Symptom
A yield*-delegating async generator resumed via .return(v) or .throw(e) never forwards the completion to the delegated iterator's return/throw methods, and can't continue after the resume. Test262 signatures: Cannot read properties of undefined, throw-arg-1, reject reason, Promise incorrectly … in language/expressions/class/async-gen-method-static/yield-star-* (and the statements/class + non-class equivalents).
Root (from the #5703 worker's investigation)
Perry routes .throw()→catch and .return()→finally into linearized generator states, but for async generators crates/perry-transform/.../generator/lower/abrupt.rs::build_async_catch_route_body hard-codes a {value: undefined, done: false} return and has no continuation loop (throw_continuation = None, deliberately). So the delegated iterator's throw/return never fires in spec order, the post-resume yielded value is dropped, and the delegation loop cannot resume. A try/catch desugar prototype made the inner iterator's methods fire in correct order but still dropped the resumed value — confirming the blocker is the async-generator abrupt-resume continuation machinery, a substantial standalone feature.
Scope / relationship
Measure
scripts/test262_subset.py --root vendor/test262 --dir language/expressions/class/async-gen-method-static language/statements/class/async-gen-method-static --jobs 8
Async-generator
yield*delegation drops.return()/.throw()abrupt resumeSplit out of #5703 after a worker confirmed its residual was mis-scoped: ~10 of the 11 cases on #5703 are not the #5662 class-expression regression. They are an async-generator delegation gap that reproduces identically for class statements, plain
async function*, and instance methods — the class-expression form is irrelevant. (Thelanguage/statements/classcopies merely bucket asdiffinstead ofruntime-failbecause an async-test failure still exits 0.)Symptom
A
yield*-delegating async generator resumed via.return(v)or.throw(e)never forwards the completion to the delegated iterator'sreturn/throwmethods, and can't continue after the resume. Test262 signatures:Cannot read properties of undefined,throw-arg-1,reject reason,Promise incorrectly …inlanguage/expressions/class/async-gen-method-static/yield-star-*(and thestatements/class+ non-class equivalents).Root (from the #5703 worker's investigation)
Perry routes
.throw()→catch and.return()→finally into linearized generator states, but for async generatorscrates/perry-transform/.../generator/lower/abrupt.rs::build_async_catch_route_bodyhard-codes a{value: undefined, done: false}return and has no continuation loop (throw_continuation = None, deliberately). So the delegated iterator'sthrow/returnnever fires in spec order, the post-resume yielded value is dropped, and the delegation loop cannot resume. Atry/catchdesugar prototype made the inner iterator's methods fire in correct order but still dropped the resumed value — confirming the blocker is the async-generator abrupt-resume continuation machinery, a substantial standalone feature.Scope / relationship
yield*delegation)" subcluster of test262 language/class tail — 197 fails (async-gen static methods, accessor-name computed-in, private brand) #5592.Measure