Surface rename of the signed integer family: s1..s64 become i1..i64
(u1..u64, usize, isize unchanged). 'string' keeps the s-prefix arm in
name classification; width parsing moves to the i-prefix arm next to
isize.
Internal TypeId tags follow the surface (.s8/.s16/.s32/.s64 ->
.i8/.i16/.i32/.i64), as do mono-key mangle fragments (ptr_i64,
tu_i64_bool) and all display/diagnostic formatting (i{d}).
Migrated in the same sweep: stdlib + examples + issue repros + FFI C
companions (shared symbol names like ffi_id_i64), expected
stdout/stderr/ir snapshots, specs.md, readme.md, CLAUDE.md/AGENTS.md,
implementation_plan.md, docs/, issue writeups. Vendored stb_image and
historical flow state left untouched.
zig build test: 426/426; examples suite: 595/595.
4.4 KiB
0069 — forward identifier type alias is falsely rejected by unknown-type pass
RESOLVED. Root cause:
Lowering.scanDecls'.identifieralias branch only registeredA :: BintoProgramIndex.type_alias_mapwhenBwas already known (intype_alias_mapor theTypeTable). A forward target declared later (MyChain :: MyInt; MyInt :: i32;) was never present during the single forward scan, so the alias name went unregistered and the A2.4 unknown-type pass — which treatstype_alias_mapkeys as declared types — flagged its uses. Fix: added a fixpoint post-passresolveForwardIdentifierAliasesat the end ofscanDeclsthat re-resolves identifier-RHS aliases until no progress, after every top-level name has been seen. A value const is never an.identifiernode and an alias whose target is a value const still misses both lookups, so issue 0068's value-const rejection is preserved. Regression:examples/0132-types-forward-type-alias.sx.
Symptom
A forward-referenced identifier type alias is rejected as an unknown type, even though the same alias chain works when ordered after its target.
Observed: MyChain is diagnosed as an unknown type.
Expected: MyChain :: MyInt; MyInt :: i32; should resolve MyChain to i32
when used in a type annotation, matching the existing ordered-chain behavior
(MyInt :: i32; MyChain :: MyInt;).
Reproduction
MyChain :: MyInt;
MyInt :: i32;
main :: () -> i32 {
v: MyChain = 7;
return v;
}
Run:
./zig-out/bin/sx run .sx-tmp/probe-0068-forward-alias.sx
Observed output:
error: unknown type 'MyChain'
--> .sx-tmp/probe-0068-forward-alias.sx:7:8
|
7 | v: MyChain = 7;
| ^^^^^^^
The repro is standalone; the inline source above is sufficient to recreate the
scratch file under .sx-tmp/.
Investigation prompt
Fix issue 0069: a forward-referenced identifier type alias must not be falsely rejected by the A2.4 unknown-type diagnostic pass.
Context:
- This surfaced while re-reviewing
8770145, the issue-0068 fix. That fix correctly stopped arbitrary value consts (NotAType :: 123) from satisfying the unknown-type check. - Ordered identifier aliases still work:
MyInt :: i32; MyChain :: MyInt;. .calltype aliases still work:Vec3 :: Vec(3, f32);andFoo :: Complex(u32);.- The failing shape is specifically a forward identifier alias:
MyChain :: MyInt; MyInt :: i32;.
Suspected area:
src/ir/lower.zig,Lowering.scanDecls, especially the.identifieralias branch forconst_declvalues. It only insertscd.nameintoProgramIndex.type_alias_mapif the RHS is already intype_alias_mapor already registered in theTypeTable. A forward target is not present yet, so the alias name is never recorded.src/ir/semantic_diagnostics.zig,UnknownTypeChecker.collectDeclaredTypeNames/reportIfUnknownType. After issue 0068,.identifieraliases are intentionally excluded fromconstValueIntroducesTypeand are supposed to be covered by canonical facts (ProgramIndex.type_alias_map/TypeTable). Because the forward alias never reaches those facts, the checker flags the alias as unknown.
Likely fix:
- Do not reintroduce the issue-0068 bug by adding all
.identifierconst names to the declared-type set. - Instead, make identifier aliases converge through canonical alias facts even
when the RHS is declared later. A small two-pass alias registration/resolution
in
scanDecls, or an explicit pending-alias graph that resolves after all top-level declarations are scanned, would keepProgramIndex.type_alias_mapauthoritative without accepting value constants. - Preserve value const rejection:
NotAType :: 123; v: NotATypemust continue to emitunknown type 'NotAType'. - Preserve ordered/chained aliases and type-returning call aliases:
examples/0116-types-type-alias-size-align.sx,examples/0201-generics-generic-struct.sx, andexamples/1117-diagnostics-value-const-as-type-rejected.sx.
Verification:
- Add a focused regression for the repro above, likely in the
01xxtypes block because the desired behavior is successful alias resolution. - Run the new regression and the existing alias/diagnostic guards:
zig build
zig build test
bash tests/run_examples.sh
Expected result: the forward alias program compiles/runs (returning 7), the
issue-0068 value-const case still fails with a diagnostic, and the full suite
passes.