Files
ww/test/lang/try_str_unwrap_test.ww
Hojun-Cho 438efab8c6 test: migrate str/slice global family-1 batch to test/lang @test, retire C twins (fold-2)
Continue fold-2 (after 374e97b): migrate the remaining Family-1 str/slice
global + literal + index + call-arg group from bespoke build+run C twins to
test/lang @test, retiring each twin in the same commit. Runtime coverage MOVES
from $(TESTS) to test-lang (T1 runs+asserts via `ww test`) + test-lang-byteid
(T2 keeps cs==ww .s byte-id); coverage is preserved, the $(TESTS) headline
drops 9 (434->425). All asserts are primitive int/u8/bool comparisons (no
fmt/strconv in the assert path); the slice-store/index rows reset the global
each fn and sum ADJACENT elements so a dropped/mis-strided/over-wide word FAILS.

  989_globslicefield_run.c    -> glob_slice_field_test.ww     (slice field of a global struct: g.f=<slice> stores full 24B header; len/cap/non-zero-offset + str/scalar controls)
  989_globstrslice_run.c      -> glob_str_slice_arg_test.ww   (global str sliced with default hi passed as call arg loads its len word; explicit-hi control)
  989_trystr_run.c            -> try_str_unwrap_test.ww       (`!` unwrap of str-success tagged union shuffles the str header for ident-source/error-first/success-first)
  797_len_strglobal_run.c     -> len_str_global_test.ww       (len(str-global) loads .len via name(SB); local-str control)
  801_litstr_pseudo_run.c     -> lit_str_pseudo_test.ww       (string-literal .len/.ptr pseudo-field; empty/multibyte + arg-passthrough)
  803_globalidx_run.c         -> global_index_test.ww         (global str/slice index read/addr-of/store/compound, esz 1/4; local regression pins)
  903_tuple_elem_slice_len.c  -> tuple_elem_slice_len_test.ww (len(t.N) of a slice/str tuple element loads .len at +8; 2/3-slice, str-slice both orders)
  927_composite_call_arg_run.c-> composite_call_arg_test.ww   (slice-returning CALL passed inline as a composite arg; canonical/letslice/two-call/middle/nested/scalar/tagged)
  952_slicecopy_assign_run.c  -> slice_copy_assign_test.ww    (bulk slice-copy-assign `arr[lo:hi]=bs`, esz 1/4, field/via-ptr/local bases; reslice-read companion)

rd_reslice asserts the TRUE value 360 (the .c twin's want=104 was 360 & 0xFF,
an exit-code truncation). 723_composite_call_arg.c's comment repointed to the
new test/lang location. 802_lenidx_run.c is DEFERRED (it carries //ww:error
reject rows — needs a value-rows-only split + a slim reject carrier, a fold-3
pass). Bump LANGBYTEID_EXPECTED_MIN 22->31 to ratchet the new corpus floor.
2026-06-22 11:52:41 +09:00

42 lines
1.7 KiB
Plaintext

// try_str_unwrap_test — 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);
};