// alias_accept_test — #5 alias arc F1: the transitive TY_NAMED chase. cstage // single-peeled the alias at promotion/cond/assign/index/field/arg/union/cast // consumers, so a 2+-level alias (or one alias over a named aggregate) left the // type TY_NAMED and fell to a scalar/word0-only/pointer tail — runtime-wrong or // byte-diverging vs wwstage (which already chased). Each @test pins one consumer // shape, asserting the value the C row checked so a re-narrowing can't hide. // Migrated from test/wcc/944_alias_accept_run.c (#5-C3). package alias_accept_test; // binop_alias_base type bab_myint = int; // binop_2level type b2_myint = int; type b2_myint2 = b2_myint; type b2_myu = u32; // ret_through_2level type rt_myint = int; type rt_myint2 = rt_myint; // assign_alias_alias type aa_k1 = int; type aa_k2 = int; // cond_* family (alias-of-bool) type cond_myb = bool; // dot_2level (alias declared before base — forward ref under test) type dot_a3 = dot_b3; type dot_b3 = dot_c3; type dot_c3 = struct { x: size, y: size, z: size }; // deref_alias_ptr type dp_pi = *int; type dp_pi2 = dp_pi; // slicefield_store_2lvl type sfs_sl = []int; type sfs_sl2 = sfs_sl; type sfs_box = struct { s: sfs_sl2, n: int }; // slicefield_range_2lvl type sfr_sl = []int; type sfr_sl2 = sfr_sl; type sfr_box = struct { s: sfr_sl2, n: int }; // strfield_store_2lvl type sfst_s1t = str; type sfst_s2t = sfst_s1t; type sfst_box = struct { s: sfst_s2t, n: int }; // slicefield_structlit_2lvl type sfsl_sl = []int; type sfsl_sl2 = sfsl_sl; type sfsl_box = struct { s: sfsl_sl2, n: int }; // slicefield_viaptr_2lvl type sfv_sl = []int; type sfv_sl2 = sfv_sl; type sfv_box = struct { s: sfv_sl2, n: int }; // slicefield_chainstore_2lvl type sfc_sl = []int; type sfc_sl2 = sfc_sl; type sfc_inner = struct { s: sfc_sl2 }; type sfc_outer = struct { i: sfc_inner }; // slicefield_ptrchain_2lvl type sfp_sl = []int; type sfp_sl2 = sfp_sl; type sfp_inner = struct { s: sfp_sl2, n: int }; type sfp_outer = struct { pi: *sfp_inner }; // slicefield_chainread_2lvl type sfcr_sl = []int; type sfcr_sl2 = sfcr_sl; type sfcr_inner = struct { s: sfcr_sl2 }; type sfcr_outer = struct { i: sfcr_inner }; // slicefield_ptrread_2lvl type sfpr_sl = []int; type sfpr_sl2 = sfpr_sl; type sfpr_box = struct { s: sfpr_sl2, n: int }; // slicefield_wholeread_2lvl type sfw_sl = []int; type sfw_sl2 = sfw_sl; type sfw_box = struct { s: sfw_sl2, n: int }; // slicefield_idx_tripwire_73 type sfi_sl = []int; type sfi_sl2 = sfi_sl; type sfi_box = struct { s: sfi_sl2, n: int }; // idx_2level type idx_arr = [4]int; type idx_arr2 = idx_arr; // slice_2level type sl2_sl = []int; type sl2_sl2 = sl2_sl; // range_2level type rng_arr = [4]int; type rng_arr2 = rng_arr; // slice_of_alias_arg type soa_arr = [4]int; type soa_arr2 = soa_arr; // float_alias_param_kenv3 (alias before base — forward ref) type fak_fa = fak_fb; type fak_fb = f64; // float_alias_param type fap_f1t = f64; type fap_f2t = fap_f1t; // str_alias_2level type sa2_s1t = str; type sa2_s2t = sa2_s1t; // slice_alias_param type slp_b1 = []int; type slp_b2 = slp_b1; // arg_2level_fwdref (alias before base — forward ref) type afr_ali = afr_base; type afr_base = struct { a: size, b: size, c: size }; // arg_2level_litinit type ali_st = struct { a: size, b: size, c: size }; type ali_row = ali_st; // arg_2level_5word type a5_big = struct { a: size, b: size, c: size, d: size, e: size }; type a5_big2 = a5_big; // arg_2level_floatclass type afc_fs = struct { x: f64, n: size }; type afc_fs2 = afc_fs; // arg_base_control type abc_base = struct { a: size, b: size, c: size }; // union_store_norm type usn_base = struct { a: size, b: size }; type usn_ali = usn_base; // union_store_fwd (alias before base — forward ref) type usf_ali = usf_base; type usf_base = struct { a: size, b: size }; // union_store_3word type us3_base = struct { a: size, b: size, c: size }; type us3_ali = us3_base; // union_push_arg type upa_base = struct { a: size, b: size }; type upa_ali = upa_base; // union_store_base_ctl type usbc_base = struct { a: size, b: size, c: size }; // union_slit_base_ctl type uslbc_base = struct { a: size, b: size }; // union_slit_alias type usla_base = struct { a: size, b: size }; type usla_ali = usla_base; // union_slit_alias2 type usl2_base = struct { a: size, b: size }; type usl2_ali = usl2_base; type usl2_ali2 = usl2_ali; // union_slit_order (alias before base — forward ref) type uslo_ali = uslo_base; type uslo_base = struct { a: size, b: size }; // castprim_3lvl_base type cp3_s1 = struct { f: u32 }; type cp3_s2 = cp3_s1; type cp3_s3 = cp3_s2; // castprim_ptr2lvl_base type cpp_s1 = struct { f: u32 }; type cpp_s2 = cpp_s1; // castprim_2lvl_base_ctl type cp2_s1 = struct { f: u32 }; type cp2_s2 = cp2_s1; // untyped_tagdst_2lvl_hold type utd_r1 = (void | size); type utd_r2 = utd_r1; // untyped_str2lvl_ctl type usc_sa1 = str; type usc_sa2 = usc_sa1; // untyped_int2lvl_ctl type uic_ia1 = i64; type uic_ia2 = uic_ia1; // untyped_bool1lvl_ctl type ub1_ba1 = bool; // untyped_bool2lvl_bound90 type ub2_bb1 = bool; type ub2_bb2 = ub2_bb1; // v2_ctrl type v2c_pc = *i64; // v2_alias2 type v2a_pa = *i64; type v2a_pb = v2a_pa; // sp_alias1 type sp1_inner = (i64 | str); type sp1_outer = (...sp1_inner | void); // sp_alias2 type sp2_inner = (i64 | str); type sp2_inner2 = sp2_inner; type sp2_outer = (...sp2_inner2 | void); // rangevar_alias2 type rva_slk = []int; // nested_alias_field_norm type nfn_fa = nfn_inner; type nfn_inner = struct { a: size, b: size }; type nfn_outer = struct { x: nfn_fa, y: nfn_fa }; // nested_alias_field_fwd (outer before fa before inner — forward ref) type nff_outer = struct { x: nff_fa, y: nff_fa }; type nff_fa = nff_inner; type nff_inner = struct { a: size, b: size }; fn rt_dbl(x: rt_myint2) int = { return x * 2; }; fn cond_pick(b: cond_myb) i32 = { if (b) { return 0; }; return 1; }; fn sfcr_noise(x: int) int = { return x * 7 + 3; }; fn sfpr_noise(x: int) int = { return x * 7 + 3; }; fn sfw_noise(x: int) int = { return x * 7 + 3; }; fn soa_sum(s: []int) int = { let t: int = 0; for (let x .. s) { t = t + x; }; return t; }; fn fak_take(x: fak_fa) f64 = { return x * 2.0; }; fn fap_half(x: fap_f2t) f64 = { return x / 2.0; }; fn sa2_taillen(s: sa2_s2t) int = { return (s.len: int); }; fn slp_first(s: slp_b2) int = { return s[0]; }; fn afr_take(s: afr_ali) size = { return s.a + s.b + s.c; }; fn ali_take(s: ali_row) size = { return s.a + s.b + s.c; }; fn a5_take(s: a5_big2) size = { return s.a + s.e; }; fn afc_take(s: afc_fs2) size = { if (s.x != 2.5) { return 99; }; return s.n; }; fn abc_take(s: abc_base) size = { return s.a + s.b + s.c; }; fn upa_peek(v: (void | upa_ali)) size = { match (v) { case let s: upa_ali => { return s.b; }; case void => { return 0; }; }; }; @test fn binop_alias_base() void = { let a: bab_myint = 5; let b: int = 3; let c = a + b; assert(c == 8); let d: bab_myint = 2; assert(a * d == 10); assert(!(a < b)); assert(a - b == 2); }; @test fn binop_2level() void = { let a: b2_myint2 = 7; let b: int = 2; assert(a % b == 1); let u: b2_myu = 10: u32; let v: u32 = 3: u32; assert(u / v == 3: u32); assert(u + v == 13: u32); }; @test fn ret_through_2level() void = { let a: rt_myint2 = 21; assert(rt_dbl(a) == 42); }; @test fn assign_alias_alias() void = { let x: aa_k1 = 5; let y: aa_k2 = x; assert(y == 5); }; // alias-bool at the IF consumer (assert itself rejects alias-bool — that loud // case is assert_stays_loud, not migrated here). @test fn cond_if() void = { let b: cond_myb = true; let r: int = 1; if (b) { r = 0; }; assert(r == 0); }; @test fn cond_for() void = { let b: cond_myb = true; let i: int = 0; for (b) { i = i + 1; if (i >= 3) { b = false; }; }; assert(i == 3); }; @test fn cond_bang() void = { let b: cond_myb = false; let n = !b; let r: int = 0; if (!n) { r = 1; }; assert(r == 0); }; @test fn cond_andor() void = { let b: cond_myb = true; let c: cond_myb = false; let r: int = 0; if (b && !c) { } else { r = 1; }; assert(r == 0); if (c || b) { } else { r = 2; }; assert(r == 0); }; @test fn cond_fnparam() void = { let b: cond_myb = true; assert(cond_pick(b) == 0); }; @test fn dot_2level() void = { assert(size(dot_a3) == 24); assert(size((void | dot_a3)) == 32); let v: dot_a3; v.x = 1; v.y = 2; v.z = 3; assert(v.x + v.y + v.z == 6); }; @test fn deref_alias_ptr() void = { let v: int = 41; let p: dp_pi2 = &v; assert(*p == 41); *p = 7; assert(v == 7); }; @test fn slicefield_store_2lvl() void = { let a: [3]int = [700: int, 800: int, 900: int]; let b: sfs_box; b.n = 5; b.s = a[0:3]; assert(b.n == 5); assert(b.s[0] == 700); assert(b.s[2] == 900); assert(b.s.len == 3); }; @test fn slicefield_range_2lvl() void = { let a: [3]int = [700: int, 800: int, 900: int]; let b: sfr_box; b.s = a[0:3]; b.n = 5; assert(b.s.len == 3); assert(b.s[2] == 900); for (let x .. b.s) { assert(!(x < 700)); }; }; @test fn strfield_store_2lvl() void = { let b: sfst_box; b.s = "hello"; b.n = 5; assert(b.s.len == 5); }; @test fn slicefield_structlit_2lvl() void = { let a: [3]int = [700: int, 800: int, 900: int]; let b: sfsl_box = sfsl_box { s = a[0:3], n = 5: int }; assert(b.n == 5); assert(b.s.len == 3); assert(b.s[2] == 900); }; @test fn slicefield_viaptr_2lvl() void = { let a: [3]int = [700: int, 800: int, 900: int]; let b: sfv_box; let p = &b; p.s = a[0:3]; assert(p.s.len == 3); assert(p.s[2] == 900); }; @test fn slicefield_chainstore_2lvl() void = { let a: [3]int = [700: int, 800: int, 900: int]; let v: sfc_outer; v.i.s = a[0:3]; assert(v.i.s.len == 3); assert(v.i.s[2] == 900); }; @test fn slicefield_ptrchain_2lvl() void = { let a: [3]int = [700: int, 800: int, 900: int]; let i: sfp_inner; i.n = 1; let v: sfp_outer; v.pi = &i; v.pi.s = a[0:3]; assert(i.s.len == 3); assert(i.s[2] == 900); }; @test fn slicefield_chainread_2lvl() void = { let a: [3]int = [700: int, 800: int, 900: int]; let v: sfcr_outer; v.i.s = a[0:3]; let k = sfcr_noise(9); assert(k == 66); let w = v.i.s; assert(w.len == 3); }; @test fn slicefield_ptrread_2lvl() void = { let a: [3]int = [700: int, 800: int, 900: int]; let b: sfpr_box; b.s = a[0:3]; let p = &b; let k = sfpr_noise(9); assert(k == 66); let w = p.s; assert(w.len == 3); }; @test fn slicefield_wholeread_2lvl() void = { let a: [3]int = [700: int, 800: int, 900: int]; let b: sfw_box; b.s = a[0:3]; let k = sfw_noise(9); assert(k == 66); let w = b.s; assert(w.len == 3); assert(w[2] == 900); }; @test fn slicefield_idx_tripwire_73() void = { let a: [3]int = [700: int, 800: int, 900: int]; let xs: [2]sfi_box; xs[0].s = a[0:3]; assert(xs[0].s.len == 3); }; @test fn idx_2level() void = { let a: idx_arr2 = [1000: int, 2000: int, 3000: int, 4000: int]; assert(a[2] == 3000); a[1] = 9999; assert(a[1] == 9999); }; @test fn slice_2level() void = { let a: [4]int = [1000: int, 2000: int, 3000: int, 4000: int]; let s: sl2_sl2 = a[1:3]; assert(s.len == 2); assert(s[0] == 2000); s[1] = 7777; assert(a[2] == 7777); }; @test fn range_2level() void = { let a: rng_arr2 = [1: int, 2: int, 3: int, 4: int]; let sum: int = 0; for (let x .. a) { sum = sum + x; }; assert(sum == 10); }; @test fn slice_of_alias_arg() void = { let a: soa_arr2 = [1000: int, 2000: int, 3000: int, 4000: int]; let s = a[1:3]; assert(s.len == 2); assert(s[1] == 3000); assert(soa_sum(a[0:4]) == 10000); }; @test fn float_alias_param_kenv3() void = { assert(fak_take(1.5) == 3.0); }; @test fn float_alias_param() void = { let v: fap_f2t = 5.0; assert(fap_half(v) == 2.5); }; @test fn str_alias_2level() void = { let v: sa2_s2t = "hello"; assert(v.len == 5); assert(sa2_taillen(v) == 5); let w: sa2_s2t = v; assert(w.len == 5); }; @test fn slice_alias_param() void = { let a: [3]int = [1000: int, 2000: int, 3000: int]; let s: slp_b2 = a[0:3]; assert(slp_first(s) == 1000); }; @test fn arg_2level_fwdref() void = { let x: afr_ali; x.a = 4; x.b = 9; x.c = 13; assert(afr_take(x) == 26); }; @test fn arg_2level_litinit() void = { let x: ali_st = ali_st { a = 4: size, b = 9: size, c = 13: size }; assert(ali_take(x) == 26); }; @test fn arg_2level_5word() void = { let v: a5_big2; v.a = 1000; v.b = 2; v.c = 3; v.d = 4; v.e = 5000; assert(a5_take(v) == 6000); }; @test fn arg_2level_floatclass() void = { let v: afc_fs2; v.x = 2.5; v.n = 7; assert(afc_take(v) == 7); }; @test fn arg_base_control() void = { let x: abc_base; x.a = 4; x.b = 9; x.c = 13; assert(abc_take(x) == 26); }; @test fn union_store_norm() void = { let x: usn_ali; x.a = 4; x.b = 9; let v: (void | usn_ali) = x; match (v) { case let s: usn_ali => { assert(s.a == 4); assert(s.b == 9); }; case void => { assert(false); }; }; }; @test fn union_store_fwd() void = { let x: usf_ali; x.a = 4; x.b = 9; let v: (void | usf_ali) = x; match (v) { case let s: usf_ali => { assert(s.a == 4); assert(s.b == 9); }; case void => { assert(false); }; }; }; @test fn union_store_3word() void = { let x: us3_ali; x.a = 4; x.b = 9; x.c = 3; let v: (void | us3_ali) = x; match (v) { case let s: us3_ali => { assert(s.a == 4); assert(s.c == 3); }; case void => { assert(false); }; }; }; @test fn union_push_arg() void = { let x: upa_ali; x.a = 4; x.b = 9; assert(upa_peek(x) == 9); }; @test fn union_store_base_ctl() void = { let x: usbc_base; x.a = 4; x.b = 9; x.c = 3; let v: (void | usbc_base) = x; match (v) { case let s: usbc_base => { assert(s.a == 4); assert(s.c == 3); }; case void => { assert(false); }; }; }; @test fn union_slit_base_ctl() void = { let v: (void | uslbc_base) = uslbc_base{a=4000, b=9000}; match (v) { case let s: uslbc_base => { assert(s.a == 4000); assert(s.b == 9000); }; case void => { assert(false); }; }; }; @test fn union_slit_alias() void = { let v: (void | usla_ali) = usla_ali{a=4000, b=9000}; match (v) { case let s: usla_ali => { assert(s.a == 4000); assert(s.b == 9000); }; case void => { assert(false); }; }; }; @test fn union_slit_alias2() void = { let v: (void | usl2_ali2) = usl2_ali2{a=4000, b=9000}; match (v) { case let s: usl2_ali2 => { assert(s.a == 4000); assert(s.b == 9000); }; case void => { assert(false); }; }; }; @test fn union_slit_order() void = { let v: (void | uslo_ali) = uslo_ali{a=4000, b=9000}; match (v) { case let s: uslo_ali => { assert(s.a == 4000); assert(s.b == 9000); }; case void => { assert(false); }; }; }; @test fn castprim_3lvl_base() void = { let x: cp3_s3; x.f = 70000; let y: u64 = (x.f: u32): u64; assert(y == 70000); }; @test fn castprim_ptr2lvl_base() void = { let x: cpp_s2; x.f = 70000; let p: *cpp_s2 = &x; let y: u64 = (p.f: u32): u64; assert(y == 70000); }; @test fn castprim_2lvl_base_ctl() void = { let x: cp2_s2; x.f = 70000; let y: u64 = (x.f: u32): u64; assert(y == 70000); }; @test fn untyped_hold33_pin() void = { let mn: (void | size) = 5; assert(mn is size); }; @test fn untyped_tagdst_2lvl_hold() void = { let v: utd_r2 = 5; assert(v is size); }; @test fn untyped_str2lvl_ctl() void = { let v: (void | usc_sa2) = "hi"; assert(v is usc_sa2); }; @test fn untyped_int2lvl_ctl() void = { let v: (void | uic_ia2) = 7; assert(v is uic_ia2); }; @test fn untyped_bool1lvl_ctl() void = { let v: (void | ub1_ba1) = true; assert(v is ub1_ba1); }; @test fn untyped_bool2lvl_bound90() void = { let v: (void | ub2_bb2) = true; assert(v is ub2_bb2); }; @test fn v2_ctrl() void = { let x: i64 = 7; let v: (void | v2c_pc) = &x; assert(v is v2c_pc); }; @test fn v2_alias2() void = { let x: i64 = 7; let v: (void | v2a_pb) = &x; assert(v is v2a_pb); }; @test fn sp_alias1() void = { let v: sp1_outer = 5: i64; assert(v is i64); }; @test fn sp_alias2() void = { let v: sp2_outer = 5: i64; assert(v is i64); }; @test fn amplen_plain() void = { let s: []i64 = [1, 2, 3]; let p: *i64 = &s.len; assert(*p == 3); }; @test fn rangevar_alias2() void = { let a: [4]int = [10: int, 20: int, 30: int, 40: int]; let t: rva_slk = a[2:]; assert(t.len == 2); assert(t.cap == 2); let sum: int = 0; for (let x .. t) { sum = sum + 0 * x + 1; }; assert(sum == 2); }; @test fn rangevar_plain_ctl() void = { let a: [4]int = [10: int, 20: int, 30: int, 40: int]; let t: []int = a[2:]; let sum: int = 0; for (let x .. t) { sum = sum + 0 * x + 1; }; assert(sum == 2); }; @test fn nested_alias_field_norm() void = { let v: nfn_outer; v.x.a = 4; v.x.b = 9; v.y.a = 7; v.y.b = 3; assert(v.x.b == 9); assert(v.y.b == 3); }; @test fn nested_alias_field_fwd() void = { let v: nff_outer; v.x.a = 4; v.x.b = 9; v.y.a = 7; v.y.b = 3; assert(v.x.b == 9); assert(v.y.b == 3); let pa = &v.y.b; *pa = 11; assert(v.y.b == 11); };