Files
ww/selfhost
Hojun-Cho 908875682a selfhost/cmd/wcc/cgenutil: collapse nullableptrtag onto tinfo.params (#50 phase 2, A.6.3f-b)
Phase 2 of A.6.3f, closing A.6.3 entirely (a/b/c/d/e/f-a/f-b all
landed). With #50 phase 1 (26724fe) populating TY_TAGGED.params,
nullableptrtag retires its AST-keyed predecessor: walk ti.params,
strip TY_NAMED via .under on each variant, return idx of first
TY_PTR.

Mirrors cstage cmd/w6c/cgen.c:404-416 line-for-line. Source-order
semantics preserved by phase 1's append-tail head/tail
construction (head = first n.list variant). For a `(*T | void)`,
*T-first → returns 0; void-first → walks past void (vt.kind==
TY_VOID, no match), *T at idx 1 → returns 1.

Two paths the new tinfo-keyed body handles that the AST walk
missed (cstage parity, dead-in-bootstrap today, parallel to #49
TY_TUPLE / #51b typed-float corrections):

  - Aliased *T variant: `type ip = *int; let x: (ip | void);` —
    cstage cgen.c:415 strips TY_NAMED via .under; new wwstage
    body mirrors. Bootstrap has zero aliased-ptr-variant
    callsites today (`grep "^type [a-z]+ = \*"` yields only an
    out-of-union test/uses.ww case).
  - void-first ordering: cstage walks past TY_VOID and finds *T
    at idx 1. Same in wwstage. No test/wcc fixture exercises
    void-first today.

Outer-type TY_NAMED strip (cstage cgen.c:409 `if t->kind==TY_NAMED
t = t->under`) intentionally skipped: tinfofornode for N_TNAME
already resolves the alias and returns the underlying tinfo
unwrapped — `typenamed` is declared at lib/ww/typ.ww:238 but has
zero producers in selfhost today. The strip would be a no-op
under current invariants. Tracked as part of #13 (TTAGGED
normalization parity) for when wwstage starts producing
TY_NAMED.

Net +30 LOC across cgenutil.ww + two .combined.ww bundler regens
(new function body is ~14 lines vs ~4; new WHY comment shorter
than the pre-graduation note's 7).

Byte-identity (994/995) is the gate; full make test green at
133/133 confirms.
2026-05-23 02:21:53 +09:00
..