Repository navigation
Two compiler.rs tests assert absence over a region that can be empty by construction #5562
Description
Re-filed from #3245. An attempt claimed that issue on 2026-09-28 and left an empty branch, and a dispatch row that has spent its retry ceiling keeps its issue for good - so no bee could take it again, however much the brief improved. The work below is carried over unchanged.
Found by the same sweep as #3237, confirmed adversarially, not fixed here —
see "Why this is filed rather than patched" at the end.
Identify both by test NAME, not line number: bootstrap/src/compiler.rs was
being edited concurrently during the investigation and line numbers moved ~119
lines mid-read.
1. a_clocked_body_gets_no_return_guard
let clocked = v.split("always @(posedge").nth(1).unwrap_or("");
assert!(!clocked.contains("__t27_ret"), ...);
.unwrap_or("") degrades to the empty string whenever the key is absent,
and the empty region satisfies the negative assertion by construction. That
single assert! is the entire test body: nothing asserts clocked is
non-empty, nothing asserts the loop or the en arm is inside it.
No sibling anchor exists. fn on_clock appears as a test fixture exactly once
in compiler.rs — in this test. The
assert!(verilog.contains("always @(posedge clk)")) elsewhere belongs to
HirVerilogEmitter, a different emitter, not to gen_verilog_clocked_fn. The
only real anchor on this literal lives in another test binary
(bootstrap/tests/clocked_counter.rs) on a fixture with module-level var
state, so it does not constrain this test's region — and a maintainer who
changes the emitted literal gets no signal from here.
2. a_loop_outside_a_function_never_tests___t27_ret
Region is &v[v.rfind("endfunction")...]. Measured on the fixture with
target/release/t27c: output is 94 lines, last endfunction at 53,
initial begin : ..._test at 63, __t27_ret at 48–51 inside g (correctly
outside the region). The region is lines 53–94.
The subject sits inside it only because gen_verilog_module happens to emit
its functions section before its test-assertions section. Nothing in the test
asserts that ordering. No presence anchor exists in this test or anywhere in
the crate: grep -n 'initial begin :' returns only the two emitter sites; no
test asserts the lowered block exists.
Additionally the .expect("the fixture declares a function") on that rfind
cannot fire and does not check what its message says — __mul_noop is
unconditionally injected, so an endfunction is always present regardless of
whether the fixture declares a function.
The fix, in both cases
The rule from #3237: a negative assertion needs a positive anchor. Assert the
region is non-empty and contains the construct under test before asserting the
needle is absent. For #2, additionally anchor on the emitted block
(initial begin :) rather than relying on unstated section ordering.
Why this is filed rather than patched
bootstrap/src/compiler.rsis under the M5 freeze: any edit requires
bootstrap/stage0/FROZEN_HASHto be updated to
sha256(bootstrap/src/compiler.rs)in the same commit. That is a
deliberate, auditable change, not a drive-by test repair.- The file was being edited by another session while this was measured.
Touching it now invites a conflict on the one file where conflicts are most
expensive. - CI capacity: each push costs 28 check-runs and the queue stood at 224
during this pass (SKILL.md is the NOW.md problem again: 182 of 293 commits touch one 865 KB file, and every concurrent PR conflicts on it #3236). Both defects are latent — neither is failing
today — so nothing is lost by sequencing this behind the current batch.
Evidence above is reproducible without editing anything.
Boundary
bootstrap/src/compiler.rsbootstrap/tests/clocked_counter.rs
The instruments
Every one of these reads and prints; none of them writes. Run them from the repository root, with <spec> replaced by the file in ## Boundary:
.t27 is not Rust and not Zig, and a bee fluent in either writes one by
accident. Measured 2026-09-20: a bee filled eight bodies in
specs/file/watcher.t27 with return Ok(());, Err(FileError::WatcherNotFound)
and for i in 0..watchers.length. The parse ratchet refused the whole file --
Unexpected token in expression: RParen, line 123 -- and a spec that does not
parse generates nothing, so every test it already carried stopped running.
At the top level the parser accepts exactly these eight forms, with an optional
pub, and no others:
const var fn enum struct test invariant bench
There is no trait, no impl, no type X = ..., no generics, no macro. What
a bee reaches for from another language, and what happens:
- Rust's result sugar (
Ok(()),Err(E::V),?) is not a construct here. - Rust macros (
println!,format!,vec!) are not constructs here. - A range loop (
for i in 0..n) is Rust and Zig, not this language. - Zig builtins (
catch unreachable,@intCast,@constCast) are not constructs here. - Cross-module reuse (
use other::fn;) parses and then generates a comment and an unqualified call, so the Zig fails withuse of undeclared identifier(use a::b; generates no import, so no spec can reuse a function from another spec #4298). It does not work yet.
t27c parse <spec> answers in one line whether what you wrote is the language.
Run it before you report, every time.
t27c spec-status <spec>- the compiler's one-word verdict: IMPLEMENTED, PARTIAL, UNWRITTEN, NOPARSE, NOFN. Exit code is 0 whatever it says, so read the word.t27c symbols <spec>- every name the file declares, with its kind. Answers "does this already exist here?" before you add it.t27c outline <spec>- per function: its locals, what it calls, what it returns. The contract you are implementing against.t27c coverage <spec>- which functions have a test and which do not. The issue asks for tests; this is how you check you wrote them.t27c lint <spec>- style and shape warnings. It OVER-REPORTShas no test or invariant: measured 2026-09-20 over 60 specs it printed 677 of those wherecoveragefound 190 untested functions, disagreeing on 59 of the 60 - it warns aboutbit_to_trit_pairinspecs/base/ternary_encoding.t27, whichtest bit_to_trit_pair_zerocalls on line 249. Read it as a hint;coverageis the answer.t27c typecheck <spec>- types, before generation. PrintsTypecheck OK (0 errors, 0 warnings)or the errors.t27c test-report <spec>- builds this spec and runs its own tests, which is what the oracle does.BLOCKEDmeans the generated Zig does not compile, with the error beside it.python3 tools/dupe_scan.py --name <function>- where that function already lives, if it does. 576 of 4021 bodies here are byte-identical copies.
The rest of the toolbelt is in docs/BEE_TOOLBELT.md.
User Scenarios
- Given the test
a_clocked_body_gets_no_return_guardinbootstrap/src/compiler.rs, When the search key"always @(posedge"is absent from the generated Verilog, Then the region degrades to an empty string and the negative assertionassert!(!clocked.contains("__t27_ret"))passes vacuously without verifying the clocked body exists. - Given the test
a_loop_outside_a_function_never_tests___t27_retinbootstrap/src/compiler.rs, When the emitter changes section ordering so thatinitial begin :test assertions appear before the functions section, Then the region from the lastendfunctionto end of output no longer contains the test block and the negative assertion passes without exercising the intended code path.
Requirements
- FR-001: The test
a_clocked_body_gets_no_return_guardMUST assert that the clocked region is non-empty and contains the expectedalways @(posedge clk)construct before asserting__t27_retis absent. - FR-002: The test
a_loop_outside_a_function_never_tests___t27_retMUST anchor the search region on the emittedinitial begin :test block (presence anchor) rather than relying on unstated section ordering, and MUST assert that region is non-empty before asserting__t27_retis absent. - FR-003: Any edit to
bootstrap/src/compiler.rsMUST updatebootstrap/stage0/FROZEN_HASHtosha256(bootstrap/src/compiler.rs)in the same commit.
Success Criteria
cargo test -p bootstrap a_clocked_body_gets_no_return_guardexits 0 and the test body contains a positive anchor asserting the clocked region is non-empty and contains"always @(posedge clk)"before the negative assertion on__t27_ret.cargo test -p bootstrap a_loop_outside_a_function_never_tests___t27_retexits 0 and the test body anchors oninitial begin :presence, asserts that region is non-empty, then asserts__t27_retis absent.sha256sum bootstrap/src/compiler.rsmatches the value stored inbootstrap/stage0/FROZEN_HASH(exit 0 from verification script).cargo test -p bootstrapexits 0 (all compiler tests pass).
Activity
dmitrii-f-t27 commentedon Oct 3, 2026
On master f88f759 both tests already carry the positive anchor this issue asks for:
a_clocked_body_gets_no_return_guardassertsalways @(posedgeis present (bootstrap/src/compiler.rs:44294), anda_loop_outside_a_function_never_tests___t27_retassertsinitial beginis emitted and sits after the lastendfunction(compiler.rs:44345-44358). Both landed in 7b335cb (#3317, 2026-09-06), before this re-file. Suggest closing as fixed.Checked with t27c 0.4.0 built from f88f759; commands and inputs available on request.