Repository navigation
[GOLD-RING] fix(gen-rust): bool negation and integer-width coercion - #1777
Merged
Merged
Conversation
t27c typecheck accepted three patterns that gen-rust lowered into Rust
that does not compile. All three share one root cause: expr_to_rust was
a static fn, so it could not consult the codegen's type tables.
1. `!x` on a Rust bool became the integer zero test `(x) == 0`
(`bool == {integer}` -> E0308). The operand check only recognised
comparison operators, so a `bool` parameter or a `-> bool` call fell
through. expr_to_rust is now a &self method and reuses the existing
`expr_is_bool` predicate. Integer operands still get `(x) == 0`,
since Rust's `!` is bitwise there.
2. A `return` was not coerced to the declared return type: `return dir;`
(u8) and `return (ctr >> 8) & 255;` (u64) from a `-> u32` fn -> E0308.
3. Binary operands were not coerced to a common width: `u16 * u8`
(E0277), `u32 * u64` (E0308). Shifts are exempt -- Rust already
accepts any integer type as the shift amount.
(2) and (3) are driven by a new conservative `infer_int_type` over
params, locals, constants and callee return types. A cast is emitted
only on positive evidence of a declared width that differs; bare
literals and unknown widths are left alone, so Rust's own inference
still applies and existing output is untouched.
Fixed in gen-rust rather than by tightening typecheck: t27 accepts
mixed widths by design across all five backends.
Verified: 889-spec differential against the pre-fix compiler -- 26 files
change, 15 drop rustc errors, 11 are byte-identical in their error sets,
0 regress. gen (zig), gen-c, gen-verilog, gen-verilog-hir and typecheck
are byte-identical on every changed spec. 1506 unit tests pass, incl. 6
new regression tests covering both the fixes and the negative cases.
FROZEN_HASH reseal (M5) accompanies the compiler.rs change, per
FROZEN.md 5 -- same ceremony as the earlier gen-verilog fixes.
Closes #1775
Co-Authored-By: Claude Opus 4.8 <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 Aug 6, 2026
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
PR DashboardGenerated at: 2026-08-06 10:33:14 UTC
Summary
Seal Status
|
Required by the check-now-freshness gate: every PR to master must update docs/NOW.md. Closes #1775 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
PR DashboardGenerated at: 2026-08-06 10:44:38 UTC
Summary
Seal Status
|
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 #1775
t27c typecheckaccepted three patterns thatgen-rustlowered into Rust that does not compile. All three share one root cause:expr_to_rustwas a static fn, so it could not consult the codegen's type tables.Fixes
!<bool>->(x) == 0. The operand check only recognised comparison operators, so aboolparameter or a-> boolcall fell through to the integer zero test (bool == {integer}-> E0308).expr_to_rustis now a&selfmethod and reuses the existingexpr_is_boolpredicate. Integer operands still get(x) == 0, since Rust's!is bitwise there.Return not coerced to the declared return type.
return dir;(u8) andreturn (ctr >> 8) & 255;(u64) from a-> u32fn -> E0308.Binary operands not coerced to a common width.
u16 * u8(E0277),u32 * u64(E0308). Shifts are exempt — Rust already accepts any integer type as the shift amount.(2) and (3) are driven by a new conservative
infer_int_typeover params, locals, constants and callee return types. A cast is emitted only on positive evidence of a declared width that differs; bare literals and unknown widths are left alone, so Rust's own inference still applies and existing output is untouched.Fixed in gen-rust rather than by tightening typecheck: t27 accepts mixed widths by design across all five backends.
Verification
889-spec differential against the pre-fix compiler
Largest wins:
isa/ternary_memory80->43,fpga/vcd_conformance_compare46->42,igla/race/ternary_mac9->5.All 11 "unchanged" specs were checked individually and have byte-identical error sets — nothing new was swapped in. They abort early on unrelated pre-existing parse-level gen-rust bugs, which is why the
!fix does not move their count.Backend isolation
gen(zig),gen-c,gen-verilog,gen-verilog-hirandtypecheckare byte-identical on all 26 changed specs — the change is structurally confined toRustCodegen.t27c suiteRun on both this branch and the pre-fix compiler. Summaries are identical, and the FAIL sets match exactly:
The 8 failures are
gen-verilog-yosys-smoke— pre-existing, in a backend this PR does not touch, and present identically on the base compiler.Caveat, disclosed: the suite was run against a mirror of the repo root whose
specs/omitsscratch/, covering the remaining 560 specs. A full-tree run cannot complete — the parse phase is superlinear andspecs/scratch/holds 12.4M lines. That is pre-existing and unrelated; filed separately as #1781.Tests
1506 unit tests pass, including 6 new regression tests covering the three fixes plus three negative cases (
!on an integer stays a zero-test; matching widths gain no redundant cast; shift amounts are not coerced).Reviewer notes
compiler.rschange, per FROZEN.md §5 — same ceremony as the earlier gen-verilog fixes (7ea79c7f5,f444e7af1).tri-net'scrypto_frame.t27can now revert its workarounds to the cleaner!seen_any/return dir;/& 255forms. The existing workarounds (seen_any == false,dir as u32) still generate correctly and are not double-cast, so the revert is safe in either order.🤖 Generated with Claude Code