Repository navigation
fix(compiler): assert (a & b) == c is one condition, not assert(a & b) then == c - #5594
Merged
Merged
Conversation
…) then == c The statement parser sent every `assert (` to the call path, so a bare assert whose condition opens with a parenthesis parsed as `assert(a & b)` followed by `== c`. Typecheck said ok; the Zig backend emitted `if (!(a & b)) @Panic("assertion failed") == c;`, which zig rejects. A lookahead now skips the balanced parentheses after `assert`; when a binary operator follows the matching `)` on the same line, the bare form is parsed and the whole condition goes into the assert. `assert(x);`, `assert((a & b) == c);` and `assert(x, "msg")` keep the old path. Corpus, master vs this branch, 1146 specs: ast-dump, gen and gen-c change for 3 specs (railway_deploy, mod_structure, mvp_ternary_classifier_jtag_noport; 8 asserts); gen-rust and gen-verilog change for none. Under zig test --test-no-exec every error those asserts caused is gone (8 "unreachable code", 5 "expected type 'bool'"); the remaining errors in those specs are on master too and none is new. Seal: compiler.rs changed, so bootstrap/stage0/FROZEN_HASH moves (FROZEN.md section 5). railway_deploy.t27 and mod_structure.t27 matched their seals on master and are resealed with this branch's t27c (gen_hash_c, gen_hash_zig, sealed_at only). Regression guard: bootstrap/tests/assert_paren_binary.rs (4/4). Closes #5593 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
This was referenced Oct 2, 2026
Merged
This was referenced Oct 2, 2026
Owner
Author
|
Reviewer bee W -- verified at head The title's claim matches the diff: Evidence (fresh clone under /tmp, t27c built from master 6111696 and from this head):
Red checks: test-ratchet and fpga-conformance are also red on #5455, which does not touch the parser, so they are pre-existing. Corpus ratchet, spec-guards, untrusted-input, coverage and Scorecard are red on master; emit-bitexact fails on every open PR. |
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.
Closes #5593
What was wrong
The statement parser sent every
assert (to the call path. Soassert (a & b) == cparsed asassert(a & b)followed by== c. Typecheck said ok, and the Zig backend emitted:The fix
bootstrap/src/compiler.rsgets a lookahead. It skips the balanced parentheses afterassert. If a binary operator follows the matching)on the same line, it parses the bare form, so the whole condition goes into the assert.assert(x);,assert((a & b) == c);andassert(x, "msg")keep the old path.Measured: master d04bf14 vs this branch, all 1146 specs
ast-dump,gen(Zig),gen-ccloud/railway_deploy(4 asserts),compiler/mod_structure(1),port/fpga/verilog/mvp_ternary_classifier_jtag_noport(3)gen-rust,gen-verilogzig test --test-no-exec, every error those 8 asserts caused is gone: 8 "unreachable code" and 5 "expected type 'bool'".invariantblocks, which have their own parse path;Seals
bootstrap/stage0/FROZEN_HASHmoves (FROZEN.md section 5).railway_deploy.t27andmod_structure.t27matched their seals on master. They are resealed with this branch's t27c, and onlygen_hash_c,gen_hash_zigandsealed_atchange.Tests
bootstrap/tests/assert_paren_binary.rs: 4/4. The bare form with==,andand-must emit exactly what the call form with the same condition emits, and the call forms keep their old output.cargo test --bin t27cdoes not compile on master in this environment (proxy.rs:hyper_utilBuilder::request; axum without--features server), and neither doestests/corpus_unresolved.rs(E0716). That is why the guard is an integration test.assert (x & y) == xnow passeszig test7/7. On master its Zig does not compile.🤖 Generated with Claude Code