pushargsrev's five aistagged gates (N_IDENT #55, N_CALL #21, N_INDEX
#12, N_DOT #22a, deref #35) treated a tagged arg as already-tagged
when its SLOT SIZE matched the param's. A same-slot subset union
((bool|void) into (i64|bool|void), both 16B) then natural-pushed the
narrower box's words carrying SOURCE tags — no re-layout, no
cg_widen_tag_remap twin — so the callee matched the wrong arm
(silent: probes exited 10/90 where cstage exits 30/27). cstage keys
widen detection on type equality (cgen.c:10000 same = (pu == au) ||
type_eq) and routes every non-same tagged source through the zeroed
scratch + tag remap; the slot-DIFFER wwstage path already mirrored
that byte-identically, so the fix computes cstage's same check once
(wsame) and replaces each slot-size test with it. This also erases
the last known cs!=ww shape divergence (the 16B-local staging vs
direct-push frame delta on prefix subsets).
8 subsetwiden_* fixtures own the class: call-result/ident/str-payload
/mid-arg remap (the wrong-arm shapes), prefix (the shape-divergence
repro), and bigslot/return-pos/struct-24-to-32 sibling guards. Corpus
pin 1740/343/22/209/1166/3480.
`case T1 | T2 =>` (binding-less; cstage parse.c:635-650 chains extra
types through cs->list, bindings stay single-type by design). Three
wwstage layers, no AST change (node.list already exists):
- parser (expr.ww): pipe loop after the non-let arm's first
parsetype;
- checker (check.ww): resolvewalk N_MCASE now walks n.list so each
alt gets its type_ stamp (exhaustiveness/casecovers were already
alt-aware, built ahead of the parser);
- cgen (cgenexpr.ww): the single-pattern want-computation moves
VERBATIM into matcharmwant; a cs.list arm emits CMPQ/JE per alt
funneling into one match_body label, mirroring cgen.c:11118-11141
incl. label mint order and the tag<0 clamp. Nullable arms keep
ignoring alts (both stages).
Graduates the held e2e row (pin 1732/1158/3464); byte-identical on
the repro and the single-pattern control.
cstage parse.c:1027 accepts `for ()` — N_FOR with a nil cond, no
for-else arm, no test emitted (an unconditional loop; a deliberate
Go-flavored ww divergence from Hare, original to the toolchain
import). The wwstage parser had no RPAREN early-out and rejected it.
Selfhost checker and cgen already nil-guard n.cond, so the parser arm
is the whole gap. Graduates the held e2e row (pin 1731/1157/3462).
Adjacent asymmetries left filed, not fixed here (rule 11): the brace
form `for { }`, the empty middle clause of the 3-clause form, and
the REVERSE case (wwstage accepts 2-clause `for (cond; post)` which
cstage rejects).
wwstage dotchainresolve gated its *T roots on an N_TPTR-over-N_TNAME
tnode; an inferred `let p = alloc(S{...})!` rides the checker-
SYNTHESIZED N_TPTR whose pointee is the struct BODY node (the #24
TNAME-normalize covers only the direct struct-lit binding), so the
root gate failed and chained p.field.pseudo reads fell to the
unfused deref arms — shape-only divergence vs cstage's type-keyed
fold (both stages runtime-correct; the historical field(SB) leak the
pin described was already fixed). Widen the local and global root
gates to accept the N_TSTRUCT pointee; correctness stays enforced by
the stamped-tinfo peel below (TY_PTR -> pointee TY_STRUCT).
Graduates alias_g73_heapfill out of DATABYTEID_DIVERGED (2 pins
remain, both the tagged-spill family); adds compile fixtures pinning
the newly-converged siblings (nested read+store, slice .cap,
inferred-global root; pin 1730/22/3460) and a runtime lang row that
mutates then re-points the heap base — a read bypassing the pointer
returns the wrong len.
The last bug-pinned C carrier. Its header documents both #55 halves;
with the cgen side fixed the STRONGER assertion set it deferred is
expressible: barevalue builds the 794 two-file program FLAT
(file-keyed import — a dir-keyed aa/ compiles aa as its own sep unit
where main.v is invisible and the collision cannot express), runs
exit 7 on BOTH drivers, and asserts the flat __root.s cs==ww
byte-identical (rule 10). defshadow pins the def-vs-fn arm-order
corner (foreign scalar def under a curmod fn: bare read 42, not
141), modqualfnval the qualified fn-value positive twin.
Carrier fleet 16 -> 15: 5 units / 6 bootstrap / 3 platform /
738_module_decl. Zero bug-pins remain.
The #173 remap loop in cgtryprop gated on the tparam's explicit `!`
flag only; a LEGACY union (no marks anywhere) classifies error
variants POSITIONALLY (index 0 is success, cstage cg_variant_is_error
cgen.c:905) — so wwstage emitted no remap and propagated the callee's
raw tag into a differently-ordered caller union, a silent wrong arm
(cstage exit 7, wwstage 9 on the banked r700 row). Add the
variantiserror twin and gate the loop on it; refresh the drifted
cstage cite.
Graduates the held e2e row into the corpus (pin 1727/1156/3454) and
adds legacy-mode rows to test/lang/tryprop_tag_remap_test.ww:
reversed order both directions, slot-0 remap, str payload integrity,
a two-hop chain whose pre-fix runtime pass was double-miss tag
cancellation (the lang byteid leg pins the emitted remap blocks),
and a same-order zero-emission control.
test/libenv/libenv_test.ww owns the env-arranged legs of the lib/os
getenv and lib/dirs XDG suites (rows asserted ok, not SKIP, plus the
created-chain layout), the dirs too-long abort on both stages, and the
make-owned runner for the self-arranged stat suite. Wired beside the
sep observers under test-compiler.
The three must-abort runs (u32n/u64n zero, decodedsize unaligned) move
into the owning lib suites as test.expectabort rows; the five
normal-return controls already live in the r989_libprecond_* fixtures.
wwstage parity rides the lib-wide cs==ww byte identity gate.
Each row builds regfile/symlink/subdir under temp.dir (Hare's os-test
idiom) and asserts exact cleanup, so the suite passes bare and the
carrier's env+tree arrangement job disappears. Every carrier assertion
maps to an in-test row.
Strengthens the pre-symmetry-era cstage-only stdout scrape to both
frontends with gated exits and the rule-10 cs==ww byte-id; the libc
binding smoke likewise runs both stages.
One commit for both carriers: the asserttyped manifest and the -c/-r
parse-error gate are the same wwstage-only wwdump_ww subprocess
surface. The 901_*.ww raw gap companions stay in test/wcc, fed via
testenv.repo().
One commit for both carriers: flag-misuse parity and the
missing-package fatal are the same driver-CLI subprocess surface. The
-V oracle parses WW_VERSION out of cmd/wcc/ww.h at run time; the
missingpkg ww_ww twin stays owned by bootstrap carrier 993_ww_ww.c.
Ports 708_param_shadow_mod, 712_redecl and 961_opaque_guards into
test/tool/rejects_test.ww on testenv, one commit because the three
carriers share the single asymmetric-polarity claim (cstage rejects,
wwstage accepts) that a both-stage //ww:error fixture cannot carry.
The neg_selfimp leg drops: test/wcc/data/r948_selfimport/case.ww owns
the identical both-frontend claim.
The unowned remainder is the four run-stderr assertions — msg content
for fail_msg/abort_msg, MANDATORY EMPTINESS for fail_nomsg/abort_bare
(rt_abort(NULL,0) writes nothing) — which the fixture protocol cannot
see (run exit only). The rows build the r957_* fixture sources in
place via the cstage driver; byte-id extends the lowering to wwstage
(the carrier's own argument). Owned legs cited, not duplicated: all
eight exit rows by the r957_assert_*/r957_abort_* fixtures, the
checker rejects by r957_assert_reject_*, byte-id by the
test-data-byteid blanket.
Only the ast_proof leg was unowned: wwdump -a / wwdump_ww -a dump
byte-id plus the ordered dot-over-structlit-over-tname node shape for
a trailing op on a qualified struct literal (inexpressible as a
runtime scenario while the #77 literal-temporary cgen gap holds; the
multilevel row pins the source-order a.b.C tname flatten). The three
build/run scenarios are owned by the r84_qualstruct_* fixtures plus
the test-data-byteid blanket — their vestigial want_exit fields were
already dead in the carrier.
954_tuprecv_run, 956_tuprecv_f64_run and 956_modqualdestr_run shared
one retained dimension: w6c_ww compiles the destructure shape cleanly
AND emits no asserttyped stderr diagnostic (#121 A-narrow / #6a-A
stamp nets) — a channel neither test/lang nor the fixture protocol
has. All 11 rows fold into one observer with the drew-C4 non-vacuity
self-check on the shared predicate. Owned legs cited, not duplicated:
value rows + byte-id ride test/lang/tuprecv_test.ww,
test/lang/tuprecv_f64_test.ww and the test-lang-byteid blanket; the
modqual values + byte-id ride the r956_modqual_* fixtures and
test-data-byteid — those four rows compile the fixture files in place
so probe and fixture cannot drift. Bundled: one file, one concern
(the wwstage stamp-absence dimension).
826_alias_tuple_coerce, 944_alias_accept_run and
944_variant_chain_b95_run all reduced to the same irreducible shape: a
LIVE per-stage asymmetry (probed at HEAD) no symmetric fixture or
@test can host. Ported under the DIVERGE discipline — both sides
asserted loud (826 neg_0: cstage "not assignable to declared pair"
vs wwstage over-accept; #96: cstage runs vs w6c_ww "unsupported
address-of shape"; #277: cstage runs vs ww_ww "deferred #277"), so
a fix on either side fails the row and demands graduation. Owned legs
cited, not duplicated: r826_alias_tuple_* byte rows ride
test-data-byteid, 826's neg_1 went symmetric at HEAD and moves to a
//ww:error fixture per the audit split, the 944 value/reject corpora
live in test/lang/{alias_accept,variant_chain_b95}_test.ww and the
alias_*/vchain_* fixtures. Bundled: one file, one concern (held
divergence pins).
Both carriers were already slim: the r76_def_widen_* byte-id legs are
owned by the test-data-byteid blanket, 783's positive byte rows by the
r78_amp_fn_assign_* fixtures plus that same blanket, and its symmetric
non-tagged rejects by the corpus //ww:error fixtures. The unowned
remainder is three cstage-only loud-rejects (the 760 narrowing def-ref
and 783's two tagged-slot rows); the wwstage over-accepts (no def-init
assignability check; #214 void-variant leniency) are documented at the
site per the residual audit, never asserted as desired — the rows
graduate to //ww:error fixtures when the wwstage side tightens.
Bundled: one file, one concern (cstage-reject pins awaiting wwstage
graduation).
wwiroundtrip pins the @packed re-emit through a real -I tree on both
driver stages (importer-side layout exit 91), strengthened with the
`struct @packed {` needle in the retained sepwork pk2.wwi (a
single-file two-package form emits no .wwi, so the tree is
irreducible). identityreject pins the stage asymmetry as a DIVERGE
row: cstage rejects with "not assignable" (packed is type identity,
harec types.c:621), wwstage builds+runs through the documented
#224/#10 nominal-lossy leniency; a wwstage tighten fails the row and
demands graduation to a //ww:error fixture. The 15 layout/runtime
value rows are fixture-shaped and move to the declarative corpus per
the residual audit port split.
test/misc hosts the residual mixed-shape observers (divergence pins,
stamp/stderr probes, .wwi trees) on testenv, wired into test-compiler
beside the sep/xmod/asm families; its rule declares both full
per-stage toolchains plus the wwdump twins for the coming files.
The 689 port keeps the both-driver run-exit-6 backstop and the
per-stage absolute DATAW row count (linker dedup and byte-id sweeps
are both blind to a symmetric double-emit).
The 18 active rows keep compile + cs==ws byte-id and the tab-anchored
ADDQ $N,SP cleanup markers with both polarities (mem-class rows must
contain their slot's cleanup; the exactly-48B boundary row must not).
The per-row driver build+run legs (incl. the uninit-global zero-box
exit 91) move to the r929 run fixture corpus per the residual audit
port split; the four buildfail rows were already dead here, owned by
the r929_memarg_reject_* fixtures.
The 13 active rows keep compile + cs==ws byte-id and the hidden-RDI
"(BP), DI" presence/absence polarity (present iff sret-class; the two
exactly-32B boundary rows must stay register). The per-row driver
build+run legs move to the r926 run fixture corpus per the residual
audit port split; the seven buildfail rows were already dead here,
owned by the r926_sret_reject_* fixtures.
The five symmetric rows compile their r764_amp_fn_ident_* fixture
sources in place (runtime owned by those fixtures; pre-fix junk-store
still exits 0, so the LEAQ window is the discriminator) and keep the
cs==ws byte-id leg. The cross-module row stays cstage-only pending
#184; its wwstage/byte-id legs graduate with that task.
asmgate_test.ww absorbs 530_w6a_parsenum and 989_datargate_run: the
strtoll-semantics identity rows plus the bare-minus reject against
both assemblers with cross-stage .o byte-identity, and the undefined
DATAR-slot loud reject (no .o written) with the defined-slot
byte-identical ok path. The w6a_ww skip gates drop: the Make target
declares both assemblers.
archive_test.ww absorbs 610_arch and 632_w6l_manyflags: archive
member selectivity through a load-bearing undefined @symbol extern
(link exit 0, run exit 7), and the -L capacity table {1,64,65,100,
128} against both w6l and w6l_ww with an ET_EXEC check per leg. ar is
/usr/bin/ar via runcommand; the junk -L flags are real argv entries
instead of a 16KB shell string.
link_test.ww absorbs 600_w6l and 620_data_link: ET_EXEC on the
trivial pipeline, writable-global read/write runs, the exact
two-PT_LOAD R+X/R+W split, the single-PT_LOAD no-DATAW invariant 992
depends on, and the BSS filesz trim (filesz 1 < memsz 32, loader
zero-fill). Strengthened: the ldd staticness proxy is replaced by a
direct no-PT_INTERP phdr scan.
elfobj_test.ww (test/object, on testenv) absorbs 500_w6a, 510_dataw,
and 520_datar: ELF64 header magic/class over the 4 inline programs,
DATAW section/symbol layout plus the 6-section no-DATAW legacy
invariant 991 depends on, and the DATAR .rela.data reloc through
link and run. Strengthened: the reloc symbol is resolved to
'greeting' (declared but never implemented in the C carrier).
728 -> test/asm/matchdispatch_test.ww. The distinct-CMPQ-tag
collection window over TEXT b.next preserved on both stages.
Strengthened: per-row byte-id legs added -- the C header claimed a
cmp -s its code never ran; all three rows verify green.
719/724/744/746 -> test/asm/dataemit_test.ww. Exact DATAW payload
needles, the produce-window zero-init and MOVQ-load count floors,
and the strdef inline-pair want/anti windows preserved with their
per-row byte-id legs.
720/723/727/743 -> test/asm/callarg_test.ww. Ordered PUSHQ windows,
tag-synth + stack-overflow-cleanup needles and the variadic
eightbyte store-count floors preserved. Strengthened: 720's
4-variant row gains the byte-id leg the C skipped behind the
then-open #22 zero-init gate — #22 landed (724 pins the fix), and
the leg verifies green on both stages.
718/721/730 -> test/asm/sret_test.ww. Frame-size and max--K(BP)
stomp sentinels, line-adjacency sret triangle (hidden-RDI, return-
the-pointer, no-AX-capture, forwarding reload) and narrow-trailing-
field windows preserved, including 718's #15 byte-id gate on the
three-return row. 718's whole-suite ww_ww-executable gate dropped
with the other skip gates (the Make target declares the tools).
726/731/732/733/734/735/745/747 -> test/asm/modshadow_test.ww, one
@test per carrier, every want/anti window, occurrence floor and
byte-id leg preserved. New ASM_WW_TESTS block runs the test/asm
observers under test-compiler beside the residual carriers.
test/xmod/typecheck_test.ww replaces 989_callarg_typecheck.c and
989_tagged_subset_reject.c. Preserved: both -T __wwtests reservation
faces (both stages, diagnostic required), the shape-mismatch collision
(both stages), the cstage-only same-shape #37 pin, and both tagged
leaf-bridge xmod rows. Not ported, owned elsewhere per the audit: the
carriers' twelve ordinary call-arg rows (r989_callarg_* fixtures) and
the three w6c-vs-w6c_ww byte-id rows (test-data-byteid over
r989_tagsubset_{flatten_subset,slice_subset,nested_wrap}).
test/xmod/label_test.ww replaces 706_fnlabel_mangle.c and
750_mklabel_modscoped.c with every assertion preserved (fnlabelmangle
fixture run-112 both stages; three mklabel rows with run exits and
module-qualified label needles). Strengthened: fnlabel adds the
cs==ww sepwork .s byte-id the carrier never asserted.
test/xmod/m1_test.ww replaces 989_m1mangle_run.c and
989_m1usehint_run.c with every assertion preserved (5 tree rows +
2 usehint rows, both stages, plus the leaf_collision byte-id leg;
concat order strengthened from shell glob to byte-sorted listdir).
test/xmod/collide_test.ww replaces 989_fnptrcollide_run.c and
989_barefn_collide_run.c with every assertion preserved (build-reject
both stages; run-exit 9 + exactly-one TEXT main.run/aa.run + cs==ww).
Makefile grows the XMOD_WW_TESTS block mirroring SEP_WW_TESTS, wired
into test-compiler.
944_alias_cgen_b5_run.c -> alias_g73_heapfill (//ww:compile), joining
its migrated alias_* siblings. The carrier's stated fixture blocker
('//ww:compile links') is stale: the COMPILE cell runs the bare
frontend, no link. The live #24 field(SB) deref-read leak enters
DATABYTEID_DIVERGED, upgrading the carrier's silent byte-id waiver
with a graduation tripwire.
839_xmod_nominal_typeeqast.c -> r839_xmod_nominal_match (run-exit 42),
r839_xmod_a6_concrete (run), r839_xmod_incompat_concrete (error
'not assignable'), r839_xmod_distinct_alias (error 'ambiguous
without nominal layout').
r839_xmod_nominal_match enters DATABYTEID_DIVERGED: the carrier waived
byte-id for the pre-existing cross-module tagged-return spill
divergence; the DIVERGED row makes it loud-on-fix instead. The
typeeqast-layer discriminator itself stays with the lib byteid gate
(test/byteid/libbyteid_test.ww), as the carrier documented.