// #95: widening a source whose TYPE reaches a union // variant through an alias CHAIN (or by structural fallback) must tag the right // variant. Pins 1/2/deep-level chain membership, exact-precedence (ali|ali2), // nominal (str|linerr) regression, bare-pointer source, and unrelated-struct // structural fallback. Migrated from test/wcc/944_variant_chain_b95_run.c // (K_RUN rows: build+run cs==ww + asm byte-id). The K_BUILDERR reject rows are // runww //ww:error carriers (test/wcc/data/vchain_*); the cstage-runs/ww-rejects // #277 row + the #81 call-source byte-id-waived rows are carried separately. // Types are per-row-prefixed because the C rows reused names with different shapes. package variant_chain_b95_test; type c1_base = struct { a: int, b: int }; type c1_al0 = c1_base; type c2_base = struct { a: int, b: int }; type c2_al0 = c2_base; type c2_ali = c2_al0; type cds_base = struct { a: int, b: int }; type cds_ali = cds_base; type cds_ali2 = cds_ali; type cdv_base = struct { a: int, b: int }; type cdv_ali = cdv_base; type cdv_ali2 = cdv_ali; type casa_base = struct { a: int, b: int }; type casa_ali = casa_base; type casa_ali2 = casa_ali; type casb_base = struct { a: int, b: int }; type casb_ali = casb_base; type casb_ali2 = casb_ali; type ns_linerr = str; type ne_linerr = str; type ec_base = struct { a: int, b: int }; type ec_al0 = ec_base; type ec_ali = ec_al0; type bc_vt = struct { a: int }; type bc_stream = *bc_vt; type b2_vt = struct { a: int }; type b2_st0 = *b2_vt; type b2_stream = b2_st0; type us_ta = struct { a: int, b: int }; type us_tb = struct { a: int, b: int }; @test fn chain_1lvl_i() void = { let s: c1_base; s.a = 4; s.b = 9; let v: (void | c1_al0) = s; assert(v is c1_al0); }; @test fn chain_2lvl_i() void = { let s: c2_base; s.a = 4; s.b = 9; let v: (void | c2_ali) = s; assert(v is c2_ali); }; @test fn chain_deep_src() void = { let s: cds_ali2; s.a = 4; s.b = 9; let v: (void | cds_ali) = s; assert(v is cds_ali); }; @test fn chain_deep_var() void = { let s: cdv_base; s.a = 4; s.b = 9; let v: (void | cdv_ali2) = s; assert(v is cdv_ali2); }; @test fn chain_amb_srcA() void = { let s: casa_ali; s.a = 4; s.b = 9; let v: (casa_ali | casa_ali2) = s; assert(v is casa_ali); assert(!(v is casa_ali2)); }; @test fn chain_amb_srcB() void = { let s: casb_ali2; s.a = 4; s.b = 9; let v: (casb_ali | casb_ali2) = s; assert(v is casb_ali2); assert(!(v is casb_ali)); }; @test fn nom_str() void = { let s: str = "ok"; let v: (str | ns_linerr) = s; assert(v is str); assert(!(v is ns_linerr)); }; @test fn nom_err() void = { let e: ne_linerr = "bad"; let v: (str | ne_linerr) = e; assert(v is ne_linerr); assert(!(v is str)); }; @test fn exact_ctl() void = { let s: ec_ali; s.a = 4; s.b = 9; let v: (void | ec_ali) = s; assert(v is ec_ali); }; @test fn bare_ctl() void = { let x: bc_vt; x.a = 7; let v: (void | bc_stream) = &x; assert(v is bc_stream); match (v) { case let s: bc_stream => { assert(s.a == 7); }; case void => { assert(false); }; }; }; @test fn bare_2lvl() void = { let x: b2_vt; x.a = 7; let v: (void | b2_stream) = &x; assert(v is b2_stream); match (v) { case let s: b2_stream => { assert(s.a == 7); }; case void => { assert(false); }; }; }; @test fn unrel_struct() void = { let s: us_ta; s.a = 4; s.b = 9; let v: (void | us_tb) = s; assert(v is us_tb); };