check: populate fn-type params in the wwstage tinfo layer
The N_TFN arm stamped only size and return, so every fn tinfo carried a nil param chain and typeeq judged any two same-return fn types equal: tagged-union dedup collapsed (*fn(A) T | *fn(B) T) to a bare 8-byte pointer and match read the pointer word as a tag, falling through every arm for a real second-variant value. Build the tparam chain like cstage's N_TFN resolve (bare ... sets the FFI variadic flag; a Hare T... param wraps to []T with a per-param variadic bit that typeeq now compares, mirroring cstage type_eq). Graduates the four r76_typeeq_fn pins; the DATABYTEID_DIVERGED ledger is empty.
This commit is contained in:
7
Makefile
7
Makefile
@@ -581,10 +581,9 @@ DATABYTEID_EXPECTED_MIN = 911
|
||||
# Known cs!=ww divergences (loud over blind, the 989_lib_byteid DIVERGE
|
||||
# discipline): each entry must still build on both stages AND still differ.
|
||||
# When a compiler fix lands the entry fails demanding graduation out of
|
||||
# this list rather than silently widening coverage. Tracked with the #59
|
||||
# divergence family.
|
||||
DATABYTEID_DIVERGED = r76_typeeq_fn_diff_arity r76_typeeq_fn_diff_param_type \
|
||||
r76_typeeq_fn_io_vtable_shape r76_typeeq_fn_variadic_vs_fixed
|
||||
# this list rather than silently widening coverage. Currently empty: the
|
||||
# 2026-08 drain closed all eight original entries.
|
||||
DATABYTEID_DIVERGED =
|
||||
$(if $(DATABYTEID_FILES),,$(error test-byteid: empty data corpus))
|
||||
test-data-byteid: $(BIN)/ww $(BIN)/w6c $(BIN)/w6c_ww
|
||||
@work=$$(mktemp -d "$(CURDIR)/$(DATABYTEID_DIR).XXXXXX") || exit 1; \
|
||||
|
||||
@@ -88,6 +88,10 @@ export type tparam = struct {
|
||||
// struct instead, matching cstage Type.iserror semantics.
|
||||
// Faithful STORAGE_ERROR-node port filed as #62.
|
||||
iserror: bool,
|
||||
// Hare-style `T...` — type_ is []T when set. Mirrors cstage
|
||||
// Tparam.variadic (cmd/wcc/ww.h); distinct from tinfo.variadic,
|
||||
// the C-style FFI `...` marker.
|
||||
variadic: bool,
|
||||
tnext: *tparam,
|
||||
};
|
||||
|
||||
@@ -547,6 +551,7 @@ export fn typeeq(a: *tinfo, b: *tinfo) bool = {
|
||||
for (true) {
|
||||
if (pa == nil) { if (pb == nil) { return true; }; return false; };
|
||||
if (pb == nil) { return false; };
|
||||
if (pa.variadic != pb.variadic) { return false; };
|
||||
if (!typeeq(pa.type_, pb.type_)) { return false; };
|
||||
pa = pa.tnext;
|
||||
pb = pb.tnext;
|
||||
|
||||
@@ -2311,6 +2311,32 @@ fn tinfofornode(c: *checker, n: *syntax.node) *syntax.tinfo = {
|
||||
r.slotsize = 8u64;
|
||||
syntax.tinfocachebind(c.tc, n, r);
|
||||
r.ret = tinfofornode(c, n.lhs);
|
||||
// Params must be populated (cstage check.c N_TFN builds the
|
||||
// Tparam chain): with params nil on every fn tinfo, typeeq saw
|
||||
// any two same-return fn types equal, so tagged-union dedup
|
||||
// collapsed `(*fn(A) T | *fn(B) T)` to a bare 8B pointer and
|
||||
// match read the pointer word as a tag.
|
||||
{
|
||||
let fphead: *syntax.tparam = nil;
|
||||
let fptail: *syntax.tparam = nil;
|
||||
let fpn: *syntax.node = n.list;
|
||||
for (fpn != nil) {
|
||||
if (syntax.streq(fpn.str, "...")) {
|
||||
r.variadic = 1;
|
||||
fpn = fpn.next;
|
||||
continue;
|
||||
};
|
||||
let fpt: *syntax.tinfo = tinfofornode(c, fpn.lhs);
|
||||
let fpv: bool = fpn.op == syntax.tkind.TK_ELLIPSIS;
|
||||
if (fpv) { fpt = syntax.typeslice(fpt); };
|
||||
let ftp: *syntax.tparam = alloc(syntax.tparam{name=fpn.str, type_=fpt, iserror=false, variadic=fpv, tnext=nil})!;
|
||||
if (fphead == nil) { fphead = ftp; }
|
||||
else { fptail.tnext = ftp; };
|
||||
fptail = ftp;
|
||||
fpn = fpn.next;
|
||||
};
|
||||
r.params = fphead;
|
||||
};
|
||||
case syntax.nkind.N_TENUM:
|
||||
// Cstage cmd/wcc/check.c:529-542: storage type's size/align
|
||||
// (default i32 = 4B/4B). Cgen's slotsize-TENUM fallback pads
|
||||
@@ -2546,7 +2572,7 @@ fn tinfofornode(c: *checker, n: *syntax.node) *syntax.tinfo = {
|
||||
if (st.size > maxsz) { maxsz = st.size; };
|
||||
if (st.align > al) { al = st.align; };
|
||||
};
|
||||
let tp: *syntax.tparam = alloc(syntax.tparam{name="", type_=src.type_, iserror=src.iserror, tnext=nil})!;
|
||||
let tp: *syntax.tparam = alloc(syntax.tparam{name="", type_=src.type_, iserror=src.iserror, variadic=false, tnext=nil})!;
|
||||
if (head == nil) { head = tp; } else { tail.tnext = tp; };
|
||||
tail = tp;
|
||||
nv += 1;
|
||||
@@ -2564,7 +2590,7 @@ fn tinfofornode(c: *checker, n: *syntax.node) *syntax.tinfo = {
|
||||
if (vt.align > al) { al = vt.align; };
|
||||
};
|
||||
let ve: bool = varianterr(c, v);
|
||||
let tp: *syntax.tparam = alloc(syntax.tparam{name="", type_=vt, iserror=ve, tnext=nil})!;
|
||||
let tp: *syntax.tparam = alloc(syntax.tparam{name="", type_=vt, iserror=ve, variadic=false, tnext=nil})!;
|
||||
if (head == nil) { head = tp; } else { tail.tnext = tp; };
|
||||
tail = tp;
|
||||
nv += 1;
|
||||
|
||||
Reference in New Issue
Block a user