Files
ww/test/wcc/data/match_yield_in_switch/case.ww
Hojun-Cho 411515a83b wcc: checker-seam drain — spreads, tuple aliases, yield scoping
Four seams from one review cluster, all landing on the same checker
files; gates ran on the union (rule 11 body).

?-subset: the wwstage walk compared `...spread` ALIAS nodes on both
sides of the error-subset check, falsely rejecting a spread-carried
error return (`(i64 | ...errs)`, cs-accept/ww-reject) — both sides
now flatten like trycountvariants (cstage Tparams are pre-flattened
at type level).

Multi-let/multi-assign: the tuple gates keyed on the RAW rhs kind,
rejecting a NAMED tuple alias (`type pair = (i64,i64)`; cs clean-
reject, ww asserttyped stop) — both stages chase per #99 alias
transparency, wwstage rettupleof peels the alias so cgmassign keeps
the str element's len/cap stores, and the catA massign-alias error
pin re-rules to a run fixture. The N_MLET diagnostic also printed
its operands swapped (elem/declared reversed vs its wording).

Yield: match_yield_type didn't descend into N_SWITCH, so a yield
inside a switch arm typed the match void and dropped the value
(both stages); and a stray yield outside any match arm reached cgen
unchecked — both stages now gate on a match-arm counter (the
c->loops discipline).
2026-08-09 01:51:39 +09:00

22 lines
491 B
Plaintext

//ww:run-exit 0
// A yield inside a switch arm yields from the enclosing MATCH; the
// match-yield walk didn't descend into N_SWITCH, so the match typed
// void and the yielded value was dropped.
package main;
fn pick(v: (i32 | str)) i32 = {
let r: i32 = match (v) {
case let x: i32 =>
switch (x) {
case 2: yield 42;
case: yield 7;
};
case let s: str => yield 0;
};
return r;
};
export fn main() i32 = {
let u: (i32 | str) = 2;
if (pick(u) == 42) { return 0; };
return 1;
};