Skip to content

[GOLD-RING] fix(gen-rust): bool negation and integer-width coercion - #1777

Merged
gHashTag merged 3 commits into
masterfrom
claude/wonderful-jackson-a3ea48
Aug 6, 2026
Merged

gHashTag merged 3 commits into
masterfrom
claude/wonderful-jackson-a3ea48

Conversation

@gHashTag

@gHashTag gHashTag commented Aug 6, 2026 •

Copy link
Copy Markdown
Owner

Closes #1775

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.

Fixes

  1. !<bool> -> (x) == 0. The operand check only recognised comparison operators, so a bool parameter or a -> bool call fell through to the integer zero test (bool == {integer} -> E0308). 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. Return not coerced to the declared return type. return dir; (u8) and return (ctr >> 8) & 255; (u64) from a -> u32 fn -> E0308.

  3. 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_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.

Verification

889-spec differential against the pre-fix compiler

Specs with changed output 26 / 889
rustc errors improved 15
Unchanged (byte-identical error sets) 11
Regressed 0

Largest wins: isa/ternary_memory 80->43, fpga/vcd_conformance_compare 46->42, igla/race/ternary_mac 9->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-hir and typecheck are byte-identical on all 26 changed specs — the change is structurally confined to RustCodegen.

t27c suite

Run on both this branch and the pre-fix compiler. Summaries are identical, and the FAIL sets match exactly:

Parse failures:           0      Gen Verilog fails:        0
Typecheck fails:          0      Gen Verilog smoke fails:  8
GF16 conformance:         0      FPGA smoke fails:         0
Gen Zig failures:         0      Gen C failures:           0
Gen Rust failures:        0      Seal mismatches:          0
                                 FP divergences:           0

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/ omits scratch/, covering the remaining 560 specs. A full-tree run cannot complete — the parse phase is superlinear and specs/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

  • FROZEN_HASH reseal (M5) accompanies the compiler.rs change, per FROZEN.md §5 — same ceremony as the earlier gen-verilog fixes (7ea79c7f5, f444e7af1).
  • Downstream: tri-net's crypto_frame.t27 can now revert its workarounds to the cleaner !seen_any / return dir; / & 255 forms. 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

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>
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-08-06 10:20:30 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 0
PRs with All Checks Green 50
READY 0
FAILING 0
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=6770cc28c320 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-08-06 10:33:14 UTC

Summary

Status Count
Total Open PRs 34
PRs with Failing Checks 24
PRs with All Checks Green 10
READY 9
FAILING 24
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=6770cc28c320 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

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>
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

📓 NotebookLM Notebook linked to this PR

This notebook contains session context, decisions, and artifacts for this work.

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-08-06 10:44:38 UTC

Summary

Status Count
Total Open PRs 34
PRs with Failing Checks 24
PRs with All Checks Green 10
READY 9
FAILING 24
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=6770cc28c320 != manifest seal=87e5cbd3ad94.
    The committed NMSE numbers were certified against an older compiler.rs.
    Run scripts/reseal-check.sh locally for the two-step reseal command (advisory; not a merge gate).

@gHashTag
gHashTag merged commit 8b89b67 into master Aug 6, 2026
19 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.

codegen: gen-rust emits uncompilable Rust for bool negation and mixed integer widths

1 participant