Files
ww/test/misc/heldasym_test.ww
Hojun-Cho 05a5830805 test: port the live cs/ww divergence pins to ww; retire 826 + 944 slim carriers
826_alias_tuple_coerce, 944_alias_accept_run and
944_variant_chain_b95_run all reduced to the same irreducible shape: a
LIVE per-stage asymmetry (probed at HEAD) no symmetric fixture or
@test can host. Ported under the DIVERGE discipline — both sides
asserted loud (826 neg_0: cstage "not assignable to declared pair"
vs wwstage over-accept; #96: cstage runs vs w6c_ww "unsupported
address-of shape"; #277: cstage runs vs ww_ww "deferred #277"), so
a fix on either side fails the row and demands graduation. Owned legs
cited, not duplicated: r826_alias_tuple_* byte rows ride
test-data-byteid, 826's neg_1 went symmetric at HEAD and moves to a
//ww:error fixture per the audit split, the 944 value/reject corpora
live in test/lang/{alias_accept,variant_chain_b95}_test.ww and the
alias_*/vchain_* fixtures. Bundled: one file, one concern (held
divergence pins).
2026-08-08 15:05:52 +09:00

194 lines
6.6 KiB
Plaintext

package heldasym_test;
// LIVE cs-vs-ww divergence pins, ported from the retired native
// carriers test/wcc/826_alias_tuple_coerce.c (neg_0),
// test/wcc/944_alias_accept_run.c and
// test/wcc/944_variant_chain_b95_run.c. Each row pins BOTH sides of a
// held stage asymmetry the symmetric fixture grammar cannot host
// (//ww:error demands both stages fail; @test needs ww to build).
// DIVERGE discipline: the divergent side is asserted LOUD, so a fix
// on either side fails the row and demands graduation to the
// symmetric home — the asymmetry can never rot silently.
//
// aliastupleneg0: tuple-alias element-type mismatch. cstage rejects
// with "not assignable to declared pair"; wwstage OVER-ACCEPTS (the
// residual audit's held over-accept; graduates to a //ww:error
// fixture on the wwstage tighten). The arity twin (neg_1) went
// symmetric at HEAD and moves to the corpus per the audit split; the
// r826_alias_tuple_* byte-id rows are owned by test-data-byteid.
//
// aliasaccept96 (held task #96): `&s.len` / `&s.cap` over a 1- or
// 2-level alias-typed slice PARAM. cstage classifies the address
// shape through the alias chase and runs correct (exit 0); the
// wwstage frontend loud-rejects "unsupported address-of shape" — the
// reject must carry its diagnostic, a crash is vacuous. Graduates to
// test/lang/alias_accept_test.ww rows when #96 closes.
//
// variantchain277 (held task #277, out of #95): a CALL result typed
// as a 2-level struct alias widened into (void | ali) then `v is
// ali`. cstage's aggregate-return path builds+runs exit 0; the
// wwstage DRIVER build loud-stops with the EXACT "deferred #277"
// diagnostic (an unrelated wwstage error must not masquerade as
// coverage — the ww_ww build path is where #277 fires, so the driver,
// not bare w6c_ww, is driven). Graduates to test/lang when #277
// wires.
import os;
import os.exec;
import strings;
import testenv;
import time;
fn fail(label: str, why: str) void = {
let m: str = strings.concat("heldasym FAIL: ", label, " -- ", why,
"\n");
os.write(2, m.ptr, m.len: u64);
assert(false);
};
fn tmo() time.duration = {
return (240i64 * (time.second: i64)): time.duration;
};
fn rundir(dir: str, name: str, argv: []str, out: *testenv.commandout) i32 = {
testenv.runcommand(dir, dir, name, argv, tmo(), out);
if (out.termination != exec.termination.EXIT) { return -1; };
return out.code;
};
@test fn aliastupleneg0() void = {
let td: str = testenv.fresh();
testenv.writefile(strings.concat(td, "/n0.ww"), strings.concat(
"package main;\n",
"type pair = (int, int);\n",
"export fn main() i32 = {\n",
"\tlet x: pair = (3, \"s\");\n",
"\treturn x.0: i32;\n",
"};\n"));
let co: testenv.commandout;
let cav: []str = [testenv.driver("w6c"), "-o",
strings.concat(td, "/n0c.s"), strings.concat(td, "/n0.ww")];
if (rundir(td, "cstage", cav, &co) == 0) {
fail("neg_0", "w6c built (should loud-reject)");
};
if (!testenv.has(co.stderr, "not assignable to declared pair")) {
fail("neg_0", "cstage reject lost its diagnostic");
};
let wav: []str = [testenv.driver("w6c_ww"), "-o",
strings.concat(td, "/n0w.s"), strings.concat(td, "/n0.ww")];
if (rundir(td, "wwstage", wav, &co) != 0) {
fail("neg_0", strings.concat("w6c_ww rejected -- over-accept ",
"closed; graduate this row to a //ww:error fixture"));
};
testenv.clean(td);
};
// cstage builds+runs exit 0; the wwstage FRONTEND (w6c_ww, where #96
// fires) loud-rejects with its diagnostic.
fn aliasrow(label: str, src: str) void = {
let td: str = testenv.fresh();
testenv.writefile(strings.concat(td, "/c.ww"), src);
let co: testenv.commandout;
let bav: []str = [testenv.driver("ww"), "build", "-o", "bin",
"c.ww"];
if (rundir(td, "build", bav, &co) != 0) {
fail(label, "cstage build failed (want run)");
};
let rav: []str = [strings.concat(td, "/bin")];
if (rundir(td, "run", rav, &co) != 0) {
fail(label, "cstage run != 0");
};
let wav: []str = [testenv.driver("w6c_ww"), "-o",
strings.concat(td, "/o.s"), strings.concat(td, "/c.ww")];
if (rundir(td, "wwstage", wav, &co) == 0) {
fail(label, strings.concat("w6c_ww accepted -- #96 closed; ",
"graduate to test/lang/alias_accept_test.ww"));
};
if (!testenv.has(co.stderr, "unsupported address-of shape")) {
fail(label, "wwstage reject lost its #96 diagnostic");
};
testenv.clean(td);
};
@test fn aliasaccept96() void = {
aliasrow("amplen1_bound96", strings.concat(
"package main;\n",
"type sl1 = []i64;\n",
"fn check(s: sl1) i32 = {\n",
"\tlet p: *i64 = &s.len;\n",
"\tif (*p == 3) { return 0; };\n",
"\treturn 1;\n",
"};\n",
"export fn main() i32 = {\n",
"\tlet b: []i64 = [1, 2, 3];\n",
"\treturn check(b);\n",
"};\n"));
aliasrow("amplen2_bound96", strings.concat(
"package main;\n",
"type sl1 = []i64;\n",
"type sl2 = sl1;\n",
"fn check(s: sl2) i32 = {\n",
"\tlet p: *i64 = &s.len;\n",
"\tif (*p == 3) { return 0; };\n",
"\treturn 1;\n",
"};\n",
"export fn main() i32 = {\n",
"\tlet b: []i64 = [1, 2, 3];\n",
"\treturn check(b);\n",
"};\n"));
aliasrow("ampcap2_bound96", strings.concat(
"package main;\n",
"type sl1 = []i64;\n",
"type sl2 = sl1;\n",
"fn check(s: sl2) i32 = {\n",
"\tlet p: *i64 = &s.cap;\n",
"\tif (*p == 3) { return 0; };\n",
"\treturn 1;\n",
"};\n",
"export fn main() i32 = {\n",
"\tlet b: []i64 = [1, 2, 3];\n",
"\treturn check(b);\n",
"};\n"));
};
@test fn variantchain277() void = {
let src: str = strings.concat(
"package main;\n",
"type base = struct { a: int, b: int };\n",
"type al0 = base;\n",
"type ali = al0;\n",
"fn mk() ali = {\n",
"\tlet s: ali;\n",
"\ts.a = 4; s.b = 9;\n",
"\treturn s;\n",
"};\n",
"export fn main() i32 = {\n",
"\tlet v: (void | ali) = mk();\n",
"\tif (!(v is ali)) { return 1; };\n",
"\treturn 0;\n",
"};\n");
let td: str = testenv.fresh();
testenv.writefile(strings.concat(td, "/c.ww"), src);
let co: testenv.commandout;
let bav: []str = [testenv.driver("ww"), "build", "-o", "c",
"c.ww"];
if (rundir(td, "build_cstage", bav, &co) != 0) {
fail("callret_bound277", "cstage build failed (want run)");
};
let rav: []str = [strings.concat(td, "/c")];
if (rundir(td, "run_cstage", rav, &co) != 0) {
fail("callret_bound277", "cstage run != 0");
};
let wav: []str = [testenv.driver("ww_ww"), "build", "-o", "cw",
"c.ww"];
if (rundir(td, "build_wwstage", wav, &co) == 0) {
fail("callret_bound277", strings.concat("ww_ww accepted -- ",
"#277 wired; graduate to test/lang"));
};
if (!testenv.has(co.stderr, "deferred #277")) {
fail("callret_bound277", strings.concat("wwstage stop is not ",
"the exact `deferred #277` diagnostic"));
};
testenv.clean(td);
};