selfhost/cmd/wcc: drop indexvaluetnode from cgassign + delete 3 retired AST-walkers (#69, #61d)

cgassign's two element-store sites (N_DOT and N_INDEX index targets) fed the
index node into indexvaluetnode to recover the element type. The tagged-store
machinery reads tinfo directly post-#68, so both sites now read the checker-
stamped element tinfo via lhs.type_: esz from .size (mirror #60), tagged gate
via the shared istaggedtype/slotsize/cgwidentaggedstore path (all NAMED-
peeling). cstage parity: cgen.c:3507-3523 (idx_eff(base->type)->sub->size).
The new esz reads the element's natural .size, where the old elemsizeofc
routed struct elements through slotsize -- so a padded-struct chained-index
store (`[][]Point`) now matches cstage's ->size instead of diverging; that
shape is untested (#7 indexbaseesz territory), so this is faithfulness, not
a corpus change.

With cgassign migrated, indexvaluetnode has zero external callers; dotfieldtnode's
sole caller was indexvaluetnode; rhstargetname is self-recursive only -- all
three retired (-132 LOC). This closes the A.6.3 AST-walker arc: the *node
type-resolvers that existed because tinfo was lossy on nominal identity are
gone, now that Phase-N (#63-#68) built the TY_NAMED layer and every consumer
reads the stamped tinfo. make test 134/134, byte-id 950+990-997 hold.
This commit is contained in:
2026-05-24 00:16:14 +09:00
parent 901ddf20b9
commit e5092709e4
4 changed files with 75 additions and 471 deletions

View File

@@ -3712,30 +3712,32 @@ fn cgassign(c: *cgen, n: *node) void = {
};
} else { if (base.kind == nkind.N_DOT) {
esz = indexbaseesz(c, base);
// Without this, the tagged-element gate
// below (keyed on elemtn) misses for
// `obj.arr[i] = v` over an [N]Tagged field
// and the store falls through to scalar —
// task #30, sister of the cgindex N_INDEX-
// base fix #24. indexvaluetnode now handles
// N_DOT base, so the element type drops out
// of the same helper.
let bt: *node = indexvaluetnode(c, lhs);
if (bt != nil) { elemtn = bt; };
// Tagged-element gate (below) keys on the store
// target's element type. lhs.type_ is the
// checker-stamped element tinfo of the N_INDEX,
// so carry lhs and let the gate read it via
// .type_ — same idiom as cgindex's n.type_ read
// (#60). Drops the indexvaluetnode walk for the
// N_DOT base (#69/#61d, was #30). cstage reads
// idx_eff(base->type)->sub (cmd/w6c/cgen.c:3517-
// 3523).
let dt: *tinfo = lhs.type_: *tinfo;
if (dt != nil) { elemtn = lhs; };
} else { if (base.kind == nkind.N_INDEX) {
// Chained-write write-side parallel of the
// cgindex N_INDEX-base arm graduated in #24:
// `names[i][k] = v` (names: **u8) — outer
// base is the inner N_INDEX whose value-type
// is *u8, so the outer element is u8 and
// the store is MOVB, not MOVQ.
let bt: *node = indexvaluetnode(c, base);
if (bt != nil) {
esz = elemsizeofc(c, bt);
let bk2: nkind = bt.kind;
if (bk2 == nkind.N_TPTR) { elemtn = bt.lhs; };
if (bk2 == nkind.N_TSLICE) { elemtn = bt.lhs; };
if (bk2 == nkind.N_TARRAY) { elemtn = bt.lhs; };
// cgindex N_INDEX-base arm (#24): `names[i][k]
// = v` (names: **u8) — outer element is u8 so
// the store is MOVB, not MOVQ. lhs.type_ is the
// checker-stamped outer element tinfo; esz is
// its natural size and the gate reads it via
// .type_. Drops the indexvaluetnode walk
// (#69/#61d, mirror #60). cstage: esz =
// idx_eff(base->type)->sub->size
// (cmd/w6c/cgen.c:3517-3518).
let et: *tinfo = lhs.type_: *tinfo;
if (et != nil) {
esz = et.size: i32;
elemtn = lhs;
};
};};};
};