// The `!` unwrap of a str-success tagged union must // shuffle the str header (DX,CX,R8) → (AX,BX,CX) for ANY operand shape and ANY // variant order, keyed off the STAMPED operand type, migrated from // test/wcc/989_trystr_run.c (#16). The wwstage cgtryprop/cgtryunw computed // succisstr only for an N_CALL operand (name-keyed fnretlookupmod on the callee // leaf) and tested the FIRST variant, so an ident-source unwrap and an // error-first union both dropped the `MOVQ CX,BX / MOVQ R8,CX` shuffle and kept // a stale len/cap; the fix reads the stamped operand's success-variant type via // successvariant()+typeisstr(). A 40-byte `junk` str precedes each unwrap so a // dropped shuffle leaks junk's len (40) into s.len: pre-fix ident_source ran // ww=40 vs cs=2 (silent overrun). cs==ww was byte-id-blind on this shape. package try_str_unwrap_test; type e = !i32; fn mk_se() (str | e) = { return "hi"; }; fn mk2_es() (e | str) = { return "abc"; }; fn mk_se4() (str | e) = { return "wxyz"; }; @test fn ident_source() void = { // ident-source unwrap (`let r = mk(); r!`) — the dropped-shuffle case. let r: (str | e) = mk_se(); let junk: str = "0123456789012345678901234567890123456789"; let s: str = r!; assert(s.len: i32 == 2); }; @test fn errfirst_call() void = { // error-first union (e | str): the success variant is NOT the first. let junk: str = "0123456789012345678901234567890123456789"; let s3: str = mk2_es()!; assert(s3.len: i32 == 3); }; @test fn succfirst_call() void = { // success-first call (str | e) — the control the pre-fix path got right. let junk: str = "0123456789012345678901234567890123456789"; let s: str = mk_se4()!; assert(s.len: i32 == 4); };