test: port the cstage-only rejects to ww; retire 760_def_widen_const + 783_amp_fn_assign_run
Both carriers were already slim: the r76_def_widen_* byte-id legs are owned by the test-data-byteid blanket, 783's positive byte rows by the r78_amp_fn_assign_* fixtures plus that same blanket, and its symmetric non-tagged rejects by the corpus //ww:error fixtures. The unowned remainder is three cstage-only loud-rejects (the 760 narrowing def-ref and 783's two tagged-slot rows); the wwstage over-accepts (no def-init assignability check; #214 void-variant leniency) are documented at the site per the residual audit, never asserted as desired — the rows graduate to //ww:error fixtures when the wwstage side tightens. Bundled: one file, one concern (cstage-reject pins awaiting wwstage graduation).
This commit is contained in:
107
test/misc/reject_test.ww
Normal file
107
test/misc/reject_test.ww
Normal file
@@ -0,0 +1,107 @@
|
||||
package reject_test;
|
||||
|
||||
// Cstage-only loud-reject pins, ported from the retired native
|
||||
// carriers test/wcc/760_def_widen_const.c and
|
||||
// test/wcc/783_amp_fn_assign_run.c. Each row asserts ONLY the cstage
|
||||
// reject; the wwstage side over-accepts today and that over-accept is
|
||||
// documented here (residual audit, test-infra-v2-residual-20260808),
|
||||
// never asserted as desired — these rows graduate to //ww:error
|
||||
// corpus fixtures the moment the wwstage checker gains the matching
|
||||
// reject.
|
||||
//
|
||||
// 760 (#113 def_cast_fits): an out-of-range narrowing def-ref must
|
||||
// fail the cstage build loud — the const-scoped widen must never
|
||||
// become a silent truncation. wwstage has no def-init assignability
|
||||
// check at all (pre-existing leanness) and accepts. The r76_def_widen_*
|
||||
// byte-id legs the carrier also drove are owned by the
|
||||
// test-data-byteid blanket over those fixtures.
|
||||
//
|
||||
// 783 (#206 gate, tagged rows): the two NEGATIVE tagged-slot rows are
|
||||
// cstage-only pending #214 — wwstage's `(X | void)` tagged
|
||||
// assignability leniently matches any *fn against the void variant
|
||||
// (the accept-INVALID hole; its close is required before wwstage can
|
||||
// be the authoritative checker). The positive byte-id rows are owned
|
||||
// by the r78_amp_fn_assign_* fixtures plus the test-data-byteid
|
||||
// blanket; the symmetric non-tagged rejects by the corpus
|
||||
// r783_amp_fn_assign_neg_* //ww:error fixtures.
|
||||
|
||||
import os;
|
||||
import os.exec;
|
||||
import strings;
|
||||
import testenv;
|
||||
import time;
|
||||
|
||||
fn fail(label: str, why: str) void = {
|
||||
let m: str = strings.concat("reject FAIL: ", label, " -- ", why,
|
||||
"\n");
|
||||
os.write(2, m.ptr, m.len: u64);
|
||||
assert(false);
|
||||
};
|
||||
|
||||
fn tmo() time.duration = {
|
||||
return (180i64 * (time.second: i64)): time.duration;
|
||||
};
|
||||
|
||||
@test fn defwidennarrow() void = {
|
||||
let td: str = testenv.fresh();
|
||||
testenv.writefile(strings.concat(td, "/nw.ww"), strings.concat(
|
||||
"package main;\n",
|
||||
"def BIG_I32: i32 = 70000;\n",
|
||||
"def S_I16: i16 = BIG_I32;\n",
|
||||
"export fn main() i32 = { let s: i16 = S_I16; ",
|
||||
"return s: i32; };\n"));
|
||||
let av: []str = [testenv.driver("w6c"), "-o",
|
||||
strings.concat(td, "/nw.s"), strings.concat(td, "/nw.ww")];
|
||||
let co: testenv.commandout;
|
||||
testenv.runcommand(td, td, "narrow", av, tmo(), &co);
|
||||
// A deadline kill is not a reject; only a loud EXIT failure is.
|
||||
if (co.termination != exec.termination.EXIT) {
|
||||
fail("narrow", "w6c did not terminate normally");
|
||||
};
|
||||
if (co.code == 0) {
|
||||
fail("narrow", strings.concat("w6c exited 0 (expected loud ",
|
||||
"failure, no silent truncation)"));
|
||||
};
|
||||
testenv.clean(td);
|
||||
};
|
||||
|
||||
fn cstagerejectrow(label: str, src: str) void = {
|
||||
let td: str = testenv.fresh();
|
||||
testenv.writefile(strings.concat(td, "/main783.ww"), src);
|
||||
let av: []str = [testenv.driver("ww"), "build", "-o", "main783",
|
||||
"main783.ww"];
|
||||
let co: testenv.commandout;
|
||||
testenv.runcommand(td, td, label, av, tmo(), &co);
|
||||
if (co.termination != exec.termination.EXIT) {
|
||||
fail(label, "cstage build did not terminate normally");
|
||||
};
|
||||
if (co.code == 0) {
|
||||
fail(label, "cstage built but expected reject");
|
||||
};
|
||||
testenv.clean(td);
|
||||
};
|
||||
|
||||
@test fn ampfnassigntagged() void = {
|
||||
// Two same-signature ptr-to-fn variants: a direct &fn is ambiguous
|
||||
// and must never silently bind to one.
|
||||
cstagerejectrow("neg_ambiguous_tagged", strings.concat(
|
||||
"package main;\n",
|
||||
"type reader = fn(x: i32) i32;\n",
|
||||
"type writer = fn(x: i32) i32;\n",
|
||||
"fn myfn(x: i32) i32 = { return x; };\n",
|
||||
"fn main() i32 = {\n",
|
||||
" let x: (*reader | *writer | void) = &myfn;\n",
|
||||
" return 0;\n",
|
||||
"};\n"));
|
||||
// Laundering a materialized *fn into a (*reader|void) slot:
|
||||
// cstage rejects nominally (harec types.c:1039-1066 mirror).
|
||||
cstagerejectrow("neg_launder_tagged", strings.concat(
|
||||
"package main;\n",
|
||||
"type reader = fn(x: i32) i32;\n",
|
||||
"fn rd(x: i32) i32 = { return x + 1; };\n",
|
||||
"fn main() i32 = {\n",
|
||||
" let p = &rd;\n",
|
||||
" let s: (*reader | void) = p;\n",
|
||||
" return 0;\n",
|
||||
"};\n"));
|
||||
};
|
||||
Reference in New Issue
Block a user