// #59: an append/insert of a STRUCT-LITERAL // value evaluates the value BEFORE the len-bump (Hare order). Migrated from // test/wcc/946_append_structlit_evalorder_run.c (value rows; cs==ww byte-id // rides T2). // // #263 both-wrong-IDENTICAL: pre-fix both stages filled the literal AFTER // cg_append_grow bumped xs.len, so a `len(xs)` field expression saw the // post-grow length (sum 6 not 3). The asm-diff/byte-id gates are blind to it — // only a runtime readback is the net. insert() desugars to this same arm. // narrow_neighbor (sub-8B struct filled to capacity) catches the 8B-over-copy // regression: a wrong tail copy clobbers the adjacent `victim` allocation. package append_structlit_evalorder_test; type rec = struct { f: i64 }; type narrowrec = struct { a: i32 }; @test fn append_eval() void = { let xs: []rec = []; append(xs, rec{ f = len(xs): i64 }); append(xs, rec{ f = len(xs): i64 }); append(xs, rec{ f = len(xs): i64 }); let s: i64 = xs[0].f + xs[1].f + xs[2].f; assert(s == 3); }; @test fn insert_eval() void = { let xs: []rec = []; append(xs, rec{ f = 100 }); append(xs, rec{ f = 200 }); insert(xs[1], rec{ f = len(xs): i64 }); assert(xs[1].f == 2); assert(xs[0].f == 100); assert(xs[2].f == 200); }; @test fn narrow_neighbor() void = { let xs: []narrowrec = []; append(xs, narrowrec{ a = len(xs): i32 }); let victim: []i64 = []; append(victim, 1234605616436508552i64); let i: i32 = 1; for (i < 8) { append(xs, narrowrec{ a = len(xs): i32 }); i += 1; }; let s: i32 = 0; let j: i32 = 0; for (j < 8) { s += xs[j].a; j += 1; }; assert(s == 28); assert(victim[0] == 1234605616436508552i64); };