A def initializer whose rhs references another def -- `def INT_MIN: int = I32_MIN;`, `def SIZE_MAX: size = U64_MAX;` -- failed to compile: an N_IDENT->SK_DEF types as the referent's DECLARED type (i32, u64), so the def-init assignability check (type_assignable) rejected i32 -> int / u64 -> size, even though the value is a compile-time constant that fits. This blocked faithful types/types::c limit defs (no cast in the Hare source). In a def initializer the rhs is a flexible constant. When it folds to a compile-time integer (the #88 eval_def_const path: sibling/imported def refs, casts, arithmetic) and the value fits the declared integer target, re-flexibilize it to UNTYPED_INT so the existing untyped-int->typed assignability path accepts it. This emulates Hare's flexible-constant promotion (ICONST -> promote_flexible/lower_flexible, ref/harec/src/types.c:860); def_cast_fits is the range check that keeps a genuine out-of-range narrowing a loud "not assignable" error, never a silent truncation (rule 7). It is strictly the const subset: the general CONCRETE (non-const) integer widening Hare does at types.c:1021-1037 is intentionally stricter in ww -- #115. cstage-only: the wwstage checker (selfhost/cmd/wcc/check.ww, "let init / return assignability") intentionally never checks def-init assignability (it stays quiet, leaving full inference to the C side), so it never rejected the widening -- the #88 stamp already laid the correct DATA row. Relaxing the cstage aligns the richer side DOWN to the leaner side (rule 10); both stages stamp the identical folded value, so emitted asm is byte-identical. The bootstrap corpus has zero cross-prim-width def-ref defs, so the new path is dead there and 990-997 are unperturbed. Coverage: test/wcc/760_def_widen_const (i32->int neg, u64->size, byte-id on each, cstage-only out-of-range narrowing fail-loud).
9.4 KiB
9.4 KiB