wcc: tagged-union foundations (never, void, flatten, exhaust)
- `never` bottom type: TY_NEVER, assignable to anything; size 0.
- Type-set normalization for N_TTAGGED in resolve_type:
- flatten nested anonymous (A|B)|C → (A|B|C); named aliases stay
nominal (not flattened through)
- dedup duplicates (NAMED pointer-id; others structural)
- drop `never` variants
- collapse single-element set: (T|never) → T, (T|T) → T
- Match exhaustiveness: error when a variant is unhandled and no
default arm covers it. Multi-pattern `case T1 | T2 =>` counts
each alt.
- (T | void) optionals: bare `return;` from a tagged-union-returning
fn emits the void variant's tag (payload undefined; void size 0).
selfhost mirrored: TY_NEVER constant + tynever in tctx + seedprim
entry; voidvariantindex helper; cgreturn bare-return handling.
This commit is contained in:
@@ -105,6 +105,25 @@ static const struct row rows[] = {
|
||||
{ "fn f(a: i32) i32 = { return a; }; fn g() i32 = { return f(); };",
|
||||
"not enough arguments" },
|
||||
{ "fn f() void = { if (1) { }; };", "if condition" },
|
||||
|
||||
/* tagged-union normalization & exhaustiveness */
|
||||
{ "fn f() (i32 | never) = { return 7; }; "
|
||||
"fn g() i32 = { return f(); };", "ok" }, /* (T|never) → T */
|
||||
{ "fn f() (i32 | i32) = { return 5; }; "
|
||||
"fn g() i32 = { return f(); };", "ok" }, /* dedup → i32 */
|
||||
{ "fn f() (i32 | void) = { return; };", "ok" }, /* bare return → void variant */
|
||||
{ "fn f(b: bool) (i32 | void) = { if (b) { return 1; }; return; };",
|
||||
"ok" },
|
||||
{ "fn f() (i32 | str | bool) = { return 1; }; "
|
||||
"fn g() void = { let v: (i32 | str | bool) = f(); "
|
||||
"match (v) { case let x: i32 => { }; case let x: str => { }; }; };",
|
||||
"variant bool not handled" },
|
||||
{ "fn f() (i32 | str | bool) = { return 1; }; "
|
||||
"fn g() void = { let v: (i32 | str | bool) = f(); "
|
||||
"match (v) { case let x: i32 => { }; case => { }; }; };",
|
||||
"ok" }, /* default arm absorbs missing variants */
|
||||
{ "fn die() never = { for (true) { let _: i32 = 1; }; }; "
|
||||
"fn f() i32 = { die(); };", "ok" }, /* never assignable to anything */
|
||||
};
|
||||
|
||||
int
|
||||
|
||||
Reference in New Issue
Block a user