An if/else branch written without braces is a scope of its own (#458) - #475
Merged
Merged
Conversation
`if (x) a(); else for (const c of gen()) ...` failed to compile in every model: "operand #0 does not dominate this use". A braced branch is a Block, and a Block keeps its own lists of what it must give back at its end - owned locals, `using` declarations. An unbraced branch was generated straight into the enclosing block's lists, so the iterator a `for ... of` over a generator owns, defined inside the branch's region, was released at the end of the block around the `if`, outside that region. A number loop or a `for ... of` over an array owns nothing there, which is why they compiled. mlirGenBranchStatement generates an unbraced then/else statement with lists of its own and the same scope exit a Block ends with; a braced branch still goes through mlirGen(Block). Test: 00unbraced_branch_scope (compile and JIT, and in the rc/none corpus): an unbraced else and then iterating a generator, inside a loop, and an unbraced if as a loop body. It failed to compile before the change; it passes under gc, rc, none and own. The own corpus is unchanged; on Linux (WSL, GCC) the rc corpus, own and new tests pass (1453/1453). Fixes #458. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #458.
In every model,
if (x) a(); else for (const c of gen()) ...failed to compile with "operand #0 does not dominate this use".A braced branch is a
Block. ABlockkeeps its own lists of what it must release at its end: owned locals andusingdeclarations. An unbraced branch was generated straight into the enclosing block's lists instead. So the iterator owned by afor ... ofover a generator, which is defined inside the branch's region, was released at the end of the block around theif, outside that region. A number loop, or afor ... ofover an array, owns nothing there, which is why those compiled.mlirGenBranchStatementnow generates an unbraced then/else statement with lists of its own, ending in the same scope exit aBlockends with. A braced branch still goes throughmlirGen(Block).Tests
New
00unbraced_branch_scope.ts, registered as compile and JIT tests and in the rc/none corpus. It covers:elseand an unbracedtheniterating a generator;ifas a loop body.It failed to compile before the change, and now passes under gc, rc, none and own.
The own corpus is unchanged.
On Linux (WSL, GCC), the rc corpus, own tests and the new tests pass: 1453/1453.
Full Release ctest on Windows: 3690/3691. The one failure is
test-compile-gc-defaultlib-collector, the known local LNK2005 against the stale installed default library; it fails on main the same way.🤖 Generated with Claude Code