Files
ww/test/lang/forrange_fieldbase_test.ww
Hojun-Cho 132ea4ee60 test: migrate Fam13 misc checker/coercion value tests to @test (#5-C6)
Final fold-2 chunk. The 12 Fam13 single-file value drivers move from
test/wcc/*_run.c into in-language @test row-tables under test/lang/:

- value rows -> test/lang/*_test.ww (12 files)
- reject rows -> runww //ww:error carriers (13, dual-stage non-vacuous)
- nullable abort rows -> runww //ww:run-exit 1 carriers (3)
- 953_globalslice_arg -> _runonly (cs!=ww checker divergence, #28)
- 788 value_not_type_neg + 953_arrlit_slice reject_assign kept as slim
  rc-only .c pins (divergent-diag dual-reject, mutation-gated); 788 #29

Coverage parity verified row-by-row vs each retired driver; advisor-
ratified carve taxonomy; two-round reviewed. Floor ratchet follows.
2026-06-24 22:59:32 +09:00

88 lines
2.3 KiB
Plaintext

// forrange_fieldbase_test — #70: by-value for-range over a NON-IDENT slice/str
// base (field chain, indexed element, call result). Migrated from
// test/wcc/937_forrange_fieldbase_run.c (value rows; cs==ww byte-id rides T2).
// The two LOUD-reject rows (deref base #11, non-ident array base #70) stay as
// runww //ww:error carriers under test/wcc/data/.
//
// Pre-#70 the range header stored the data POINTER into the bound temp and the
// per-iteration code reused it as the base, so i was compared against the
// pointer and the loop walked off the end (regex.finish SEGV); empty slices
// coincidentally exited on ptr==0, so the byte-id gate held on both-wrong. Now
// bound = len, base ptr spilled to its own slot. field_base_24B is the live
// SEGV repro (24B str-header elements through a ptr field); eval_once pins the
// range operand is captured once (a per-iteration field re-read would mis-sum).
package forrange_fieldbase_test;
type holder = struct { xs: []i64, name: str };
type holder2 = struct { xs: []i64, n: i64 };
type bag = struct { names: []str, n: i64 };
fn mk() []i64 = {
let xs: []i64;
append(xs, 7);
append(xs, 8);
return xs;
};
@test fn field_base() void = {
let h: holder = holder { xs = mk(), name = "h" };
let s1: i64 = 0;
for (let v .. h.xs) { s1 += v; };
assert(s1 == 15);
let p: *holder = &h;
let s2: i64 = 0;
for (let v .. p.xs) { s2 += v; };
assert(s2 == 15);
};
@test fn field_base_24B() void = {
let names: []str;
append(names, "ab");
append(names, "cde");
let b: bag = bag { names = names, n = 2 };
let p: *bag = &b;
let total: i64 = 0;
for (let nm .. p.names) {
total += (len(nm): i64);
};
assert(total == 5);
};
@test fn indexed_base() void = {
let m: [][]i64;
append(m, mk());
let s: i64 = 0;
for (let v .. m[0]) { s += v; };
assert(s == 15);
};
@test fn call_base() void = {
let s: i64 = 0;
for (let v .. mk()) { s += v; };
assert(s == 15);
};
@test fn empty_field() void = {
let h: holder = holder { name = "e", ... };
let hit: bool = false;
for (let v .. h.xs) { hit = true; };
assert(!hit);
};
@test fn eval_once() void = {
let a: []i64;
append(a, 7);
append(a, 8);
let b: []i64;
append(b, 100);
let h: holder2 = holder2 { xs = a, n = 0 };
let s: i64 = 0;
for (let v .. h.xs) {
s += v;
h.xs = b;
};
assert(s == 15);
assert(len(h.xs) == 1);
};