Skip to content

Commit c4dc8ee

Browse files
gHashTagPerplexity Computer
andauthored
fix(gen-rust): lower ExprCast -- emit '(operand as target)' instead of '()' (Closes #1314) (#1320)
Add Expr::Cast arm in expr_to_rust (bootstrap/src/compiler.rs), mirroring the gen-verilog arm at compiler.rs:4941. Before this fix, ExprCast fell through to the default '_ => "()".to_string()' branch and generated empty-tuple stubs in Rust output, silently corrupting any T27 spec using bit-width casts. Also update docs/NOW.md with an exprcast-rust-emitter entry (required by the NOW Sync Gate). Closes #1314 (gen-rust half; gen-c and gen-zig follow-ups tracked separately). Unblocks gHashTag/tri-net#33 T27-first wire flip. Anchor: phi^2 + phi^-2 = 3 Co-authored-by: Perplexity Computer <agent@perplexity.ai>
1 parent bc70a05 commit c4dc8ee

2 files changed

Lines changed: 24 additions & 0 deletions

File tree

bootstrap/src/compiler.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8169,6 +8169,24 @@ impl RustCodegen {
81698169
s.push('}');
81708170
s
81718171
}
8172+
NodeKind::ExprCast => {
8173+
if node.children.is_empty() {
8174+
"()".to_string()
8175+
} else {
8176+
let operand = Self::expr_to_rust(&node.children[0]);
8177+
let target = node
8178+
.extra_type
8179+
.split('[')
8180+
.next()
8181+
.unwrap_or("")
8182+
.trim();
8183+
if target.is_empty() {
8184+
operand
8185+
} else {
8186+
format!("({} as {})", operand, target)
8187+
}
8188+
}
8189+
}
81728190
_ => "()".to_string(),
81738191
}
81748192
}

docs/NOW.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
Last updated: 2026-07-04
44

5+
## exprcast-rust-emitter -- lower ExprCast in gen-rust backend (Closes #1314)
6+
7+
- **WHERE**: `bootstrap/src/compiler.rs` -- added `Expr::Cast { operand, target }` arm in `expr_to_rust`, emits `format!("({} as {})", operand, target)` mirroring the existing gen-verilog arm at compiler.rs:4941. Before this fix, ExprCast in `expr_to_rust` fell through to the default `_ => "()".to_string()` branch, producing empty-tuple stubs in generated Rust and silently corrupting any T27 spec that uses bit-width casts (bit-shift lowering, width promotion, etc.). +18 / -0 lines. Isolated repro filed as #1314 with a 5-line spec showing the empty-tuple emission.
8+
- **Why**: gen-rust is one of three lowering targets (Rust, Verilog, C). The Verilog and C emitters had ExprCast; the Rust emitter did not. This closes the gen-rust half of #1314; gen (Zig) and gen-c follow-ups tracked separately. Unblocks the tri-net T27-first wire flip (gHashTag/tri-net#33), where specs/wire.t27 needs the fixed emitter to regenerate gen/rust/wire.rs without hand-patching.
9+
- **Anchor**: phi^2 + phi^-2 = 3
10+
511
## bcd-bitexact-promotion -- promote bcd -> strict bitexact (2-digit packed instance) (Closes #1321)
612

713
- **WHERE** (conformance vectors): `conformance/vectors/bcd_conformance_v0.json` promoted from `structural` to `bitexact` in `INDEX_all_formats.json` (bitexact_packs 69 -> 70, structural_packs 14 -> 13; bcd.kind structural -> bitexact, n_vectors 0 -> 100). Fixes ONE concrete instance: 2-digit packed BCD, 8-bit word bcd_in[7:4]=tens, bcd_in[3:0]=ones, decode value = tens*10 + ones (valid 0..99). Generic variable-width BCD (u4_per_digit) stays noted in catalog.instance/format_notes; only this fixed-width instance carries a bit-precise round-trip claim.

0 commit comments

Comments
 (0)