w6c,ww: re-emit ... union-spread marker in .wwi producer (M4 E3, #95)

The N_TTAGGED serializer emitted each variant via wwi_type but never
re-emitted the `...` prefix for TK_ELLIPSIS spread variants, so an
exported `(...inner | str)` round-tripped through .wwi as `(inner | str)`.
The consumer's checker then could not flatten inner's members into the
alias and variadic-assignability rejected bare members — under separate
compilation this broke fmt/log/getopt. Re-emit `...` before the variant
type, both stages; the producer stays purely syntactic (flatten/dedup
remain the consumer's type-store job, per ref/hare/hare/unparse/type.ha:290-300).

Gate: test/wcc/989_wwispread_sep.c — table-driven (2-arm + 3-arm spreads)
x both stages, asserts the marker survives the .wwi, the consumer binds
bare members under --sep (exit 0), and cs==ww .wwi byte-identity.
This commit is contained in:
2026-06-18 09:52:19 +09:00
parent f4d809dc79
commit 24ca570a7e
9 changed files with 244 additions and 1 deletions

View File

@@ -272,6 +272,11 @@ wwi_type(FILE *of, Node *t)
fputc('(', of);
for (Node *e = t->list; e; e = e->next) {
if (e != t->list) fputs(" | ", of);
/* #95: re-emit the spread marker purely syntactically;
* the consumer's type-store flattens (ref/hare/hare/
* unparse/type.ha:290-300). */
if (e->op == TK_ELLIPSIS)
fputs("...", of);
wwi_type(of, e);
}
fputc(')', of);