wcc/check: #11 def [_]T length-inference — stamp the def decl path, the #7 let-twin (both stages)

def xs:[_]T=arrlit was sized 0 (no DATA emitted, garbage indexed reads) on BOTH stages, byte-id-identical: #7 wired [_] length-inference only on the let decl path, never def. cstage check.c N_DEF pass-2 infers the length from the initialiser and re-points both d->type and the SK_DEF Sym (an indexed read resolves the def through its Sym); wwstage check.ww runs inferarraylen before resolvewalk. Checker-only — cgen lays the DATA correctly once the length is stamped. w6c and wwdump combined.ww regen'd (both embed the wcc checker).

Pin: table-driven test/wcc/814_def_arr_infer_len (index reads int/u8/2d + 1-elem edge + negative build-fail), teeth-proven against a reverted inference. Filed separately, not folded (rule-11): def-global .len GAP-A (#7 cgdot twin), def str-array element DATA GAP-B (#270), [0]T-vs-[_] alen==0 conflation (pre-existing in the #7 let path too).
This commit is contained in:
2026-06-08 14:50:03 +09:00
parent ba13940b96
commit 0c5482fad0
6 changed files with 410 additions and 0 deletions

View File

@@ -15416,6 +15416,14 @@ export fn checkfile(c: *checker, file: *node) void = {
if (d.lhs != nil) { resolvewalk(c, d.lhs); }; // return type
resolvefnbody(c, d);
case nkind.N_DEF:
// #11: a module-level `def xs: [_]T = arrlit;` must infer
// its length BEFORE resolvewalk stamps d.lhs's tinfo, the
// def twin of the N_LET arm below. #7 wired only the let
// path, so the def path silently stayed length 0 (no DATA,
// garbage indexed reads). inferarraylen mutates the N_TARRAY
// length child in place (the SSoT all reads resolve through),
// so no Sym re-point is needed on this side.
inferarraylen(c, d);
if (d.lhs != nil) { resolvewalk(c, d.lhs); };
if (d.rhs != nil) { resolvewalk(c, d.rhs); };
// #251: `def D: [N]T = [int/rune lits]` array-init