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:
@@ -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