Files
ww/selfhost/cmd
Hojun-Cho 5bfcd8bd6b cgen: convert the struct-store loop arms to a tinfo-native fill (#31 c2)
The W1/W2/W5/W4b store / structlit-fill arms still resolved struct field
LAYOUT by bare-leaf name (structlookupchain / structlookup / letvarstructinfo)
inside the per-field store loop -- the write-side twin of commit-1's read fix.
Under a cross-module same-leaf collision (two modules each exporting a `pair`,
16B vs 24B) the field is stored at the wrong offset/width; an interior 2-byte
field store silently corrupted neighbours. cstage walks the resolved Type*
(never a name) and is correct; this aligns wwstage UP (ww-only change).

Convert each store loop to a tinfo-native fill. Two new helpers in cgenutil.ww:
sretretsizetn (a verbatim port of cstage cg_sret_retsize -- 4 kind-branches,
no TY_BANG, dropping the #129 module-juggling that was pure name-keying
compensation, redundant once the lookup walks resolved tinfo) and
cgstructlitfilltn (the tinfo-native twin of cgstructlitfill, recursing on
tichase(tf.type_).fields with NO name lookup at any nesting level). Supporting
twins storeopsz / tfieldlookup / cgdotfieldhardstoptn. Because the fill never
bottoms out on a name, the W4b "decisive wall" (a structlit that needed a
(sname,smod)-keyed structinfo the stamped leaf-only tinfo couldn't supply)
dissolves by construction, with no module-aware tinfo->structinfo bridge.

This CLOSES the nine in-loop nested sub-arms (N_CALL / N_STRUCTLIT / N_IDENT
field receive) by construction -- the tf walk has no name lookup. The
non-reddenable global arms (W5/W4b) are converted-for-construction: a qualified
global decl resolves its bare leaf correctly today, so byte-id (cs.s==ww.s) is
their net, not a value pin. `!T` is kind-preserving in both stages
(resolve_type / tinfofornode), so a `!struct` sret sizes as the inner struct,
never TAGGED -- the #129 drop changes no size.

Completes the 2-commit #31 arc (RULING R2 / Opt-2, .ai/ken-31-spec.md): the
#224 name-keyed receiver-layout cluster is now closed by construction. The
residual nested-field surface (the shared cgstructlitfill kept for its non-#31
callers + the cgenstmt/cgenutil let-receive/fill family) is tracked as #32.

Pins: test/wcc/797 value-asserts ptr-WRITE (W1) and val-WRITE (W2), each
reddening under independent per-arm revert; nestfill_box drives
cgstructlitfilltn's nested recursion (bootstrap-uncovered -- the corpus has no
struct-literal field store -- so the value pin is its only net).
2026-06-29 15:19:41 +09:00
..