Skip to content

t27b: @intCast as an array index or a slice bound takes Zig's usize, from int_cast_plan.t27 (Closes #7902) - #7905

Merged
gHashTag merged 22 commits into
masterfrom
t27b-int-cast-index-7902
Oct 9, 2026
Merged

gHashTag merged 22 commits into
masterfrom
t27b-int-cast-index-7902

Conversation

@gHashTag

@gHashTag gHashTag commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

Closes #7902. Part of #6063 (t27b coverage), item C10 of #6488.

Decision

specs/numeric/ocp_mx.t27 passes the reference (49 of 49) and t27b refused it at 42 sites of ExprCall(@intCast), every one an array index (POW2[@intCast(e - 1)], KIND_TOP[@intCast(kind)]). #7627 gave @intCast a result type only from @as, a typed binding, a parameter or a return.

In Zig 0.16 an index, and each bound of a slice, has the result type usize. So a[@intCast(k)] converts k exactly as @as(usize, @intCast(k)) does: an i64 or an i32 is checked and a negative value is a safety panic; a u8 or a u32 widens; a usize is kept; a literal folds, and a negative literal is a compile error. t27b now lowers it the same way:

  • specs/tri/t27b/int_cast_plan.t27 names the type (INDEX_TYPE, usize). A new test shows plan's answers for an index: CHECK for i64 and i32, WIDEN for u8 and u32, KEEP for usize, FOLD or REFUSE_LITERAL for a literal, TRUNCATE in wrap mode.
  • The glue (usize_operand) sends an @intCast index or slice bound through the existing int_cast with that type. It makes no decision of its own. Every other index is lowered as before.
  • @intCast as an arithmetic operand (x + @intCast(k)) still has no result type. Zig refuses it, and t27b keeps refusing it.

Evidence

Reference: t27c test-report on the t27c lab, zig 0.16.0. t27b: aarch64 under qemu, built from this branch.

spec reference t27b before t27b after
specs/numeric/ocp_mx.t27 49/49 blocked ExprCall(@intCast) 49/49
specs/tri/t27b/conformance/int_cast_index.t27 (new) 5/5, 0 vacuous -- 5/5
specs/tri/t27b/int_cast_plan.t27 12/12, 0 vacuous 11/11 12/12
  • Conformance spec, written first: i64, i32, u8, u32 and usize indexes; nested indexes; an indexed write; a slice parameter's loop; both bounds of a slice.
  • Trap case: cli/t27b/tests/int_cast_traps.t27 gains ict_negative_index_expect_trap. It traps at the @intCast line (TrapKind::Cast), before the bounds check, in the interpreter and the JIT. Zig's Debug build panics there. A truncating cast would trap at the bounds check instead, so the test would catch it.
  • Mutants:
    • All 26 assert flips of the conformance spec fail under both t27b and the reference.
    • All 13 flips of the plan's new test fail under both.
    • Generating INDEX_TYPE as isize fails int_cast_traps_outside_its_result_type.
  • cargo test --release -p t27b (aarch64, qemu): every suite passes, exit 0.
  • Seals: int_cast_plan.t27 and conformance/int_cast_index.t27 saved, then verified (all hashes MATCH).
  • Policy gates: master's check_budget() and check_all() (with master's foreign-exceptions.txt) exit 0 on this diff.
  • Ledger: ocp_mx.t27 moves from blocked to pass, and the new conformance row is added.

Budget port (strict gate, see #8236)

The strict budget lets hand-written code under cli/t27b only shrink:

  • Ty::can_widen_from in cli/t27b/src/ir.rs was a hand copy of Zig's lossless integer widening rule. specs/tri/t27b/int_cast_plan.t27 already holds that rule as widens, with its partial-order test over the eight integer types. The method's body is now one call of the generated widens. lower.rs's ic mount becomes pub(crate) so ir.rs reaches it. ir.rs: +2 -12.
  • usize_operand, this PR's index glue, is one line shorter.

Hand lines under cli/t27b against master: +12 -17, net -5.

Lines by file (git diff --numstat --no-renames origin/master...HEAD)

file kind added removed
cli/t27b/src/ir.rs hand-written, ported out 2 12
cli/t27b/src/lower.rs hand-written glue 9 4
cli/t27b/tests/tail.rs hand-written test 1 1
gen/rust/tri/t27b/int_cast_plan.rs generated (t27c gen-rust) 7 1
specs/tri/t27b/int_cast_plan.t27 .t27 27 0
specs/tri/t27b/conformance/int_cast_index.t27 .t27 129 0
cli/t27b/tests/int_cast_traps.t27 .t27 11 0
.trinity/seals/* (2, schema 2), docs/reports/t27b_expectations.json, AGENTS.md data / prose

Gates and checks (t27c lab, tree merged with master cde548e)

  • check_budget() over git diff --numstat --no-renames cde548ecd...HEAD, built from cde548e's gen/c/policy/own_language.c: exit 0.
  • check_all() with cde548e's tools/policy/foreign-exceptions.txt and the name-status: exit 0.
  • cargo test --release -p t27b (aarch64 under qemu): 14 suites ok, 0 failed.
  • Generated code. t27c gen-rust of int_cast_plan.t27 with that tree's t27c is byte-identical to the committed file.
  • Seals. Both re-minted with that t27c (schema 2), int_cast_plan with its 12 tests; seal --verify: all hashes MATCH.
  • AGENTS.md, re-measured with wc -l: 14758 plus 1222, tests 8284, against master cde548e's 14763 plus 1222 and 8284.
  • Corpus. t27b corpus specs over master's tree, master's t27b against this branch's: exactly one file changes, specs/numeric/ocp_mx.t27, from blocked (ExprCall(@intCast)) to pass (49 tests, 116 asserts). Of 1731 files, no other changes.

t27b lab: signed receipt (#7686)

Head 9c10b0f is this branch merged with master 3ac8bef (which brings #8252, see #8248). It is requested on the t27b lab with a fresh 32-byte challenge. The base is a signed run of master 3ac8bef, requested with its own challenge because the lab had no run of that commit. The compare will be posted here when both runs are in.

The 3ac8bef merge resolved only the AGENTS.md line, re-measured with wc -l. Its tree was checked again on the t27c lab: cargo test --release -p t27b 14 suites ok, gen-rust byte-identical, seal --verify all hashes MATCH, check_budget() and check_all() (3ac8bef's gate files) exit 0.

Earlier receipt (before the budget port)

Base 76836e2 (master, the lab's own signed run). Head d659b89, this PR's change on that base, requested from the t27b lab with a fresh challenge (#7686). The compare was run on t27b-lab from /work/t27 as /work/t27c-master corpus-receipt compare BASE HEAD --challenge-head <challenge>:

base "76836e23e4580a3fb3c87bf5ef6bfd3f713a2c7a" AUTH_MISSING_NONE AUTHOR leaves-bound true
head "d659b8990efdc9ac172cc07da39e19edbd65b02c" AUTH_MISSING_NONE FRESH leaves-bound true
  input only-head specs/tri/t27b/conformance/int_cast_index.t27
  input changed specs/tri/t27b/int_cast_plan.t27
  verdict changed specs/numeric/ocp_mx.t27
  verdict only-head specs/tri/t27b/conformance/int_cast_index.t27
  output only-head specs/numeric/ocp_mx.t27
  output only-head specs/tri/t27b/conformance/int_cast_index.t27
  output changed specs/tri/t27b/int_cast_plan.t27
  lane improved specs/numeric/ocp_mx.t27
  lane improved specs/tri/t27b/conformance/int_cast_index.t27
  lane neutral specs/tri/t27b/int_cast_plan.t27
totals false inputs false verdicts false outputs false: IMPROVED_ONLY

Exit 3, IMPROVED_ONLY.

base 76836e2 head d659b89
files 1664 1665 (+1: the new spec)
t27b pass / pass_vacuous 992 / 153 994 / 153
blocked / fail / timeout 496 / 19 / 4 495 / 19 / 4
jit_interp_mismatch / crash 0 / 0 0 / 0
reference pass 1179 1180
reference disagree (files / tests) 0 / 0 0 / 0
cargo test --release -p t27b (aarch64, qemu) 145 passed 145 passed, 0 failed

Commits after d659b89. These are merges of master and nothing else: 8dee18c / e87e790, 430c522, 408d740, e66473f 4270760, 2dfe978, 6b6386e, 09ffc2f, 12ee225, 6cd8fba 35e6996 and a97cb9e. They change no file of this PR except AGENTS.md's remainder line and the ledger. AGENTS.md is re-measured with wc -l after the lines master added. In the ledger, master's rows and this PR's are kept. Since master's #7862 (see #7859), the ledger stores no counts, only max_not_pass (25 now). After each merge, the merged tree was built on the t27c lab, and cargo test --release -p t27b passed there (14 suites), with ocp_mx at 49/49.

Native arm64 (t27b-native-ratchet, ubuntu-24.04-arm, the reference built natively): reference disagree 0. Its red verdict is master's own findings (MOVED and UNEXPECTED PASS lines on other specs, the same on master). No line names a file of this PR.

Generated with Claude Code

claude and others added 2 commits October 9, 2026 02:01
…from int_cast_plan.t27 (Closes #7902)

Part of #6063 (t27b coverage), item C10 of #6488.

Zig gives an index and each bound of a slice the result type usize, so
`POW2[@intcast(e - 1)]` converts e as `@as(usize, @intcast(e))` would:
an i64 is checked and a negative one traps, a u8 widens, a usize is
kept, a literal folds. int_cast_plan.t27 names that type (INDEX_TYPE)
and its tests show plan's answers there; the glue lowers such an index
through the existing int_cast. specs/numeric/ocp_mx.t27 passes 49/49.

- specs/tri/t27b/conformance/int_cast_index.t27: ocp_mx's shapes, 5 tests,
  reference 5/5, 0 vacuous.
- cli/t27b/tests/int_cast_traps.t27: a negative index traps at the cast.
- Glue: 11 added lines in lower.rs, 1 in tests/tail.rs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-08 19:34:42 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 34
PRs with All Checks Green 16
READY 1
FAILING 34
PENDING 0
NO CHECKS YET 0

These columns do not partition: 1 + 34 + 0 + 0 = 35, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=21a1173dfe32 != 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).

AGENTS.md keeps #7819's line and re-measures this PR's after it (wc -l);
the ledger keeps both new conformance rows, counts 923 / 151 / 35.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-08 20:31:19 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 42
PRs with All Checks Green 8
READY 1
FAILING 42
PENDING 0
NO CHECKS YET 0

These columns do not partition: 1 + 42 + 0 + 0 = 43, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=3c0ade9e73e4 != 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).

AGENTS.md keeps #7803's line and re-measures this PR's after it (wc -l);
the ledger's counts are recounted from its rows: 925 / 151 / 34.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed (Closes #7902)

Master brings #8028. The only conflict was the AGENTS.md remainder line,
re-measured with wc -l. The ledger merged without a conflict, but both sides
had lowered max_not_pass by one to the same text; it is recounted from the
rows (18). Hand lines under cli/t27b against 325b0b1: net -5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed (Closes #7902)

Master brings #8258 (lower.rs's body walks move to ast_walk.t27). Conflicts
were the AGENTS.md remainder line (re-measured with wc -l) and the ledger
(rows kept from both sides, max_not_pass recounted from the rows). Hand lines
under cli/t27b against ab5b3b7: net -5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-09 20:48:56 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 46
PRs with All Checks Green 4
READY 0
FAILING 46
PENDING 0
NO CHECKS YET 0

These columns do not partition: 0 + 46 + 0 + 0 = 46, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=557cd271f4e3 != 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).

…ed (Closes #7902)

Master brings #8027. The only conflict was the AGENTS.md remainder line,
re-measured with wc -l; max_not_pass is recounted from the rows. Hand lines
under cli/t27b against 54f3c14: net -5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-09 21:02:21 UTC

Summary

Status Count
Total Open PRs 50
PRs with Failing Checks 48
PRs with All Checks Green 2
READY 0
FAILING 48
PENDING 0
NO CHECKS YET 0

These columns do not partition: 0 + 48 + 0 + 0 = 48, and there are 50 open PRs. A PR is being counted twice or not at all.

Seal Status

  • ⚠️ STALE -- sha256(compiler.rs)=557cd271f4e3 != 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).

…ed (Closes #7902)

Master brings #8350 (lower.rs's node scans move to ast_scan.t27). The only
conflict was the AGENTS.md remainder line, re-measured with wc -l;
max_not_pass is recounted from the rows. Hand lines under cli/t27b against
e4338f4: net -5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gHashTag
gHashTag merged commit 6a03402 into master Oct 9, 2026
28 of 32 checks passed
gHashTag pushed a commit that referenced this pull request Oct 9, 2026
…Closes #7909)

Master brings #7905. The only conflict was the AGENTS.md remainder line,
re-measured with wc -l; max_not_pass is recounted from the rows. Hand lines
under cli/t27b against 6a03402: net -7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

t27b: @intCast as an array index or a slice bound takes Zig's usize result type (specs/numeric/ocp_mx.t27)

2 participants