Skip to content

fix(gen-zig): narrowing unsigned cast lowers to @truncate, not @intCast - #1999

Merged
gHashTag merged 1 commit into
masterfrom
fix/gen-zig-narrowing-truncate
Aug 9, 2026
Merged

fix(gen-zig): narrowing unsigned cast lowers to @truncate, not @intCast#1999
gHashTag merged 1 commit into
masterfrom
fix/gen-zig-narrowing-truncate

Conversation

@gHashTag

@gHashTag gHashTag commented Aug 9, 2026

Copy link
Copy Markdown
Owner

t27 as truncates on a narrowing integer cast (Rust semantics), but the Zig backend always emitted the checked @intCast, which panics in safe builds when the value doesn't fit. tri_settle::reward_weighted extracts the u32 halves of a u64 (weighted_total as u32, (weighted_total >> 32) as u32); on a 2³²-multiple input @intCast aborts instead of truncating.

Fix

Codegen(Zig) now carries a param/typed-local type map, scoped per fn (populated from the fn signature and typed let locals). ExprCast emits @truncate when the source integer is provably a wider unsigned int than the (unsigned) target; signed narrowing and widening/unknown stay on @intCast (unchanged).

The unsigned-only restriction is deliberate: Zig's @truncate rejects a signed source (e.g. i16 as u8), which a broader rule broke — caught by ast-check on link_quality_monitor.

Validation

  • tri-net corpus: 16 gen/zig regenerate (narrowing sites flip to @truncate); all pass zig ast-check + zig test
  • icarus / C / Rust untouched (gen-zig only)
  • t27 unit suite: 1537 passed / 0 failed
  • FROZEN_HASH resealed

A companion tri-net PR regenerates the 16 affected gen/zig.

Refs #1948

🤖 Generated with Claude Code

t27 'as' truncates on a narrowing integer cast (Rust semantics), but the
Zig backend always emitted the CHECKED @intcast, which panics in safe
builds when the value does not fit. tri_settle::reward_weighted extracts
the u32 halves of a u64 (weighted_total as u32, (weighted_total >> 32)
as u32); on a 2^32-multiple input @intcast aborts instead of truncating.

Codegen(Zig) now carries a param/typed-local type map, scoped per fn
(populated from the fn signature and typed 'let' locals). ExprCast emits
@truncate when the source integer is provably a WIDER UNSIGNED int than
the unsigned target; signed narrowing and widening/unknown stay on
@intcast (unchanged). The unsigned-only restriction is deliberate: Zig's
@truncate rejects a signed source (e.g. 'i16 as u8'), which a broader
rule broke -- caught by ast-check on link_quality_monitor.

tri-net corpus: 16 gen/zig regenerate (narrowing sites flip to
@truncate); all pass zig ast-check + zig test. icarus / C / Rust are
untouched (gen-zig only). t27 unit suite 1537 passed / 0 failed.

FROZEN_HASH resealed.

Refs #1948

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 9, 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 9, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-08-09 02:45:49 UTC

Summary

Status Count
Total Open PRs 15
PRs with Failing Checks 2
PRs with All Checks Green 13
READY 5
FAILING 2
PENDING 0

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=6c30e43706ec != 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 d4c768e into master Aug 9, 2026
23 checks passed
@gHashTag
gHashTag deleted the fix/gen-zig-narrowing-truncate branch August 9, 2026 02:46
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.

1 participant