Skip to content

Fix #488, #534, #634, #635: generator expressions in more positions; async function expressions#686

Merged
nickna merged 1 commit into
mainfrom
wrk/hopeful-montalcini-32d03a
Jun 16, 2026
Merged

Fix #488, #534, #634, #635: generator expressions in more positions; async function expressions#686
nickna merged 1 commit into
mainfrom
wrk/hopeful-montalcini-32d03a

Conversation

@nickna

@nickna nickna commented Jun 16, 2026

Copy link
Copy Markdown
Owner

Completes #488, #534, #634, #635.

#635 — Parse async function expressions

async function () {} and async function* () {} in expression position now parse. The parser previously only attempted an async arrow after async (it unconditionally consumed (), so any async function expression was a parse error. Added a function-keyword check that defers to the shared FunctionExpression parser (now isAsync-aware, and it already handles *), mirroring the statement-level async function declaration path.

GeneratorArrowLifter — complete, identity-preserving traversal

GeneratorArrowLifter rewrites generator function expressions into top-level Stmt.Function declarations so the mature generator-declaration IL pipeline can lower them. Its hand-rolled traversal covered only a subset of AST nodes, so a generator expression in an un-visited position was never lifted — and because the function-expression generator context is established only via the lift, the type checker then rejected its yield. The rewriter now descends through every expression- and statement-bearing position (identity-preserving, so untouched subtrees keep their node identity for the type checker).

Tests

Follow-up issues filed

Note on Test262

async function expressions let the whole Array/fromAsync/* Test262 suite parse (it uses asyncTest(async function () { … })); those ~76 tests move ParseError → Fail (a parser progression — they fail only because Array.fromAsync is unimplemented). The Test262 baseline is not updated here: local regen is non-deterministic in this Windows environment (unrelated tests flip Pass/Fail/RuntimeError run-to-run, plus intermittent host crash 0x80131506), so a regen would bake in noise. Test262 is not a CI gate; recommend regenerating its baseline in a stable environment.

…nc function expressions

#635 — Parse async function expressions
  `async function () {}` / `async function* () {}` in expression position now parse.
  The parser previously only attempted an async arrow after `async`; added a `function`
  check that defers to FunctionExpression (now isAsync-aware), mirroring the
  statement-level async-function-declaration path.

GeneratorArrowLifter — complete, identity-preserving AST traversal
  The lifter rewrites generator function expressions into declarations so the IL
  pipeline can lower them. Its traversal was incomplete, leaving generator expressions
  un-lifted in several positions (their `yield` then failed type-checking).

  #488 — descends through grouped / call-position callees, so an IIFE generator
    `(function*(){ yield 1 })()` is lifted and runs (both modes).
  #634 — descends into for / for-of / for-in / do-while / try-catch-finally / switch /
    labeled bodies (plus ternary, array/object literals, new, spread, await, etc.).
  #534 — a generator expression closing over an enclosing function's body-level local
    is lifted into that function (interpreter runs it natively; the compiler emits the
    existing #501 "Yield not supported" error, so the success path is interpreter-only).
    A conservative free-variable analysis over-approximates the bound set so a
    module-closing generator is never mis-relocated into a function — no regression to
    the #522/#1295 compiled module-closure cases.

Tests: new AsyncFunctionExpressionTests; new GeneratorTests regions for #488/#634/#534.
Full SharpTS.Tests suite green (12,716); TypeScript conformance green.

Follow-ups filed: #678 (block-scoped/loop-var capture), #679 (named genexpr
self-recursion), #681 (.call/.apply/.bind on async functions).
@nickna nickna merged commit 6a4fd72 into main Jun 16, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant