wcc,ww: prepend synth use test; user fn run coexists with runner (M4 E2, #80)

The -T harness synthesized `use test;` after name-binding, so the lib/test runner run keyed the bare scope and collided with a user-defined bare fn run — a spurious "duplicate fn run" reject (the E1 tolerance seam). Prepending the synth use before binding keys the runner as test.run in the test module namespace, distinct from the user bare run; the two coexist. Hare-faithful: the runner is its own test module (ref/hare/test/+test.ha:97). Inverts attest_userrun.ww from the #23-mandated reject to a coexist fixture; gate asserts exactly 1 TEXT run + 1 TEXT test.run on the -T asm (distinct symbols, not a dead-dup). Closes #80.
This commit is contained in:
2026-06-17 23:54:21 +09:00
parent 08cfb5b2dd
commit 939c984f51
8 changed files with 308 additions and 112 deletions

View File

@@ -1,8 +1,16 @@
// #23 -T collision — a user `fn run` collides with lib/test's bound
// runner `run` (the synth's callee) once `ww test -c` bundles lib/test.
// Both stages must loud-reject "duplicate fn run" (rc!=0), never silently
// build a binary that calls the wrong run and skips every @test.
fn run() void = { return; };
// #80/#84 -T coexist — a user `fn run` COEXISTS with lib/test's bound
// runner `run` (the synth main's callee). Once `ww test -c` bundles
// lib/test, the synth `use test;` keys lib/test's `run` under module
// "test" (#80: prepended before binding) and the user's package-less
// `run` mangles to a DISTINCT bare `run` (#84) — no duplicate. Both
// stages accept under -T and the synth runner runs the @test to exit 0;
// the user `run` must NOT hijack the entry. Pre-#80 this loud-rejected
// "duplicate fn run". The gate (910/997 coexist_run) static-label-counts
// the -T asm — exactly 1 `TEXT run` (user, bare) + 1 `TEXT test.run` (lib
// runner) — pinning #84 distinctness here in the REAL @test/-T path (a
// dead-dup regression yields 0x run / 2x test.run). General callability of
// the bare run is gated separately by 989_barefn_collide.
fn run() i32 = { return 9; };
@test fn t_one() void = {
assert(1 == 1);