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:
2026-08-07 23:54:10 +09:00
parent 06c20dbec4
commit 0b1cc5ef7c
3 changed files with 36 additions and 6 deletions

View File

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