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:
2026-05-12 01:31:35 +09:00
parent 1ac1d985f6
commit fa070b6d07
11 changed files with 260 additions and 33 deletions

View File

@@ -364,6 +364,7 @@ typedef enum {
TY_TUPLE,
TY_TAGGED, /* (T1 | T2 | ...) — Hare-style sum type */
TY_ERR,
TY_NEVER, /* bottom: assignable to anything; size 0 */
/* untyped constants (not surfaced to users; checker-internal) */
TY_UNTYPED_INT,
TY_UNTYPED_FLOAT,
@@ -408,6 +409,7 @@ extern Type *ty_u8, *ty_u16, *ty_u32, *ty_u64;
extern Type *ty_int, *ty_uint, *ty_uintptr;
extern Type *ty_f32, *ty_f64, *ty_str;
extern Type *ty_err;
extern Type *ty_never;
extern Type *ty_untyped_int, *ty_untyped_float, *ty_untyped_str;
extern Type *ty_untyped_rune, *ty_untyped_bool, *ty_untyped_nil;