In cmd/wcc/check.c the pass-1.5 SK_USE→SK_DEF/SK_FN/SK_VAR promotion sites forgot to set prev->use_alias = 1 when the imported module's top-level decl shadowed the SK_USE leaf in flat scope. Downstream dot-prefixed lookups (resolve_typename L77, N_DOT L709) gate the module-head walk on (SK_USE || use_alias), so `mod.flag` resolution fell through to "unknown type". The SK_TYPE precedent at L1660 had the line; the three sister sites at L1709/L1722/L1736 now do too, in the same one-line shape and field-set order. The wwstage selfhost/cmd/wcc/check.ww uses coexistence rather than in-place promotion: SK_USE and same-leaf SK_TYPE/FN/DEF/VAR live as separate entries differentiated by sym.mod, and scopelookupinmodule's mod-filter already disambiguates dotted lookups — no use_alias flag needed, so the cstage bug is structurally non-reachable there. An architectural note at installdecl documents this divergence-by-design and warns against porting the flag (adding a field to `sym` changes its size and risks the wwstage cgen amalloc-undersize trap). Audit covered every SK_USE→SK_X promotion path in check.c (4 sites: SK_TYPE already-correct as precedent, SK_DEF/SK_FN/SK_VAR fixed). The surfacing case was lib/fnmatch: `fn fnmatch(...)` shadows the SK_USE leaf, so `fnmatch.flag` failed in worker-fnmatch's WIP — that test (972_fnmatch_run) now flips PASS as live integration proof. test/wcc/699_use_promote_alias.c pins all four rows with a single table-driven driver (type/fn/def/var → use mod; let m: mod.flag = mod.flag.A; return m: i32, expecting exit 42 per row). 995_self_rebuild byte-identity holds.
14 lines
466 B
Plaintext
14 lines
466 B
Plaintext
// usepromote/defmod — exports a `def defmod` with the same leaf as
|
|
// the module name. Paired with pos_def.ww to exercise the SK_USE→
|
|
// SK_DEF promotion (cmd/wcc/check.c L1709). Mirrors the SK_FN bug
|
|
// shape: without `use_alias = 1`, the consumer's `defmod.flag` lookup
|
|
// fails because the promoted-in-place SK_DEF leaf no longer advertises
|
|
// itself as a module head.
|
|
|
|
export def defmod: i32 = 0i32;
|
|
|
|
export type flag = enum i32 {
|
|
NONE = 0,
|
|
A = 42,
|
|
};
|