Skip to content

A yield inside an expression is an error, and a yield's value is undefined - #621

Merged
ASDAlexander77 merged 1 commit into
mainfrom
yield-in-expression
Oct 19, 2026
Merged

ASDAlexander77 merged 1 commit into
mainfrom
yield-in-expression

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

mlirGen(YieldExpression) returned success with no value, so any expression around a yield was silently dropped. const t = ("a" + i) + (yield 1) never wrote t, and the program crashed reading it (every memory model, gc included). A value computed before the yield in the same expression would also be an SSA value of the turn that returned, gone when the generator resumes at the state label.

  • A yield now evaluates to undefined, made after the label (next() takes no argument yet). This applies where nothing is computed before the yield: yield x;, const v = yield x; and v = yield x; (with v an identifier).
  • The enclosing statement marks those yields (SupportedYieldScope), because the AST has no parent links. Compiler-made yields sit in expression statements, so they count as statement-level.
  • Any other yield is now a compile error: a yield inside an expression is not supported ... assign the yield to a variable first. Using the value of yield* is also an error, since it still gives nothing back.

Tests:

  • 00generator_yield_value.ts (compile + jit, in the corpus, so it runs under rc/none too).
  • yield-in-expression/{binary,call_argument,yield_star_value}.ts, checked for the error under gc/rc/none.

Full ctest -C Release -j 16: 100% passed, 0 failed out of 4782.

Not covered here: a variable declaration whose initializer fails with no diagnostic still declares an uninitialized variable. That silent-failure gap is general and has nothing to do with yield.

🤖 Generated with Claude Code

…fined

mlirGen(YieldExpression) returned success with no value, so an expression
around a yield was silently dropped: `const t = ("a" + i) + (yield 1)` left t
unwritten and the program crashed reading it. A value computed before the
yield in the same expression would be an SSA value of the turn that returned,
gone when the generator resumes at the state label.

A yield now gives undefined (made after the label; next() takes no argument
yet) where nothing is computed before it: `yield x;`, `const v = yield x;` and
`v = yield x;`. The statement marks those yields (the AST has no parent links);
any other yield is a compile error, and so is using the value of yield*.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit a2ead15 into main Oct 19, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the yield-in-expression branch October 19, 2026 22:33
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