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

@@ -2838,6 +2838,31 @@ check_file(Checker *c, Node *file)
case N_DEF: {
if (d->rhs) {
Type *rt = cexpr(c, d->rhs);
/* #11: `def xs: [_]T = arrlit;` — infer the length
* from the initialiser, the def twin of the module
* N_LET path below. pass-1 (N_DEF above) installed
* the SK_DEF Sym + d->type with the alen=0 sentinel;
* an indexed read resolves the def through its Sym,
* so re-point BOTH d->type (feeds cgen's emit_defs
* DATA row + defarray registry) and the Sym (feeds
* the N_INDEX / `.len` type read). #7 only wired the
* let decl path; the def path silently stayed length
* 0 (no DATA, garbage reads). Run before the
* assignability check so arrlit_init_fits sees the
* inferred length. */
if (d->type && d->type->kind == TY_ARRAY
&& d->type->alen == 0) {
Type *iu = type_chase_named(rt);
if (iu && iu->kind == TY_ARRAY) {
d->type = type_array(c->a,
d->type->sub, iu->alen);
Sym *s = scope_lookup_local(c->cur,
d->str);
if (s) s->type = d->type;
} else
err(c, d->pos, "[_]T needs an "
"array-literal initialiser");
}
/* #88: fold sibling/imported def refs, casts, and
* arithmetic to a constant. litfold (plain literal
* leaf) is already typed UNTYPED_INT by cexpr;