wwstage: expand spread variants in match check + size them off flattened members (#209)

The wwstage checker walked a match's raw AST variant list and never expanded a ...inner spread variant, so it rejected fmt's match over field = (...formattable | *mods) ('not a variant of scrutinee'). cstage's resolve_type flattens the spread at type-build. Mirror that in the AST exhaustiveness walk (casevariantin + a recursive checkvariantcovered): when a variant resolves to N_TTAGGED via a spread, recurse into its members. Additive + spread-gated -- typeeqast / casevariantpairmatch (#13) / casecovers untouched, so non-spread matches and 990-997 byte-id are unaffected. Also size a spread N_TTAGGED off each flattened member (mirror cstage check.c), dropping the inner union tag word (field 40B to 32B). Closes the #209 CHECKER reject; full fmt-byte-id still awaits cgen cluster #226 (io.read nominal-remap) + #227 (spread-widen ABI), so fmt tests stay cstage-only with retargeted comments. Adds test 792; regenerates w6c/wwdump combined.ww.
This commit is contained in:
2026-05-31 20:31:40 +09:00
parent 497f1fa0d3
commit 3d44f742a0
10 changed files with 471 additions and 113 deletions

View File

@@ -33,13 +33,13 @@
* | io.close. Asserts the owned str bytes, then
* | frees via os.free.
*
* Cstage-only per row (no STAGE_WW, no byte_id) — pre-existing wwstage
* bug #209 (sibling of #190): the wwstage checker bails `case: not a
* variant of scrutinee (X)` + `match: variant not handled
* (formattable)` on fmt.formattable match-arms whenever a downstream
* probe `import fmt;`s the package. Identical carve-out to
* 777_fmt_handle_run + 780_fmt_mods_run. Byte-id graduates with #209
* close.
* Cstage-only per row (no STAGE_WW, no byte_id). #209 (the wwstage
* checker bail `case: not a variant of scrutinee` + `match: variant not
* handled (formattable)` on fmt's spread-union match-arms) is now CLOSED;
* wwstage compiles fmt. The residual blocker is the pre-existing cgen
* cluster #226 (io.read error-remap nominal-identity) + #227 (spread-union
* widen/return-ABI). Identical carve-out to 777_fmt_handle_run +
* 780_fmt_mods_run. Byte-id graduates when #226 (+#227) land.
*
* IMPORT-ORDER WORKAROUND (sibling task #208, pre-existing): every row
* places `import os;` FIRST for the same reason 776/777/780 document
@@ -48,8 +48,10 @@
*
* DEFERRALS / RELATED (NOT addressed by these rows):
*
* - #209 (wwstage formattable match-arm bail): blocks STAGE_WW here,
* same as 777/780. Cstage-only until close.
* - #226 (io.read error-remap nominal-identity) + #227 (spread-union
* widen/return-ABI): block STAGE_WW here, same as 777/780. #209 (the
* checker bail) is closed; these cgen folds are the residual.
* Cstage-only until they land.
* - #173 (TRY-on-tagged-return both-stages broken): bsprintf widens
* nomem into io.error inline rather than `memio.fixed(buf)?` for
* the same reason memio.ww does.