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:
8
test/wcc/data/wwispread/liba/lib.ww
Normal file
8
test/wcc/data/wwispread/liba/lib.ww
Normal file
@@ -0,0 +1,8 @@
|
||||
package liba;
|
||||
|
||||
// `outer` spreads the named alias `inner` (a 2-arm union). The `...` marker
|
||||
// must survive serialization to liba.wwi so a consumer flattens inner's arms
|
||||
// into outer (#95). Without it, outer reads back as (inner | str) and a bare
|
||||
// i32/i64 is not assignable.
|
||||
export type inner = (i32 | i64);
|
||||
export type outer = (...inner | str);
|
||||
13
test/wcc/data/wwispread/main.ww
Normal file
13
test/wcc/data/wwispread/main.ww
Normal file
@@ -0,0 +1,13 @@
|
||||
package main;
|
||||
|
||||
import liba;
|
||||
|
||||
// Each assignment binds a BARE member of inner (i32, i64) or the outer-direct
|
||||
// arm (str) to liba.outer — typechecks ONLY if the spread flattened inner's
|
||||
// arms into outer across the liba.wwi round-trip (#95).
|
||||
export fn main() void = {
|
||||
let x: liba.outer = 42i32;
|
||||
x = 99i64;
|
||||
x = "hi";
|
||||
return;
|
||||
};
|
||||
6
test/wcc/data/wwispread3/libb/lib.ww
Normal file
6
test/wcc/data/wwispread3/libb/lib.ww
Normal file
@@ -0,0 +1,6 @@
|
||||
package libb;
|
||||
|
||||
// 3-arm spread: proves ALL of three's arms (i32, i64, rune) flatten into
|
||||
// wide, not just the first (#95).
|
||||
export type three = (i32 | i64 | rune);
|
||||
export type wide = (...three | str);
|
||||
13
test/wcc/data/wwispread3/main.ww
Normal file
13
test/wcc/data/wwispread3/main.ww
Normal file
@@ -0,0 +1,13 @@
|
||||
package main;
|
||||
|
||||
import libb;
|
||||
|
||||
// Bind each of three's arms (i32, i64, rune) plus the str arm to libb.wide:
|
||||
// typechecks ONLY if all three flattened across the libb.wwi round-trip (#95).
|
||||
export fn main() void = {
|
||||
let a: libb.wide = 1i32;
|
||||
a = 2i64;
|
||||
a = 9i32: rune;
|
||||
a = "z";
|
||||
return;
|
||||
};
|
||||
Reference in New Issue
Block a user