Skip to content

feat(t27b): lower switch expressions and negative const literals - #6353

Merged
gHashTag merged 1 commit into
masterfrom
claude/t27b-switch
Oct 5, 2026
Merged

gHashTag merged 1 commit into
masterfrom
claude/t27b-switch

Conversation

@gHashTag

@gHashTag gHashTag commented Oct 5, 2026

Copy link
Copy Markdown
Owner

Closes #6352
Refs #6063

What

  • switch expressions in cli/t27b, on an enum or an integer operand.
    • Lowered as a right-to-left chain of lazy Selects, so only the taken prong runs (feat(t27b): lower if-expressions natively; refuse what t27c misprints #6328).
    • The operand is evaluated once; when it is not a plain variable it is spilled to a frame slot.
    • A const operand lowers only its prong.
    • The fallback is else, or the last prong when every value is listed.
    • Peer typing is shared with if through a new select_vals.
  • Negative const literals: const X: i32 = -1; lowers as the comptime int that t27c's Zig backend prints. It was refused as ExprLiteral(negative literal).
  • Named refusals: every switch shape the reference cannot compile is refused by name. Each one is BLOCKED under t27c test-report:
  • ExprCall(value ignored) statement: a new refusal for f(x); with a non-void f in a body zig test analyzes.
    • This is why specs/fpga/bpsk.t27 is BLOCKED in the reference. Without the refusal, t27b would have passed that file once its negative literals lowered.
    • Benches are no longer analysis roots. t27c emits a bench as an uncalled fn bench_<name>() void, so Zig never analyzes it. Without that change, the refusal blocked 9 reference-passing testbench files.

Corpus (t27b corpus specs --blockers --reference t27c, master f25dbee, same t27c binary and reference cache both runs)

before after
pass 351 357
pass_vacuous 285 285
fail 9 9
rejected 569 564
front-end error 40 40
mismatch 0 0
timeout 3 2
counted (t27b pass, reference pass) 623/720 629/720
checked pass (non-vacuous, reference pass) 346 352

Newly passing, each agreeing test for test with the reference:

  • specs/api/tri_api_session
  • specs/memory/tmem/session
  • specs/memory/tmem/types
  • specs/port/scripts/check-pagination-truncation
  • trios-doctor SILVER-RING-DR-00
  • trios-scarab-types SR-01

specs/fpga/testbench/axi4_tb.t27 (reference BLOCKED) changed from timeout to rejected. No file regressed.

Tests

  • switch_runs_only_the_taken_prong: verdicts equal t27c test-report.
    • Five tests pass.
    • taken_prong_traps fails on the x - 10 overflow.
    • Covers all nine refusals.
  • discarded_call_result_is_refused_where_reached: a dropped u32 in an uncalled fn, a bench, or a fn only a bench names passes. In a test it is BLOCKED, as in the reference.
  • In enum_rejections_are_precise, the old "switch is unsupported" case now checks ExprSwitch(unreachable else).

Reference quirks seen (not fixed here)

  • Const-inlining changes peer types. The t27c optimizer inlines a local const w: u16 = 1000; as the literal 1000, so Zig peer-types an if or switch with a u8 arm to u8 and refuses the value. The reference is BLOCKED where t27b passes. This is pre-existing for if and not counted.
  • Statement-form switch (for example specs/.../json.t27, reference BLOCKED) is not lowered.

🤖 Generated with Claude Code

switch on an enum or integer operand lowers to a lazy select chain, so
only the taken prong runs (#6328); the operand is evaluated once. Shapes
the reference cannot compile are refused by name (not exhaustive,
unreachable else, duplicate prong, prong, char prong #6329).

`const X: i32 = -1;` lowers as the comptime int t27c prints.

`f(x);` with a non-void f is refused where zig test analyzes the body
(ExprCall(value ignored) statement), matching specs/fpga/bpsk.t27; bench
blocks are no longer analysis roots, since t27c emits them as uncalled
fns.

Corpus vs t27c reference at f25dbee: counted 623 -> 629 / 720,
checked pass 346 -> 352, mismatch 0 -> 0, no regressions.

Closes #6352

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

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-05 03:29:15 UTC

Summary

Status Count
Total Open PRs 46
PRs with Failing Checks 34
PRs with All Checks Green 12
READY 11
FAILING 34
PENDING 0
NO CHECKS YET 0

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

Seal Status

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

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: lower switch expressions and negative const literals like the reference

1 participant