From b26b3dbdc52254b6fc5408e2842dc8ac6043a0fd Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Fri, 5 Jun 2026 23:58:54 +0900 Subject: [PATCH] =?UTF-8?q?wcc=5Fww:=20c1=20collapse=20plain=20TY=5FNAMED?= =?UTF-8?q?=20chase=20loops=20into=20tichase=20across=20cgenstmt/cgen/chec?= =?UTF-8?q?k=20=E2=80=94=20byte-id=20neutral?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit F2a batch-4 c1, mechanical, per rob's spec census (re-verified at 4adf914; check.ww/cgenstmt.ww cites were stable as predicted, the two cgenutil [B3-SHIFT] cites moved +8: :2746->:2754, :2895->:2903). 42 conversions, every site eyes-classified plain nil+NAMED: - cgenstmt.ww 26: one-line :149 :325 :352 :532 :551 :594 :715 :732 :938 :940 :1577 :1629 :1782 :2230 :2575 :3372 :3678 + multi-line :986 :1912 :2287 :2291 :2702 :2759 :2823 :3037 :3715 (all plain, no extra guards). - cgen.ww 13: one-line :1505 :1541 :1658 :1691 :1697 :1947 :1951 :2065 :2109 :2118 + multi-line :2239 :2648 :2663 (incl. the emitdefconstants struct/array arms — plain). - check.ww 3: :1627 tupleelemslot, :1673 fieldslotsize, :4111 arrlit elem chase; WHY comments kept. tichase visibility verified: same `package wcc` (cgenstmt/cgen already call it) — no second helper. Survivors (classified, untouched): - cgenutil.ww :1301 tichase's own body (the accessor) + :2754 nullableptrtag single peel (batch-2 c3-B2 PROBE-CLEARED, 018ef66 — peel-ok annotation added this commit, cites the banked record; cs twin cmd/w6c/cgen.c:747 verified at this SHA) + :2903 flatvariantidxt pass-2 guard (batch-4 c2's site). - check.ww :1765 comment + :1805 construction write (peellint-ok annotation added — the one WRITE building the NAMED link) + :2038 spread peel (c3-B1) + :2273/:2275 &len/cap hand-walk (c3-B2) + :3666 comment FALSE POSITIVE ("io.underread" matches `.under`). - cgenexpr.ww :2886 comment only. Lint note for the peellint finale: the `.under` token-match must be token-bounded — check.ww:3666's "io.underread" is a comment false-positive at a non-boundary match. Behavior sites (:2038, :2273/:2275, :2903) and #80's site excluded per spec — they ride c2-c4. Byte-neutral proof: rebuilt w6c_ww on the five BASE main.combined.ww inputs -> all five .s byte-identical to the base build's outputs; cs==ww byte-id holds on the five REGENERATED combineds; test-unit 290 green. w6c_ww + wwdump combined.ww regens ride along. --- selfhost/cmd/w6c/main.combined.ww | 115 ++++++++++++--------------- selfhost/cmd/wcc/cgen.ww | 32 +++----- selfhost/cmd/wcc/cgenstmt.ww | 70 ++++++---------- selfhost/cmd/wcc/cgenutil.ww | 4 + selfhost/cmd/wcc/check.ww | 9 ++- selfhost/cmd/wwdump/main.combined.ww | 115 ++++++++++++--------------- 6 files changed, 147 insertions(+), 198 deletions(-) diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index ee32d42b..edc8907b 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -11896,7 +11896,7 @@ fn tupleelemslot(pt: *tinfo) u64 = { // now fires on aliased operands; byte-id holds because it collapses // NAMED to the alias-invariant underlying this read consumes. let t: *tinfo = pt; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); if (t == nil) { return 8u64; }; let pk: tykind = t.kind; if (pk == tykind.TY_VOID) { return 0u64; }; @@ -11942,7 +11942,7 @@ fn fieldslotsize(ft: *tinfo) u64 = { // now fires on aliased operands; byte-id holds because it collapses // NAMED to the alias-invariant underlying this read consumes. let t: *tinfo = ft; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); if (t == nil) { return 8u64; }; let fk: tykind = t.kind; if (fk == tykind.TY_STRUCT) { return t.slotsize; }; @@ -12074,6 +12074,9 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { under = c.tc.tyerr; }; named.resolving = 0; + // peellint-ok: construction — the one + // WRITE that builds the NAMED link; + // not a peel, can't route via tichase. named.under = under; if (under != nil) { named.size = under.size; @@ -14380,7 +14383,7 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { let at: *tinfo = tinfofornode(c, arrtn); let et: *tinfo = nil; if (at != nil) { et = at.sub; }; - for (et != nil && et.kind == tykind.TY_NAMED) { et = et.under; }; + et = tichase(et); let e: *node = rhs.list; for (e != nil) { let skip: bool = false; @@ -18823,6 +18826,10 @@ export fn nullableptrtag(t: *node) i32 = { for (p != nil) { let vt: *tinfo = p.type_; if (vt != nil) { + // peel-ok: single peel PROBE-CLEARED (batch-2 c3-B2, + // 018ef66) — constructible variant params never carry + // 2+-level NAMED at this scan; cs twin nullable_ptr_tag + // (cmd/w6c/cgen.c:747) keeps the identical single peel. if (vt.kind == tykind.TY_NAMED) { vt = vt.under; }; if (vt != nil) { if (vt.kind == tykind.TY_PTR) { return i; }; @@ -32423,7 +32430,7 @@ fn tupsse(i: i32) str = { // tuple_eslot (cmd/w6c/cgen.c). export fn tupeslot(ti: *tinfo) i32 = { let t: *tinfo = ti; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); if (t == nil) { return 8; }; if (t.kind == tykind.TY_VOID) { return 0; }; // a literal tuple's stamped element can be untyped_str (size 0) — @@ -32599,7 +32606,7 @@ fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { return (tyslicesize() / 8i64): i32; }; let t: *tinfo = e.type_: *tinfo; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); if (t != nil && (t.kind == tykind.TY_TAGGED || t.kind == tykind.TY_VOID)) { return tupeslotn(e) / 8; @@ -32626,7 +32633,7 @@ fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { // the slot — loud (rule 7, the #23/#40 widening family). fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { let t: *tinfo = e.type_: *tinfo; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); let etagged: bool = false; if (t != nil) { if (t.kind == tykind.TY_TAGGED) { etagged = true; }; }; if (dtn != nil) { @@ -32806,7 +32813,7 @@ fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { let el: *ttupleelem = tu.tupleelems; for (el != nil) { let et: *tinfo = el.type_; - for (et != nil && et.kind == tykind.TY_NAMED) { et = et.under; }; + et = tichase(et); if (et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64)) { ssecount = ssecount + 1; } else { @@ -32825,7 +32832,7 @@ fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { el = tu.tupleelems; for (el != nil) { let et: *tinfo = el.type_; - for (et != nil && et.kind == tykind.TY_NAMED) { et = et.under; }; + et = tichase(et); let isflt: bool = et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64); let eslot: i32 = tupeslot(el.type_); if (isflt) { @@ -32868,7 +32875,7 @@ fn cgtaggedtuplepayloadshift(c: *cgen, tup: *tinfo) void = { let el: *ttupleelem = tup.tupleelems; for (el != nil) { let et: *tinfo = el.type_; - for (et != nil && et.kind == tykind.TY_NAMED) { et = et.under; }; + et = tichase(et); let isflt: bool = et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64); if (isflt || tupeslot(el.type_) != 8) { let msg: str = "tuple-in-union ? unwrap: float/slice/str/tagged payload element needs SysV per-eightbyte classification (see #243); only integer tuple payloads supported\n"; @@ -32989,7 +32996,7 @@ fn cgreturn(c: *cgen, n: *node) void = { for (we != nil) { let dt: *tinfo = nil; if (pt != nil) { dt = pt.lhs.type_: *tinfo; }; - for (dt != nil && dt.kind == tykind.TY_NAMED) { dt = dt.under; }; + dt = tichase(dt); if (dt != nil && dt.kind == tykind.TY_TAGGED) { // #22b (task #28): MEMORY-class tagged // element — the whole box copies through @@ -33006,7 +33013,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_RETURN over-cap tagged arm. let eslot: i32 = tupeslotn(pt.lhs); let eu: *tinfo = we.type_: *tinfo; - for (eu != nil && eu.kind == tykind.TY_NAMED) { eu = eu.under; }; + eu = tichase(eu); let eoff: i32 = 0; if (we.kind == nkind.N_IDENT && eu != nil) { if (eu.kind == tykind.TY_TAGGED && tupeslotn(we) == eslot) { @@ -33212,9 +33219,9 @@ fn cgreturn(c: *cgen, n: *node) void = { let forwardtagged: bool = false; if ((rhs.kind == nkind.N_CALL || rhs.kind == nkind.N_INDEX || rhs.kind == nkind.N_DOT) && rhs.type_ != nil && c.fnret != nil && c.fnret.type_ != nil) { let ru: *tinfo = rhs.type_: *tinfo; - for (ru != nil && ru.kind == tykind.TY_NAMED) { ru = ru.under; }; + ru = tichase(ru); let fu: *tinfo = c.fnret.type_: *tinfo; - for (fu != nil && fu.kind == tykind.TY_NAMED) { fu = fu.under; }; + fu = tichase(fu); if (ru != nil && fu != nil && ru.kind == tykind.TY_TAGGED && fu.kind == tykind.TY_TAGGED) { if (ru == fu) { forwardtagged = true; @@ -33259,9 +33266,7 @@ fn cgreturn(c: *cgen, n: *node) void = { return; }; let ru38: *tinfo = rhs.type_: *tinfo; - for (ru38 != nil && ru38.kind == tykind.TY_NAMED) { - ru38 = ru38.under; - }; + ru38 = tichase(ru38); if (ru38 != nil) { // #37 wired the N_INDEX/N_DOT mem-read into // the widener; the remaining >32B kinds stay @@ -33851,7 +33856,7 @@ fn cgreturn(c: *cgen, n: *node) void = { if (rhs.op == tkind.TK_STAR) { arrok = true; }; }; let ati: *tinfo = c.fnret.type_: *tinfo; - for (ati != nil && ati.kind == tykind.TY_NAMED) { ati = ati.under; }; + ati = tichase(ati); if (arrok && ati != nil) { let rsz: i32 = ati.size: i32; if (rsz <= 24) { @@ -33903,7 +33908,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // elements loud-stop (rule 7, no consumer). let esubti: *tinfo = nil; if (ati.sub != nil) { esubti = ati.sub; }; - for (esubti != nil && esubti.kind == tykind.TY_NAMED) { esubti = esubti.under; }; + esubti = tichase(esubti); let esz: i32 = 8; if (esubti != nil) { esz = esubti.size: i32; }; let badel: bool = false; @@ -34056,7 +34061,7 @@ fn cgreturn(c: *cgen, n: *node) void = { let aggret: bool = false; if (c.fnret != nil) { let rti: *tinfo = c.fnret.type_: *tinfo; - for (rti != nil && rti.kind == tykind.TY_NAMED) { rti = rti.under; }; + rti = tichase(rti); if (rti != nil) { if (rti.kind == tykind.TY_ARRAY) { aggret = true; }; if (rti.kind == tykind.TY_STRUCT) { aggret = true; }; @@ -34185,9 +34190,7 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // natural size (cstage esub->size). let esubti: *tinfo = nil; if (elemn != nil) { esubti = elemn.type_: *tinfo; }; - for (esubti != nil && esubti.kind == tykind.TY_NAMED) { - esubti = esubti.under; - }; + esubti = tichase(esubti); let isagg: bool = esubti != nil && (esubti.kind == tykind.TY_STRUCT || esubti.kind == tykind.TY_ARRAY @@ -34504,7 +34507,7 @@ fn cglet(c: *cgen, n: *node) void = { let nidx: i32 = -1; let nti: *tinfo = nil; if (c.fnret != nil) { nti = c.fnret.type_: *tinfo; }; - for (nti != nil && nti.kind == tykind.TY_NAMED) { nti = nti.under; }; + nti = tichase(nti); if (nti != nil) { if (nti.kind == tykind.TY_TAGGED) { let np: *tparam = nti.params; let nidx2: i32 = 0; @@ -34560,13 +34563,9 @@ fn cglet(c: *cgen, n: *node) void = { return; }; let lru: *tinfo = rhs.type_: *tinfo; - for (lru != nil && lru.kind == tykind.TY_NAMED) { - lru = lru.under; - }; + lru = tichase(lru); let llu: *tinfo = tn.type_: *tinfo; - for (llu != nil && llu.kind == tykind.TY_NAMED) { - llu = llu.under; - }; + llu = tichase(llu); let exact38: bool = false; if (lru != nil && lru == llu) { exact38 = true; } else { @@ -34849,7 +34848,7 @@ fn cglet(c: *cgen, n: *node) void = { if (rhs.kind == nkind.N_CALL && tn != nil && tn.kind == nkind.N_TARRAY) { let ati: *tinfo = tn.type_: *tinfo; - for (ati != nil && ati.kind == tykind.TY_NAMED) { ati = ati.under; }; + ati = tichase(ati); if (ati != nil) { let lsz: i32 = ati.size: i32; let tlm: i32 = lsz - (lsz / 8) * 8; @@ -34975,9 +34974,7 @@ fn cglet(c: *cgen, n: *node) void = { } else { let aggti: *tinfo = nil; if (tn != nil) { aggti = tn.type_: *tinfo; }; - for (aggti != nil && aggti.kind == tykind.TY_NAMED) { - aggti = aggti.under; - }; + aggti = tichase(aggti); if (aggti != nil) { if (aggti.kind == tykind.TY_ARRAY) { aggn = aggti.size: i32; @@ -35032,9 +35029,7 @@ fn cglet(c: *cgen, n: *node) void = { let idx: *node = rhs.rhs; let bu: *tinfo = nil; if (base != nil) { bu = base.type_: *tinfo; }; - for (bu != nil && bu.kind == tykind.TY_NAMED) { - bu = bu.under; - }; + bu = tichase(bu); if (base != nil && base.kind == nkind.N_IDENT && bu != nil && bu.kind == tykind.TY_ARRAY) { let esz: i32 = 1; @@ -35096,9 +35091,7 @@ fn cglet(c: *cgen, n: *node) void = { let bidx: *node = base.rhs; let abu: *tinfo = nil; if (ab != nil) { abu = ab.type_: *tinfo; }; - for (abu != nil && abu.kind == tykind.TY_NAMED) { - abu = abu.under; - }; + abu = tichase(abu); if (ab != nil && ab.kind == nkind.N_IDENT && abu != nil && abu.kind == tykind.TY_ARRAY) { let aesz: i32 = 1; @@ -35310,9 +35303,7 @@ fn cglet(c: *cgen, n: *node) void = { let szi: *structinfo = structlookupchain(c, n.lhs); if (szi != nil) { let ti: *tinfo = n.lhs.type_: *tinfo; - for (ti != nil && ti.kind == tykind.TY_NAMED) { - ti = ti.under; - }; + ti = tichase(ti); if (ti != nil) { zsz = ti.size: i32; }; }; }; @@ -35646,7 +35637,7 @@ fn cgmlet(c: *cgen, n: *node) void = { let rl: *local = localfindnode(c, rhs.str); if (rl != nil) { let rti: *tinfo = rl.tnode.type_: *tinfo; - for (rti != nil && rti.kind == tykind.TY_NAMED) { rti = rti.under; }; + rti = tichase(rti); if (rti != nil) { if (rti.kind == tykind.TY_TUPLE) { let srcoff: i32 = rl.off; let foff: i32 = 0; @@ -35952,7 +35943,7 @@ fn cgforrange(c: *cgen, n: *node) void = { // synthesis precedent above). if (slctn == nil && slc != nil) { let sti2: *tinfo = slc.type_: *tinfo; - for (sti2 != nil && sti2.kind == tykind.TY_NAMED) { sti2 = sti2.under; }; + sti2 = tichase(sti2); if (sti2 != nil) { if (sti2.kind == tykind.TY_SLICE || sti2.kind == tykind.TY_STR @@ -35988,9 +35979,7 @@ fn cgforrange(c: *cgen, n: *node) void = { if (slc != nil) { if (slc.kind != nkind.N_IDENT) { let stu70: *tinfo = slc.type_: *tinfo; - for (stu70 != nil && stu70.kind == tykind.TY_NAMED) { - stu70 = stu70.under; - }; + stu70 = tichase(stu70); let arr70: bool = false; if (stu70 != nil) { if (stu70.kind == tykind.TY_ARRAY) { @@ -38505,7 +38494,7 @@ fn emitfloatlitdata(c: *cgen, directive: str, name: str, module: str, fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, base: u64) bool = { let su: *tinfo = structt; - for (su != nil && su.kind == tykind.TY_NAMED) { su = su.under; }; + su = tichase(su); if (su == nil) { return false; }; if (su.kind != tykind.TY_STRUCT) { return false; }; let pos: u64 = base; @@ -38541,7 +38530,7 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, let vr: *node = v; for (vr != nil && vr.kind == nkind.N_CAST) { vr = vr.lhs; }; let fu: *tinfo = f.type_; - for (fu != nil && fu.kind == tykind.TY_NAMED) { fu = fu.under; }; + fu = tichase(fu); if (fu != nil && fu.kind == tykind.TY_STRUCT) { if (vr == nil) { let m: str = "emitstructlitbytes: nested struct field rhs nil (#129 A.2)\n"; @@ -38658,7 +38647,7 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, fn emitstructdata(c: *cgen, directive: str, name: str, module: str, structt: *tinfo, rhs: *node) bool = { let su: *tinfo = structt; - for (su != nil && su.kind == tykind.TY_NAMED) { su = su.under; }; + su = tichase(su); if (su == nil) { return false; }; if (su.kind != tykind.TY_STRUCT) { return false; }; emitline(directive); @@ -38691,13 +38680,13 @@ fn emitstructdata(c: *cgen, directive: str, name: str, module: str, fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, emit_phase: i32) bool = { let au: *tinfo = arrt; - for (au != nil && au.kind == tykind.TY_NAMED) { au = au.under; }; + au = tichase(au); if (au == nil) { return false; }; if (au.kind != tykind.TY_ARRAY) { return false; }; let esz: i32 = au.sub.size: i32; let alen: i32 = au.alen: i32; let eu: *tinfo = au.sub; - for (eu != nil && eu.kind == tykind.TY_NAMED) { eu = eu.under; }; + eu = tichase(eu); if (eu != nil && eu.kind == tykind.TY_STRUCT) { // Validate: every element must be N_STRUCTLIT (after N_CAST). @@ -38947,11 +38936,11 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, arrt: *tinfo, rhs: *node) bool = { let au: *tinfo = arrt; - for (au != nil && au.kind == tykind.TY_NAMED) { au = au.under; }; + au = tichase(au); if (au == nil) { return false; }; if (au.kind != tykind.TY_ARRAY) { return false; }; let eu: *tinfo = au.sub; - for (eu != nil && eu.kind == tykind.TY_NAMED) { eu = eu.under; }; + eu = tichase(eu); if (eu == nil) { return false; }; if (eu.kind != tykind.TY_STR) { return false; }; if (!streq(directive, "DATAW")) { return false; }; @@ -39065,7 +39054,7 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, fn emitarraydata(c: *cgen, directive: str, name: str, module: str, arrt: *tinfo, rhs: *node) bool = { let au: *tinfo = arrt; - for (au != nil && au.kind == tykind.TY_NAMED) { au = au.under; }; + au = tichase(au); if (au == nil) { return false; }; if (au.kind != tykind.TY_ARRAY) { return false; }; if (rhs == nil) { @@ -39109,7 +39098,7 @@ fn emitarraydata(c: *cgen, directive: str, name: str, module: str, fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, rhs: *node) void = { let su: *tinfo = slt; - for (su != nil && su.kind == tykind.TY_NAMED) { su = su.under; }; + su = tichase(su); // Defensive, mirrors cstage emit_slice_data's // `if (u == NULL || u->kind != TY_SLICE) return 0` (rule-10): the // letvarisslice gate already guarantees a slice, so this is @@ -39118,7 +39107,7 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, if (su == nil || su.kind != tykind.TY_SLICE) { return; }; let etype: *tinfo = su.sub; let eu: *tinfo = etype; - for (eu != nil && eu.kind == tykind.TY_NAMED) { eu = eu.under; }; + eu = tichase(eu); if (eu != nil) { if (eu.kind == tykind.TY_STR || eu.kind == tykind.TY_SLICE || eu.kind == tykind.TY_TAGGED) { @@ -39238,9 +39227,7 @@ fn emittupledata(c: *cgen, name: str, module: str, tt: *node, rhs: *node) bool = { let eti: *tinfo = nil; if (et != nil) { eti = et.type_: *tinfo; }; - for (eti != nil && eti.kind == tykind.TY_NAMED) { - eti = eti.under; - }; + eti = tichase(eti); if (eti != nil && eti.kind == tykind.TY_TAGGED) { return false; }; @@ -39647,9 +39634,7 @@ fn emitdefconstants(c: *cgen, file: *node) void = { if (r != nil) { if (r.kind == nkind.N_STRUCTLIT) { let st: *tinfo = d.lhs.type_: *tinfo; let su: *tinfo = st; - for (su != nil && su.kind == tykind.TY_NAMED) { - su = su.under; - }; + su = tichase(su); if (su != nil) { if (su.kind == tykind.TY_STRUCT) { emitstructdata(c, "DATA", @@ -39662,9 +39647,7 @@ fn emitdefconstants(c: *cgen, file: *node) void = { if (r != nil) { if (r.kind == nkind.N_ARRLIT) { let at: *tinfo = d.lhs.type_: *tinfo; let au: *tinfo = at; - for (au != nil && au.kind == tykind.TY_NAMED) { - au = au.under; - }; + au = tichase(au); if (au != nil) { if (au.kind == tykind.TY_ARRAY) { emitarraydata(c, "DATA", diff --git a/selfhost/cmd/wcc/cgen.ww b/selfhost/cmd/wcc/cgen.ww index dac157cd..fccecad7 100644 --- a/selfhost/cmd/wcc/cgen.ww +++ b/selfhost/cmd/wcc/cgen.ww @@ -1502,7 +1502,7 @@ fn emitfloatlitdata(c: *cgen, directive: str, name: str, module: str, fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, base: u64) bool = { let su: *tinfo = structt; - for (su != nil && su.kind == tykind.TY_NAMED) { su = su.under; }; + su = tichase(su); if (su == nil) { return false; }; if (su.kind != tykind.TY_STRUCT) { return false; }; let pos: u64 = base; @@ -1538,7 +1538,7 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, let vr: *node = v; for (vr != nil && vr.kind == nkind.N_CAST) { vr = vr.lhs; }; let fu: *tinfo = f.type_; - for (fu != nil && fu.kind == tykind.TY_NAMED) { fu = fu.under; }; + fu = tichase(fu); if (fu != nil && fu.kind == tykind.TY_STRUCT) { if (vr == nil) { let m: str = "emitstructlitbytes: nested struct field rhs nil (#129 A.2)\n"; @@ -1655,7 +1655,7 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, fn emitstructdata(c: *cgen, directive: str, name: str, module: str, structt: *tinfo, rhs: *node) bool = { let su: *tinfo = structt; - for (su != nil && su.kind == tykind.TY_NAMED) { su = su.under; }; + su = tichase(su); if (su == nil) { return false; }; if (su.kind != tykind.TY_STRUCT) { return false; }; emitline(directive); @@ -1688,13 +1688,13 @@ fn emitstructdata(c: *cgen, directive: str, name: str, module: str, fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, emit_phase: i32) bool = { let au: *tinfo = arrt; - for (au != nil && au.kind == tykind.TY_NAMED) { au = au.under; }; + au = tichase(au); if (au == nil) { return false; }; if (au.kind != tykind.TY_ARRAY) { return false; }; let esz: i32 = au.sub.size: i32; let alen: i32 = au.alen: i32; let eu: *tinfo = au.sub; - for (eu != nil && eu.kind == tykind.TY_NAMED) { eu = eu.under; }; + eu = tichase(eu); if (eu != nil && eu.kind == tykind.TY_STRUCT) { // Validate: every element must be N_STRUCTLIT (after N_CAST). @@ -1944,11 +1944,11 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, arrt: *tinfo, rhs: *node) bool = { let au: *tinfo = arrt; - for (au != nil && au.kind == tykind.TY_NAMED) { au = au.under; }; + au = tichase(au); if (au == nil) { return false; }; if (au.kind != tykind.TY_ARRAY) { return false; }; let eu: *tinfo = au.sub; - for (eu != nil && eu.kind == tykind.TY_NAMED) { eu = eu.under; }; + eu = tichase(eu); if (eu == nil) { return false; }; if (eu.kind != tykind.TY_STR) { return false; }; if (!streq(directive, "DATAW")) { return false; }; @@ -2062,7 +2062,7 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, fn emitarraydata(c: *cgen, directive: str, name: str, module: str, arrt: *tinfo, rhs: *node) bool = { let au: *tinfo = arrt; - for (au != nil && au.kind == tykind.TY_NAMED) { au = au.under; }; + au = tichase(au); if (au == nil) { return false; }; if (au.kind != tykind.TY_ARRAY) { return false; }; if (rhs == nil) { @@ -2106,7 +2106,7 @@ fn emitarraydata(c: *cgen, directive: str, name: str, module: str, fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, rhs: *node) void = { let su: *tinfo = slt; - for (su != nil && su.kind == tykind.TY_NAMED) { su = su.under; }; + su = tichase(su); // Defensive, mirrors cstage emit_slice_data's // `if (u == NULL || u->kind != TY_SLICE) return 0` (rule-10): the // letvarisslice gate already guarantees a slice, so this is @@ -2115,7 +2115,7 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, if (su == nil || su.kind != tykind.TY_SLICE) { return; }; let etype: *tinfo = su.sub; let eu: *tinfo = etype; - for (eu != nil && eu.kind == tykind.TY_NAMED) { eu = eu.under; }; + eu = tichase(eu); if (eu != nil) { if (eu.kind == tykind.TY_STR || eu.kind == tykind.TY_SLICE || eu.kind == tykind.TY_TAGGED) { @@ -2235,9 +2235,7 @@ fn emittupledata(c: *cgen, name: str, module: str, tt: *node, rhs: *node) bool = { let eti: *tinfo = nil; if (et != nil) { eti = et.type_: *tinfo; }; - for (eti != nil && eti.kind == tykind.TY_NAMED) { - eti = eti.under; - }; + eti = tichase(eti); if (eti != nil && eti.kind == tykind.TY_TAGGED) { return false; }; @@ -2644,9 +2642,7 @@ fn emitdefconstants(c: *cgen, file: *node) void = { if (r != nil) { if (r.kind == nkind.N_STRUCTLIT) { let st: *tinfo = d.lhs.type_: *tinfo; let su: *tinfo = st; - for (su != nil && su.kind == tykind.TY_NAMED) { - su = su.under; - }; + su = tichase(su); if (su != nil) { if (su.kind == tykind.TY_STRUCT) { emitstructdata(c, "DATA", @@ -2659,9 +2655,7 @@ fn emitdefconstants(c: *cgen, file: *node) void = { if (r != nil) { if (r.kind == nkind.N_ARRLIT) { let at: *tinfo = d.lhs.type_: *tinfo; let au: *tinfo = at; - for (au != nil && au.kind == tykind.TY_NAMED) { - au = au.under; - }; + au = tichase(au); if (au != nil) { if (au.kind == tykind.TY_ARRAY) { emitarraydata(c, "DATA", diff --git a/selfhost/cmd/wcc/cgenstmt.ww b/selfhost/cmd/wcc/cgenstmt.ww index 28608fae..8ac148b8 100644 --- a/selfhost/cmd/wcc/cgenstmt.ww +++ b/selfhost/cmd/wcc/cgenstmt.ww @@ -146,7 +146,7 @@ fn tupsse(i: i32) str = { // tuple_eslot (cmd/w6c/cgen.c). export fn tupeslot(ti: *tinfo) i32 = { let t: *tinfo = ti; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); if (t == nil) { return 8; }; if (t.kind == tykind.TY_VOID) { return 0; }; // a literal tuple's stamped element can be untyped_str (size 0) — @@ -322,7 +322,7 @@ fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { return (tyslicesize() / 8i64): i32; }; let t: *tinfo = e.type_: *tinfo; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); if (t != nil && (t.kind == tykind.TY_TAGGED || t.kind == tykind.TY_VOID)) { return tupeslotn(e) / 8; @@ -349,7 +349,7 @@ fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { // the slot — loud (rule 7, the #23/#40 widening family). fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { let t: *tinfo = e.type_: *tinfo; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); let etagged: bool = false; if (t != nil) { if (t.kind == tykind.TY_TAGGED) { etagged = true; }; }; if (dtn != nil) { @@ -529,7 +529,7 @@ fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { let el: *ttupleelem = tu.tupleelems; for (el != nil) { let et: *tinfo = el.type_; - for (et != nil && et.kind == tykind.TY_NAMED) { et = et.under; }; + et = tichase(et); if (et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64)) { ssecount = ssecount + 1; } else { @@ -548,7 +548,7 @@ fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { el = tu.tupleelems; for (el != nil) { let et: *tinfo = el.type_; - for (et != nil && et.kind == tykind.TY_NAMED) { et = et.under; }; + et = tichase(et); let isflt: bool = et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64); let eslot: i32 = tupeslot(el.type_); if (isflt) { @@ -591,7 +591,7 @@ fn cgtaggedtuplepayloadshift(c: *cgen, tup: *tinfo) void = { let el: *ttupleelem = tup.tupleelems; for (el != nil) { let et: *tinfo = el.type_; - for (et != nil && et.kind == tykind.TY_NAMED) { et = et.under; }; + et = tichase(et); let isflt: bool = et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64); if (isflt || tupeslot(el.type_) != 8) { let msg: str = "tuple-in-union ? unwrap: float/slice/str/tagged payload element needs SysV per-eightbyte classification (see #243); only integer tuple payloads supported\n"; @@ -712,7 +712,7 @@ fn cgreturn(c: *cgen, n: *node) void = { for (we != nil) { let dt: *tinfo = nil; if (pt != nil) { dt = pt.lhs.type_: *tinfo; }; - for (dt != nil && dt.kind == tykind.TY_NAMED) { dt = dt.under; }; + dt = tichase(dt); if (dt != nil && dt.kind == tykind.TY_TAGGED) { // #22b (task #28): MEMORY-class tagged // element — the whole box copies through @@ -729,7 +729,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_RETURN over-cap tagged arm. let eslot: i32 = tupeslotn(pt.lhs); let eu: *tinfo = we.type_: *tinfo; - for (eu != nil && eu.kind == tykind.TY_NAMED) { eu = eu.under; }; + eu = tichase(eu); let eoff: i32 = 0; if (we.kind == nkind.N_IDENT && eu != nil) { if (eu.kind == tykind.TY_TAGGED && tupeslotn(we) == eslot) { @@ -935,9 +935,9 @@ fn cgreturn(c: *cgen, n: *node) void = { let forwardtagged: bool = false; if ((rhs.kind == nkind.N_CALL || rhs.kind == nkind.N_INDEX || rhs.kind == nkind.N_DOT) && rhs.type_ != nil && c.fnret != nil && c.fnret.type_ != nil) { let ru: *tinfo = rhs.type_: *tinfo; - for (ru != nil && ru.kind == tykind.TY_NAMED) { ru = ru.under; }; + ru = tichase(ru); let fu: *tinfo = c.fnret.type_: *tinfo; - for (fu != nil && fu.kind == tykind.TY_NAMED) { fu = fu.under; }; + fu = tichase(fu); if (ru != nil && fu != nil && ru.kind == tykind.TY_TAGGED && fu.kind == tykind.TY_TAGGED) { if (ru == fu) { forwardtagged = true; @@ -982,9 +982,7 @@ fn cgreturn(c: *cgen, n: *node) void = { return; }; let ru38: *tinfo = rhs.type_: *tinfo; - for (ru38 != nil && ru38.kind == tykind.TY_NAMED) { - ru38 = ru38.under; - }; + ru38 = tichase(ru38); if (ru38 != nil) { // #37 wired the N_INDEX/N_DOT mem-read into // the widener; the remaining >32B kinds stay @@ -1574,7 +1572,7 @@ fn cgreturn(c: *cgen, n: *node) void = { if (rhs.op == tkind.TK_STAR) { arrok = true; }; }; let ati: *tinfo = c.fnret.type_: *tinfo; - for (ati != nil && ati.kind == tykind.TY_NAMED) { ati = ati.under; }; + ati = tichase(ati); if (arrok && ati != nil) { let rsz: i32 = ati.size: i32; if (rsz <= 24) { @@ -1626,7 +1624,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // elements loud-stop (rule 7, no consumer). let esubti: *tinfo = nil; if (ati.sub != nil) { esubti = ati.sub; }; - for (esubti != nil && esubti.kind == tykind.TY_NAMED) { esubti = esubti.under; }; + esubti = tichase(esubti); let esz: i32 = 8; if (esubti != nil) { esz = esubti.size: i32; }; let badel: bool = false; @@ -1779,7 +1777,7 @@ fn cgreturn(c: *cgen, n: *node) void = { let aggret: bool = false; if (c.fnret != nil) { let rti: *tinfo = c.fnret.type_: *tinfo; - for (rti != nil && rti.kind == tykind.TY_NAMED) { rti = rti.under; }; + rti = tichase(rti); if (rti != nil) { if (rti.kind == tykind.TY_ARRAY) { aggret = true; }; if (rti.kind == tykind.TY_STRUCT) { aggret = true; }; @@ -1908,9 +1906,7 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // natural size (cstage esub->size). let esubti: *tinfo = nil; if (elemn != nil) { esubti = elemn.type_: *tinfo; }; - for (esubti != nil && esubti.kind == tykind.TY_NAMED) { - esubti = esubti.under; - }; + esubti = tichase(esubti); let isagg: bool = esubti != nil && (esubti.kind == tykind.TY_STRUCT || esubti.kind == tykind.TY_ARRAY @@ -2227,7 +2223,7 @@ fn cglet(c: *cgen, n: *node) void = { let nidx: i32 = -1; let nti: *tinfo = nil; if (c.fnret != nil) { nti = c.fnret.type_: *tinfo; }; - for (nti != nil && nti.kind == tykind.TY_NAMED) { nti = nti.under; }; + nti = tichase(nti); if (nti != nil) { if (nti.kind == tykind.TY_TAGGED) { let np: *tparam = nti.params; let nidx2: i32 = 0; @@ -2283,13 +2279,9 @@ fn cglet(c: *cgen, n: *node) void = { return; }; let lru: *tinfo = rhs.type_: *tinfo; - for (lru != nil && lru.kind == tykind.TY_NAMED) { - lru = lru.under; - }; + lru = tichase(lru); let llu: *tinfo = tn.type_: *tinfo; - for (llu != nil && llu.kind == tykind.TY_NAMED) { - llu = llu.under; - }; + llu = tichase(llu); let exact38: bool = false; if (lru != nil && lru == llu) { exact38 = true; } else { @@ -2572,7 +2564,7 @@ fn cglet(c: *cgen, n: *node) void = { if (rhs.kind == nkind.N_CALL && tn != nil && tn.kind == nkind.N_TARRAY) { let ati: *tinfo = tn.type_: *tinfo; - for (ati != nil && ati.kind == tykind.TY_NAMED) { ati = ati.under; }; + ati = tichase(ati); if (ati != nil) { let lsz: i32 = ati.size: i32; let tlm: i32 = lsz - (lsz / 8) * 8; @@ -2698,9 +2690,7 @@ fn cglet(c: *cgen, n: *node) void = { } else { let aggti: *tinfo = nil; if (tn != nil) { aggti = tn.type_: *tinfo; }; - for (aggti != nil && aggti.kind == tykind.TY_NAMED) { - aggti = aggti.under; - }; + aggti = tichase(aggti); if (aggti != nil) { if (aggti.kind == tykind.TY_ARRAY) { aggn = aggti.size: i32; @@ -2755,9 +2745,7 @@ fn cglet(c: *cgen, n: *node) void = { let idx: *node = rhs.rhs; let bu: *tinfo = nil; if (base != nil) { bu = base.type_: *tinfo; }; - for (bu != nil && bu.kind == tykind.TY_NAMED) { - bu = bu.under; - }; + bu = tichase(bu); if (base != nil && base.kind == nkind.N_IDENT && bu != nil && bu.kind == tykind.TY_ARRAY) { let esz: i32 = 1; @@ -2819,9 +2807,7 @@ fn cglet(c: *cgen, n: *node) void = { let bidx: *node = base.rhs; let abu: *tinfo = nil; if (ab != nil) { abu = ab.type_: *tinfo; }; - for (abu != nil && abu.kind == tykind.TY_NAMED) { - abu = abu.under; - }; + abu = tichase(abu); if (ab != nil && ab.kind == nkind.N_IDENT && abu != nil && abu.kind == tykind.TY_ARRAY) { let aesz: i32 = 1; @@ -3033,9 +3019,7 @@ fn cglet(c: *cgen, n: *node) void = { let szi: *structinfo = structlookupchain(c, n.lhs); if (szi != nil) { let ti: *tinfo = n.lhs.type_: *tinfo; - for (ti != nil && ti.kind == tykind.TY_NAMED) { - ti = ti.under; - }; + ti = tichase(ti); if (ti != nil) { zsz = ti.size: i32; }; }; }; @@ -3369,7 +3353,7 @@ fn cgmlet(c: *cgen, n: *node) void = { let rl: *local = localfindnode(c, rhs.str); if (rl != nil) { let rti: *tinfo = rl.tnode.type_: *tinfo; - for (rti != nil && rti.kind == tykind.TY_NAMED) { rti = rti.under; }; + rti = tichase(rti); if (rti != nil) { if (rti.kind == tykind.TY_TUPLE) { let srcoff: i32 = rl.off; let foff: i32 = 0; @@ -3675,7 +3659,7 @@ fn cgforrange(c: *cgen, n: *node) void = { // synthesis precedent above). if (slctn == nil && slc != nil) { let sti2: *tinfo = slc.type_: *tinfo; - for (sti2 != nil && sti2.kind == tykind.TY_NAMED) { sti2 = sti2.under; }; + sti2 = tichase(sti2); if (sti2 != nil) { if (sti2.kind == tykind.TY_SLICE || sti2.kind == tykind.TY_STR @@ -3711,9 +3695,7 @@ fn cgforrange(c: *cgen, n: *node) void = { if (slc != nil) { if (slc.kind != nkind.N_IDENT) { let stu70: *tinfo = slc.type_: *tinfo; - for (stu70 != nil && stu70.kind == tykind.TY_NAMED) { - stu70 = stu70.under; - }; + stu70 = tichase(stu70); let arr70: bool = false; if (stu70 != nil) { if (stu70.kind == tykind.TY_ARRAY) { diff --git a/selfhost/cmd/wcc/cgenutil.ww b/selfhost/cmd/wcc/cgenutil.ww index 77efff7d..a75428e6 100644 --- a/selfhost/cmd/wcc/cgenutil.ww +++ b/selfhost/cmd/wcc/cgenutil.ww @@ -2751,6 +2751,10 @@ export fn nullableptrtag(t: *node) i32 = { for (p != nil) { let vt: *tinfo = p.type_; if (vt != nil) { + // peel-ok: single peel PROBE-CLEARED (batch-2 c3-B2, + // 018ef66) — constructible variant params never carry + // 2+-level NAMED at this scan; cs twin nullable_ptr_tag + // (cmd/w6c/cgen.c:747) keeps the identical single peel. if (vt.kind == tykind.TY_NAMED) { vt = vt.under; }; if (vt != nil) { if (vt.kind == tykind.TY_PTR) { return i; }; diff --git a/selfhost/cmd/wcc/check.ww b/selfhost/cmd/wcc/check.ww index 174764e5..61683e3d 100644 --- a/selfhost/cmd/wcc/check.ww +++ b/selfhost/cmd/wcc/check.ww @@ -1624,7 +1624,7 @@ fn tupleelemslot(pt: *tinfo) u64 = { // now fires on aliased operands; byte-id holds because it collapses // NAMED to the alias-invariant underlying this read consumes. let t: *tinfo = pt; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); if (t == nil) { return 8u64; }; let pk: tykind = t.kind; if (pk == tykind.TY_VOID) { return 0u64; }; @@ -1670,7 +1670,7 @@ fn fieldslotsize(ft: *tinfo) u64 = { // now fires on aliased operands; byte-id holds because it collapses // NAMED to the alias-invariant underlying this read consumes. let t: *tinfo = ft; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); if (t == nil) { return 8u64; }; let fk: tykind = t.kind; if (fk == tykind.TY_STRUCT) { return t.slotsize; }; @@ -1802,6 +1802,9 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { under = c.tc.tyerr; }; named.resolving = 0; + // peellint-ok: construction — the one + // WRITE that builds the NAMED link; + // not a peel, can't route via tichase. named.under = under; if (under != nil) { named.size = under.size; @@ -4108,7 +4111,7 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { let at: *tinfo = tinfofornode(c, arrtn); let et: *tinfo = nil; if (at != nil) { et = at.sub; }; - for (et != nil && et.kind == tykind.TY_NAMED) { et = et.under; }; + et = tichase(et); let e: *node = rhs.list; for (e != nil) { let skip: bool = false; diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index 8ef7b5df..c7263664 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -11896,7 +11896,7 @@ fn tupleelemslot(pt: *tinfo) u64 = { // now fires on aliased operands; byte-id holds because it collapses // NAMED to the alias-invariant underlying this read consumes. let t: *tinfo = pt; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); if (t == nil) { return 8u64; }; let pk: tykind = t.kind; if (pk == tykind.TY_VOID) { return 0u64; }; @@ -11942,7 +11942,7 @@ fn fieldslotsize(ft: *tinfo) u64 = { // now fires on aliased operands; byte-id holds because it collapses // NAMED to the alias-invariant underlying this read consumes. let t: *tinfo = ft; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); if (t == nil) { return 8u64; }; let fk: tykind = t.kind; if (fk == tykind.TY_STRUCT) { return t.slotsize; }; @@ -12074,6 +12074,9 @@ fn tinfofornode(c: *checker, n: *node) *tinfo = { under = c.tc.tyerr; }; named.resolving = 0; + // peellint-ok: construction — the one + // WRITE that builds the NAMED link; + // not a peel, can't route via tichase. named.under = under; if (under != nil) { named.size = under.size; @@ -14380,7 +14383,7 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = { let at: *tinfo = tinfofornode(c, arrtn); let et: *tinfo = nil; if (at != nil) { et = at.sub; }; - for (et != nil && et.kind == tykind.TY_NAMED) { et = et.under; }; + et = tichase(et); let e: *node = rhs.list; for (e != nil) { let skip: bool = false; @@ -18823,6 +18826,10 @@ export fn nullableptrtag(t: *node) i32 = { for (p != nil) { let vt: *tinfo = p.type_; if (vt != nil) { + // peel-ok: single peel PROBE-CLEARED (batch-2 c3-B2, + // 018ef66) — constructible variant params never carry + // 2+-level NAMED at this scan; cs twin nullable_ptr_tag + // (cmd/w6c/cgen.c:747) keeps the identical single peel. if (vt.kind == tykind.TY_NAMED) { vt = vt.under; }; if (vt != nil) { if (vt.kind == tykind.TY_PTR) { return i; }; @@ -32423,7 +32430,7 @@ fn tupsse(i: i32) str = { // tuple_eslot (cmd/w6c/cgen.c). export fn tupeslot(ti: *tinfo) i32 = { let t: *tinfo = ti; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); if (t == nil) { return 8; }; if (t.kind == tykind.TY_VOID) { return 0; }; // a literal tuple's stamped element can be untyped_str (size 0) — @@ -32599,7 +32606,7 @@ fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { return (tyslicesize() / 8i64): i32; }; let t: *tinfo = e.type_: *tinfo; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); if (t != nil && (t.kind == tykind.TY_TAGGED || t.kind == tykind.TY_VOID)) { return tupeslotn(e) / 8; @@ -32626,7 +32633,7 @@ fn tuplitgpwords(c: *cgen, e: *node, dtn: *node) i32 = { // the slot — loud (rule 7, the #23/#40 widening family). fn tuplitpushelem(c: *cgen, e: *node, dtn: *node) void = { let t: *tinfo = e.type_: *tinfo; - for (t != nil && t.kind == tykind.TY_NAMED) { t = t.under; }; + t = tichase(t); let etagged: bool = false; if (t != nil) { if (t.kind == tykind.TY_TAGGED) { etagged = true; }; }; if (dtn != nil) { @@ -32806,7 +32813,7 @@ fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { let el: *ttupleelem = tu.tupleelems; for (el != nil) { let et: *tinfo = el.type_; - for (et != nil && et.kind == tykind.TY_NAMED) { et = et.under; }; + et = tichase(et); if (et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64)) { ssecount = ssecount + 1; } else { @@ -32825,7 +32832,7 @@ fn cgtupleslottocursor(c: *cgen, srcoff: i32, tu: *tinfo) void = { el = tu.tupleelems; for (el != nil) { let et: *tinfo = el.type_; - for (et != nil && et.kind == tykind.TY_NAMED) { et = et.under; }; + et = tichase(et); let isflt: bool = et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64); let eslot: i32 = tupeslot(el.type_); if (isflt) { @@ -32868,7 +32875,7 @@ fn cgtaggedtuplepayloadshift(c: *cgen, tup: *tinfo) void = { let el: *ttupleelem = tup.tupleelems; for (el != nil) { let et: *tinfo = el.type_; - for (et != nil && et.kind == tykind.TY_NAMED) { et = et.under; }; + et = tichase(et); let isflt: bool = et != nil && (et.kind == tykind.TY_F32 || et.kind == tykind.TY_F64); if (isflt || tupeslot(el.type_) != 8) { let msg: str = "tuple-in-union ? unwrap: float/slice/str/tagged payload element needs SysV per-eightbyte classification (see #243); only integer tuple payloads supported\n"; @@ -32989,7 +32996,7 @@ fn cgreturn(c: *cgen, n: *node) void = { for (we != nil) { let dt: *tinfo = nil; if (pt != nil) { dt = pt.lhs.type_: *tinfo; }; - for (dt != nil && dt.kind == tykind.TY_NAMED) { dt = dt.under; }; + dt = tichase(dt); if (dt != nil && dt.kind == tykind.TY_TAGGED) { // #22b (task #28): MEMORY-class tagged // element — the whole box copies through @@ -33006,7 +33013,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // N_RETURN over-cap tagged arm. let eslot: i32 = tupeslotn(pt.lhs); let eu: *tinfo = we.type_: *tinfo; - for (eu != nil && eu.kind == tykind.TY_NAMED) { eu = eu.under; }; + eu = tichase(eu); let eoff: i32 = 0; if (we.kind == nkind.N_IDENT && eu != nil) { if (eu.kind == tykind.TY_TAGGED && tupeslotn(we) == eslot) { @@ -33212,9 +33219,9 @@ fn cgreturn(c: *cgen, n: *node) void = { let forwardtagged: bool = false; if ((rhs.kind == nkind.N_CALL || rhs.kind == nkind.N_INDEX || rhs.kind == nkind.N_DOT) && rhs.type_ != nil && c.fnret != nil && c.fnret.type_ != nil) { let ru: *tinfo = rhs.type_: *tinfo; - for (ru != nil && ru.kind == tykind.TY_NAMED) { ru = ru.under; }; + ru = tichase(ru); let fu: *tinfo = c.fnret.type_: *tinfo; - for (fu != nil && fu.kind == tykind.TY_NAMED) { fu = fu.under; }; + fu = tichase(fu); if (ru != nil && fu != nil && ru.kind == tykind.TY_TAGGED && fu.kind == tykind.TY_TAGGED) { if (ru == fu) { forwardtagged = true; @@ -33259,9 +33266,7 @@ fn cgreturn(c: *cgen, n: *node) void = { return; }; let ru38: *tinfo = rhs.type_: *tinfo; - for (ru38 != nil && ru38.kind == tykind.TY_NAMED) { - ru38 = ru38.under; - }; + ru38 = tichase(ru38); if (ru38 != nil) { // #37 wired the N_INDEX/N_DOT mem-read into // the widener; the remaining >32B kinds stay @@ -33851,7 +33856,7 @@ fn cgreturn(c: *cgen, n: *node) void = { if (rhs.op == tkind.TK_STAR) { arrok = true; }; }; let ati: *tinfo = c.fnret.type_: *tinfo; - for (ati != nil && ati.kind == tykind.TY_NAMED) { ati = ati.under; }; + ati = tichase(ati); if (arrok && ati != nil) { let rsz: i32 = ati.size: i32; if (rsz <= 24) { @@ -33903,7 +33908,7 @@ fn cgreturn(c: *cgen, n: *node) void = { // elements loud-stop (rule 7, no consumer). let esubti: *tinfo = nil; if (ati.sub != nil) { esubti = ati.sub; }; - for (esubti != nil && esubti.kind == tykind.TY_NAMED) { esubti = esubti.under; }; + esubti = tichase(esubti); let esz: i32 = 8; if (esubti != nil) { esz = esubti.size: i32; }; let badel: bool = false; @@ -34056,7 +34061,7 @@ fn cgreturn(c: *cgen, n: *node) void = { let aggret: bool = false; if (c.fnret != nil) { let rti: *tinfo = c.fnret.type_: *tinfo; - for (rti != nil && rti.kind == tykind.TY_NAMED) { rti = rti.under; }; + rti = tichase(rti); if (rti != nil) { if (rti.kind == tykind.TY_ARRAY) { aggret = true; }; if (rti.kind == tykind.TY_STRUCT) { aggret = true; }; @@ -34185,9 +34190,7 @@ fn cgarrlitfillbp(c: *cgen, arrtn: *node, rhs: *node, off: i32) void = { // natural size (cstage esub->size). let esubti: *tinfo = nil; if (elemn != nil) { esubti = elemn.type_: *tinfo; }; - for (esubti != nil && esubti.kind == tykind.TY_NAMED) { - esubti = esubti.under; - }; + esubti = tichase(esubti); let isagg: bool = esubti != nil && (esubti.kind == tykind.TY_STRUCT || esubti.kind == tykind.TY_ARRAY @@ -34504,7 +34507,7 @@ fn cglet(c: *cgen, n: *node) void = { let nidx: i32 = -1; let nti: *tinfo = nil; if (c.fnret != nil) { nti = c.fnret.type_: *tinfo; }; - for (nti != nil && nti.kind == tykind.TY_NAMED) { nti = nti.under; }; + nti = tichase(nti); if (nti != nil) { if (nti.kind == tykind.TY_TAGGED) { let np: *tparam = nti.params; let nidx2: i32 = 0; @@ -34560,13 +34563,9 @@ fn cglet(c: *cgen, n: *node) void = { return; }; let lru: *tinfo = rhs.type_: *tinfo; - for (lru != nil && lru.kind == tykind.TY_NAMED) { - lru = lru.under; - }; + lru = tichase(lru); let llu: *tinfo = tn.type_: *tinfo; - for (llu != nil && llu.kind == tykind.TY_NAMED) { - llu = llu.under; - }; + llu = tichase(llu); let exact38: bool = false; if (lru != nil && lru == llu) { exact38 = true; } else { @@ -34849,7 +34848,7 @@ fn cglet(c: *cgen, n: *node) void = { if (rhs.kind == nkind.N_CALL && tn != nil && tn.kind == nkind.N_TARRAY) { let ati: *tinfo = tn.type_: *tinfo; - for (ati != nil && ati.kind == tykind.TY_NAMED) { ati = ati.under; }; + ati = tichase(ati); if (ati != nil) { let lsz: i32 = ati.size: i32; let tlm: i32 = lsz - (lsz / 8) * 8; @@ -34975,9 +34974,7 @@ fn cglet(c: *cgen, n: *node) void = { } else { let aggti: *tinfo = nil; if (tn != nil) { aggti = tn.type_: *tinfo; }; - for (aggti != nil && aggti.kind == tykind.TY_NAMED) { - aggti = aggti.under; - }; + aggti = tichase(aggti); if (aggti != nil) { if (aggti.kind == tykind.TY_ARRAY) { aggn = aggti.size: i32; @@ -35032,9 +35029,7 @@ fn cglet(c: *cgen, n: *node) void = { let idx: *node = rhs.rhs; let bu: *tinfo = nil; if (base != nil) { bu = base.type_: *tinfo; }; - for (bu != nil && bu.kind == tykind.TY_NAMED) { - bu = bu.under; - }; + bu = tichase(bu); if (base != nil && base.kind == nkind.N_IDENT && bu != nil && bu.kind == tykind.TY_ARRAY) { let esz: i32 = 1; @@ -35096,9 +35091,7 @@ fn cglet(c: *cgen, n: *node) void = { let bidx: *node = base.rhs; let abu: *tinfo = nil; if (ab != nil) { abu = ab.type_: *tinfo; }; - for (abu != nil && abu.kind == tykind.TY_NAMED) { - abu = abu.under; - }; + abu = tichase(abu); if (ab != nil && ab.kind == nkind.N_IDENT && abu != nil && abu.kind == tykind.TY_ARRAY) { let aesz: i32 = 1; @@ -35310,9 +35303,7 @@ fn cglet(c: *cgen, n: *node) void = { let szi: *structinfo = structlookupchain(c, n.lhs); if (szi != nil) { let ti: *tinfo = n.lhs.type_: *tinfo; - for (ti != nil && ti.kind == tykind.TY_NAMED) { - ti = ti.under; - }; + ti = tichase(ti); if (ti != nil) { zsz = ti.size: i32; }; }; }; @@ -35646,7 +35637,7 @@ fn cgmlet(c: *cgen, n: *node) void = { let rl: *local = localfindnode(c, rhs.str); if (rl != nil) { let rti: *tinfo = rl.tnode.type_: *tinfo; - for (rti != nil && rti.kind == tykind.TY_NAMED) { rti = rti.under; }; + rti = tichase(rti); if (rti != nil) { if (rti.kind == tykind.TY_TUPLE) { let srcoff: i32 = rl.off; let foff: i32 = 0; @@ -35952,7 +35943,7 @@ fn cgforrange(c: *cgen, n: *node) void = { // synthesis precedent above). if (slctn == nil && slc != nil) { let sti2: *tinfo = slc.type_: *tinfo; - for (sti2 != nil && sti2.kind == tykind.TY_NAMED) { sti2 = sti2.under; }; + sti2 = tichase(sti2); if (sti2 != nil) { if (sti2.kind == tykind.TY_SLICE || sti2.kind == tykind.TY_STR @@ -35988,9 +35979,7 @@ fn cgforrange(c: *cgen, n: *node) void = { if (slc != nil) { if (slc.kind != nkind.N_IDENT) { let stu70: *tinfo = slc.type_: *tinfo; - for (stu70 != nil && stu70.kind == tykind.TY_NAMED) { - stu70 = stu70.under; - }; + stu70 = tichase(stu70); let arr70: bool = false; if (stu70 != nil) { if (stu70.kind == tykind.TY_ARRAY) { @@ -38505,7 +38494,7 @@ fn emitfloatlitdata(c: *cgen, directive: str, name: str, module: str, fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, base: u64) bool = { let su: *tinfo = structt; - for (su != nil && su.kind == tykind.TY_NAMED) { su = su.under; }; + su = tichase(su); if (su == nil) { return false; }; if (su.kind != tykind.TY_STRUCT) { return false; }; let pos: u64 = base; @@ -38541,7 +38530,7 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, let vr: *node = v; for (vr != nil && vr.kind == nkind.N_CAST) { vr = vr.lhs; }; let fu: *tinfo = f.type_; - for (fu != nil && fu.kind == tykind.TY_NAMED) { fu = fu.under; }; + fu = tichase(fu); if (fu != nil && fu.kind == tykind.TY_STRUCT) { if (vr == nil) { let m: str = "emitstructlitbytes: nested struct field rhs nil (#129 A.2)\n"; @@ -38658,7 +38647,7 @@ fn emitstructlitbytes(c: *cgen, structt: *tinfo, rhs: *node, fn emitstructdata(c: *cgen, directive: str, name: str, module: str, structt: *tinfo, rhs: *node) bool = { let su: *tinfo = structt; - for (su != nil && su.kind == tykind.TY_NAMED) { su = su.under; }; + su = tichase(su); if (su == nil) { return false; }; if (su.kind != tykind.TY_STRUCT) { return false; }; emitline(directive); @@ -38691,13 +38680,13 @@ fn emitstructdata(c: *cgen, directive: str, name: str, module: str, fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, emit_phase: i32) bool = { let au: *tinfo = arrt; - for (au != nil && au.kind == tykind.TY_NAMED) { au = au.under; }; + au = tichase(au); if (au == nil) { return false; }; if (au.kind != tykind.TY_ARRAY) { return false; }; let esz: i32 = au.sub.size: i32; let alen: i32 = au.alen: i32; let eu: *tinfo = au.sub; - for (eu != nil && eu.kind == tykind.TY_NAMED) { eu = eu.under; }; + eu = tichase(eu); if (eu != nil && eu.kind == tykind.TY_STRUCT) { // Validate: every element must be N_STRUCTLIT (after N_CAST). @@ -38947,11 +38936,11 @@ fn emitarraylitbytes(c: *cgen, arrt: *tinfo, rhs: *node, fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, arrt: *tinfo, rhs: *node) bool = { let au: *tinfo = arrt; - for (au != nil && au.kind == tykind.TY_NAMED) { au = au.under; }; + au = tichase(au); if (au == nil) { return false; }; if (au.kind != tykind.TY_ARRAY) { return false; }; let eu: *tinfo = au.sub; - for (eu != nil && eu.kind == tykind.TY_NAMED) { eu = eu.under; }; + eu = tichase(eu); if (eu == nil) { return false; }; if (eu.kind != tykind.TY_STR) { return false; }; if (!streq(directive, "DATAW")) { return false; }; @@ -39065,7 +39054,7 @@ fn emitstrarraydata(c: *cgen, directive: str, name: str, module: str, fn emitarraydata(c: *cgen, directive: str, name: str, module: str, arrt: *tinfo, rhs: *node) bool = { let au: *tinfo = arrt; - for (au != nil && au.kind == tykind.TY_NAMED) { au = au.under; }; + au = tichase(au); if (au == nil) { return false; }; if (au.kind != tykind.TY_ARRAY) { return false; }; if (rhs == nil) { @@ -39109,7 +39098,7 @@ fn emitarraydata(c: *cgen, directive: str, name: str, module: str, fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, rhs: *node) void = { let su: *tinfo = slt; - for (su != nil && su.kind == tykind.TY_NAMED) { su = su.under; }; + su = tichase(su); // Defensive, mirrors cstage emit_slice_data's // `if (u == NULL || u->kind != TY_SLICE) return 0` (rule-10): the // letvarisslice gate already guarantees a slice, so this is @@ -39118,7 +39107,7 @@ fn emitslicedata(c: *cgen, name: str, module: str, slt: *tinfo, if (su == nil || su.kind != tykind.TY_SLICE) { return; }; let etype: *tinfo = su.sub; let eu: *tinfo = etype; - for (eu != nil && eu.kind == tykind.TY_NAMED) { eu = eu.under; }; + eu = tichase(eu); if (eu != nil) { if (eu.kind == tykind.TY_STR || eu.kind == tykind.TY_SLICE || eu.kind == tykind.TY_TAGGED) { @@ -39238,9 +39227,7 @@ fn emittupledata(c: *cgen, name: str, module: str, tt: *node, rhs: *node) bool = { let eti: *tinfo = nil; if (et != nil) { eti = et.type_: *tinfo; }; - for (eti != nil && eti.kind == tykind.TY_NAMED) { - eti = eti.under; - }; + eti = tichase(eti); if (eti != nil && eti.kind == tykind.TY_TAGGED) { return false; }; @@ -39647,9 +39634,7 @@ fn emitdefconstants(c: *cgen, file: *node) void = { if (r != nil) { if (r.kind == nkind.N_STRUCTLIT) { let st: *tinfo = d.lhs.type_: *tinfo; let su: *tinfo = st; - for (su != nil && su.kind == tykind.TY_NAMED) { - su = su.under; - }; + su = tichase(su); if (su != nil) { if (su.kind == tykind.TY_STRUCT) { emitstructdata(c, "DATA", @@ -39662,9 +39647,7 @@ fn emitdefconstants(c: *cgen, file: *node) void = { if (r != nil) { if (r.kind == nkind.N_ARRLIT) { let at: *tinfo = d.lhs.type_: *tinfo; let au: *tinfo = at; - for (au != nil && au.kind == tykind.TY_NAMED) { - au = au.under; - }; + au = tichase(au); if (au != nil) { if (au.kind == tykind.TY_ARRAY) { emitarraydata(c, "DATA",