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).
This commit is contained in:
21
test/wcc/data/match_yield_in_switch/case.ww
Normal file
21
test/wcc/data/match_yield_in_switch/case.ww
Normal file
@@ -0,0 +1,21 @@
|
||||
//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;
|
||||
};
|
||||
12
test/wcc/data/mlet_tuple_alias/case.ww
Normal file
12
test/wcc/data/mlet_tuple_alias/case.ww
Normal file
@@ -0,0 +1,12 @@
|
||||
//ww:run-exit 0
|
||||
// #99 alias transparency at multi-let: a NAMED tuple alias rhs
|
||||
// destructures like its base (was cs-reject "not a tuple" + ww
|
||||
// asserttyped stop on unstamped binds).
|
||||
package main;
|
||||
type pair = (i64, i64);
|
||||
fn mk() pair = { return (3, 4); };
|
||||
export fn main() i32 = {
|
||||
let (a, b) = mk();
|
||||
if (a + b == 7) { return 0; };
|
||||
return 1;
|
||||
};
|
||||
@@ -1,5 +1,16 @@
|
||||
//ww:error "multi-assign rhs is not a tuple"
|
||||
//ww:run-exit 0
|
||||
// #99 alias transparency at multi-assign (re-ruled from the catA
|
||||
// error pin): a NAMED tuple alias return destructures like its base;
|
||||
// rettupleof peels the alias so the str element keeps len/cap.
|
||||
package main;
|
||||
type pair = (i64, str);
|
||||
fn f() pair = { return (7i64, "hey"); };
|
||||
export fn main() i32 = { let a: i64 = 0i64; let s: str = ""; a, s = f(); return 0; };
|
||||
export fn main() i32 = {
|
||||
let a: i64 = 0i64;
|
||||
let s: str = "";
|
||||
a, s = f();
|
||||
if (a != 7i64) { return 1; };
|
||||
if (s.len != 3) { return 2; };
|
||||
if (s[0] != 'h': u8) { return 3; };
|
||||
return 0;
|
||||
};
|
||||
|
||||
21
test/wcc/data/tryprop_spread_return/case.ww
Normal file
21
test/wcc/data/tryprop_spread_return/case.ww
Normal file
@@ -0,0 +1,21 @@
|
||||
//ww:run-exit 0
|
||||
// ?-subset walk flattens ...spread members on BOTH sides; the raw
|
||||
// AST walk compared the spread alias node and falsely rejected this
|
||||
// (ww-only; cstage Tparams are pre-flattened at type level).
|
||||
package main;
|
||||
type ea = !i32;
|
||||
type eb = !i64;
|
||||
type errs = (ea | eb);
|
||||
fn inner(sel: i32) (i64 | ea | eb) = {
|
||||
if (sel == 0) { return 7i64; };
|
||||
return 5: ea;
|
||||
};
|
||||
fn outer() (i64 | ...errs) = {
|
||||
let v: i64 = inner(1)?;
|
||||
return v;
|
||||
};
|
||||
export fn main() i32 = {
|
||||
let r: (i64 | ...errs) = outer();
|
||||
if (r is ea) { return 0; };
|
||||
return 1;
|
||||
};
|
||||
8
test/wcc/data/yield_outside_match/case.ww
Normal file
8
test/wcc/data/yield_outside_match/case.ww
Normal file
@@ -0,0 +1,8 @@
|
||||
//ww:error "yield outside match"
|
||||
// break/continue get the loops gate; a stray yield reached cgen
|
||||
// unchecked and its value silently vanished.
|
||||
package main;
|
||||
export fn main() i32 = {
|
||||
yield 5;
|
||||
return 0;
|
||||
};
|
||||
Reference in New Issue
Block a user