Skip to content

t27b: _ = e; with e not a bare name is deleted where the reference deletes it and run everywhere else (Closes #7810) - #7853

Merged
gHashTag merged 5 commits into
masterfrom
t27b-discard
Oct 8, 2026
Merged

gHashTag merged 5 commits into
masterfrom
t27b-discard

Conversation

@gHashTag

@gHashTag gHashTag commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

Closes #7810. Part of #6063 (t27b coverage), which is item C10 of #6488.

What the reference does

specs/port/bootstrap/src/compiler/collect_type_decls.t27 passes the reference 8/8. t27b refused it at 17 lines with StmtAssign(undeclared) (assignment to undeclared '_'). Each of those lines is a _ = e; whose e is not a bare name. t27b only took _ = p; for a parameter p.

The reference's Compiler::compile runs optimize before gen-zig, with keep_call_discards: true. Its dead-store pass (dead_store_elim_with) walks the top-level statements of every fn body. There, a _ = e; whose e holds a call (expr_has_call) stays, and any other _ = e; is deleted. Nested blocks, and tests, are not touched.

Measured on the t27c lab (t27c gen and t27c test-report, zig 0.16.0, x86_64 Debug):

shape t27c gen reference
_ = dv_void(n); _ = dv_value(n); at the top of a fn kept pass; each call's effect counted once
_ = "literal"; _ = n + 1; at the top of a fn deleted pass
_ = a + b; (u8 200 + 100) at the top of a fn deleted pass: no trap
the same _ = a + b; inside an if kept FAIL: integer overflow
_ = "literal"; _ = dv_value(n); inside an if / else kept pass; only the taken arm's call runs
a fn in a brace-style module x { ... } the same deletion pass
_ = dv_value(4); at the top of a test const _ = dv_value(4); blocked: "'' used as an identifier without @"" syntax"
the same, nested in an if in a test kept pass

Decision, with the evidence

The decisions are a t27 plan, specs/tri/t27b/discard_plan.t27, with 4 tests. t27c gen-rust turns it into gen/rust/tri/t27b/discard_plan.rs, and lower.rs mounts that file with #[path].

  • DELETED. At the top level of a fn body (t27b's outermost scope, outside a test), an e with no call is not lowered at all, as the reference deletes it. A pure overflow there cannot trap.
  • EVALUATE. Anywhere else, e is lowered and evaluated, and its value is dropped:
    • a call to a declared fn runs as a statement, void or not, and an aggregate result goes to a temporary;
    • any other e is evaluated with its traps.
  • NOT_MINE. These two keep their paths, unchanged:
    • a bare name (_ = p;), whose path models Zig's pointless-discard rule;
    • _ = e; at the top level of a test, invariant or bench, which is t27b's test-binding path. The reference blocks that shape. Refusing it here would move t27b verdicts on files the reference blocks, and that is not this lane's to change.

The glue in assign reads three facts, and discard_value builds the EVALUATE answer:

  • whether e is a bare name;
  • where the statement is;
  • whether e holds a call (calls_in, which is expr_has_call's walk).

Conformance spec first

specs/tri/t27b/conformance/discard_value.t27 has 5 tests, each with the shapes above:

  • collect_type_decls.t27's void call at the top of a body, with literals in the arms of an if and after it. Effects are counted per branch.
  • Three discarded calls at the top of a fn: a value, a call inside + 1, and a struct result. Each runs exactly once.
  • A pure _ = a + b; at the top level that would overflow. It is deleted, so it does not trap.
  • Nested discards run only on the arm taken.
  • A discard nested in a test.
result
reference, t27c test-report 5/5, 0 vacuous, 10 runtime asserts; sealed (seal --save, then --verify: all hashes MATCH)
master's t27b refused: StmtAssign(undeclared)
this branch's t27b (aarch64 under qemu, t27b test --check) 5/5, 10 runtime asserts
  • Mutants. 10 mutants of the conformance spec flip one assert each. Every one fails exactly one test, in the reference and in t27b alike.
  • The plan. t27c test-report 4/4, 0 vacuous; sealed. All 6 plan mutants are caught by its tests.
  • The overflow tail.rs checks. The nested overflow fails in t27b with an Overflow trap, as the reference fails. The top-level one passes.

Corpus

t27b corpus specs --blockers, master against this branch, on the t27c lab (1654 files on f53a734; repeated on 14e1c7b, 1662 files, with the same result):

  • Unblocked: collect_type_decls.t27 and the conformance spec lose StmtAssign(undeclared), their only blocker.
  • Still blocked: 12 other files lose it from their blocker list but keep other blockers. They are ternary_memory, prove, knowledge_graph, ternary_deque, formula_embed, forward_pass, pins/parser, SR-00/lib, relay_observer, bigint, hybrid_bigint and sequence_hdc.
  • No file gains a blocker.

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

file kind added deleted
cli/t27b/src/lower.rs hand-written glue 29 0
cli/t27b/tests/tail.rs hand-written test 15 0
gen/rust/tri/t27b/discard_plan.rs t27c gen-rust, not hand-edited 29 0
specs/tri/t27b/discard_plan.t27 plan spec, 4 tests 82 0
specs/tri/t27b/conformance/discard_value.t27 conformance spec, 5 tests 113 0
.trinity/seals/*.json (2) t27c seal --save 40 0
docs/reports/t27b_expectations.json ledger 6 4
AGENTS.md t27b remainder line 4 1

Hand-written foreign code: 44 added lines, 0 deleted (29 in lower.rs, 15 in tests/tail.rs). That is under the #7371 cap of 40 per file and 80 per PR. Both files are on master's tools/policy/foreign-exceptions.txt. This PR does not change that file and needs no label.

AGENTS.md, re-measured with wc -l: cli/t27b/src/*.rs goes from 15195 to 15224, plus 1202 in src/*/*.rs, and cli/t27b/tests/*.rs from 8134 to 8149, on master 3d16be1.

Ledger:

  • collect_type_decls.t27: blocked -> pass.
  • Two new rows, and both specs pass.
  • Counts, recomputed from the entries on master 3d16be1: pass 923 -> 926, not_pass 35 -> 34, max_not_pass 35 -> 34.

Gates

Both gates ran on the t27c lab, using master 1083135's gen/c/policy/own_language.c and lefthook.yml's one-line C main.

  • check_budget() over git diff --numstat --no-renames origin/master...HEAD: exit 0.
  • check_all() with origin/master:tools/policy/foreign-exceptions.txt, -- and git diff --name-status origin/master...HEAD: exit 0.

cargo test --release -p t27b on the t27c lab (x86_64, interpreter only), on master 3d16be1 plus this branch: 128 passed, 0 failed. That includes the new a_discarded_value_runs_unless_the_reference_deletes_it.

Run with t27b test --check (aarch64 under qemu), on the same tree:

t27b lab: signed receipts (#7686)

Head 4e7a07a against its merge-base, master f53a734. Head 4e7a07a is this branch as first pushed: the plan, the glue, the specs and the ledger rows on master f53a734. Both are signed runs of the deployed t27b lab. The head run was requested with a fresh 32-byte challenge, and the base by an explicit request, since the lab had not run that master commit.

/work/t27c-master corpus-receipt compare BASE HEAD --challenge-head <mine>, run on the t27b lab from /work/t27:

base "f53a734b7061c2ed677b69b7d3eceb83a867cf05" AUTH_MISSING_NONE AUTHOR leaves-bound true
head "4e7a07add66a7350fb2c39a13e7536349e646fc6" AUTH_MISSING_NONE FRESH leaves-bound true
  lane improved specs/port/bootstrap/src/compiler/collect_type_decls.t27
  lane improved specs/tri/t27b/conformance/discard_value.t27
  lane improved specs/tri/t27b/discard_plan.t27
totals false inputs false verdicts false outputs false: IMPROVED_ONLY

Exit 3, IMPROVED_ONLY. (The input, verdict and output lines name the same three files and are left out here.)

base f53a734 head 4e7a07a
files 1652 1654 (+2: the new specs)
t27b pass / pass_vacuous 977 / 153 980 / 153
t27b fail 19 19
jit_interp_mismatch / crash 0 / 0 0 / 0
reference pass 1167 1169
reference disagree (files / tests) 0 / 0 0 / 0
cargo test --release -p t27b (aarch64, qemu) 142 passed, 0 failed 143 passed, 0 failed

collect_type_decls.t27 passes with 11 runtime asserts, the conformance spec with 10 and the plan with 12.

What changed after the receipted head. Master moved by #7818, #7447, #7808, #7744, #7863 and #7870 while the queue waited, and each touched the ledger, AGENTS.md or tests/tail.rs. The final head, d9591f3, is 4e7a07a merged with master 3d16be1. Those merges resolved only:

  • lower.rs's plan mounts, all kept;
  • tests/tail.rs's sections, all kept;
  • the AGENTS.md line;
  • the ledger counts.

Head 852a23a was dropped from the lab queue without running: the branch moved on before the lab reached it. On the final tree, on the t27c lab:

  • cargo test --release -p t27b passed 128, failed 0;
  • the two seals verify (all hashes MATCH);
  • collect_type_decls.t27 and the conformance spec lower with no blocker;
  • check_budget() and check_all() exit 0.

gen-rust gaps

None. The plan is decisions over bool and u8.

🤖 Generated with Claude Code

…letes it and run everywhere else (Closes #7810)

The reference's `optimize` runs before gen-zig with keep_call_discards on: its
dead-store pass deletes each `_ = e;` at the top level of a fn body whose e
holds no call, and keeps the rest. Elsewhere t27c prints `_ = e;` as written,
and Zig evaluates e, with its effects and traps, and drops the value. t27b
refused every such statement as StmtAssign(undeclared), which blocked
specs/port/bootstrap/src/compiler/collect_type_decls.t27.

The decisions are in specs/tri/t27b/discard_plan.t27 (4 tests), generated with
`t27c gen-rust` to gen/rust/tri/t27b/discard_plan.rs and mounted in
cli/t27b/src/lower.rs. DELETED: an e with no call at the top level of a fn
body. EVALUATE: anything else is evaluated and dropped. NOT_MINE: a bare name
(the parameter-discard path) and a test's top level (the test-binding path,
which the reference blocks), both unchanged.

The conformance spec is specs/tri/t27b/conformance/discard_value.t27:
`t27c test-report` 5/5, 0 vacuous. Glue: lower.rs +29, tests/tail.rs +15.
Ledger: collect_type_decls.t27 now passes; the two new specs are new rows.

Part of #6063.

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 16:23:00 UTC

Summary

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

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

Seal Status

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

lower.rs and tests/tail.rs keep both sides. The ledger takes master's and
re-applies this branch's three rows; counts recomputed from the entries:
pass 918, not_pass 36. AGENTS.md records #7447's step, which left the line
as it was (15129 plus 1202 and 8075), then this branch's: 15158 plus 1202
and 8090, on master 14e1c7b.

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 17:19:38 UTC

Summary

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

These columns do not partition: 1 + 45 + 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)=39fa3908f9fd != 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 takes #7808's step and adds this branch's: 15174 plus 1202 and
8109, on master 81da894's 15145 plus 1202 and 8094. The ledger takes
master's and re-applies this branch's rows: pass 920, not_pass 36.

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 17:59:06 UTC

Summary

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

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

Seal Status

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

tests/tail.rs keeps both sides. AGENTS.md takes master's steps and adds this
branch's: 15220 plus 1202 and 8134, on master 1083135's 15191 plus 1202 and
8119. The ledger takes master's and re-applies this branch's rows: pass 924,
not_pass 35.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AGENTS.md takes master's and adds this branch's step: 15224 plus 1202 and
8149, on master 3d16be1's 15195 plus 1202 and 8134. The ledger takes
master's and re-applies this branch's rows: pass 926, not_pass 34.

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:20:48 UTC

Summary

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

These columns do not partition: 1 + 43 + 0 + 0 = 44, 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).

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

PR Dashboard

Generated at: 2026-10-08 20:45:16 UTC

Summary

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

These columns do not partition: 1 + 40 + 0 + 0 = 41, 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).

@gHashTag
gHashTag merged commit 824c82d into master Oct 8, 2026
33 of 34 checks passed
gHashTag pushed a commit that referenced this pull request Oct 8, 2026
lower.rs and tests/tail.rs merge cleanly. AGENTS.md takes master's and adds
this branch's step: 15227 plus 1202 and 8164, on master 824c82d's 15224
plus 1202 and 8149. The ledger takes master's and re-applies this branch's
rows: pass 931, not_pass 33.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag pushed a commit that referenced this pull request Oct 9, 2026
…27b-const-div (Closes #7812)

lower.rs and tests/tail.rs keep both sides. AGENTS.md takes master's and adds
this branch's step: 15235 plus 1233 and 8200, on master 4270760's 15232
plus 1233 and 8183. The ledger takes master's (no stored counts since #7862)
and re-applies this branch's rows; max_not_pass 31 -> 30.

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: _ = e; with e not a bare name, deleted or run as the reference does (collect_type_decls)

2 participants