# 0070 — forward alias in top-level global annotation reaches LLVM verifier > **RESOLVED.** Root cause: issue 0069's `resolveForwardIdentifierAliases` > fixpoint runs at the END of `Lowering.scanDecls`, but the same scan loop > resolved top-level `var_decl` global annotations (and typed module-constant > annotations) via `self.resolveType(ta)` BEFORE that fixpoint ran — so a forward > alias (`A :: B; B :: s32; g : A = 7;`) was still absent from > `type_alias_map`, `resolveType` fabricated an empty-struct stub, and the global > got a type mismatching its initializer at LLVM verification (the typed-const > path silently mistyped the constant instead). > Fix: split `scanDecls` into two passes. Pass 1 registers function/type/alias > facts; then `resolveForwardIdentifierAliases` converges the aliases; then pass 2 > registers top-level `var_decl` globals (`registerTopLevelGlobal`) and typed > module constants (`registerTypedModuleConst`), so their annotations resolve > against the converged alias map. Globals/typed-consts can't be named in a type > position, so deferring them past type/alias registration is order-safe; the > untyped module-const branch (no annotation to resolve) stays in pass 1. > Regression: `examples/0133-types-forward-alias-global.sx`. ## Symptom A forward identifier type alias used as a top-level global's type annotation does not resolve before the global is registered, producing an LLVM verifier failure instead of compiling as the alias target type. Observed: ```text LLVM verification failed: Global variable initializer type does not match global variable type! ptr @g ``` Expected: `A :: B; B :: s32; g : A = 7;` should type `g` as `s32` and compile/run the same way as the ordered alias form. ## Reproduction ```sx A :: B; B :: s32; g : A = 7; main :: () -> s32 { return g; } ``` Run: ```sh ./zig-out/bin/sx run .sx-tmp/probe-0069-forward-alias-global.sx ``` The repro is standalone; the inline source above is sufficient to recreate the scratch file under `.sx-tmp/`. ## Investigation prompt Fix issue 0070: a forward identifier type alias used in a top-level global annotation must resolve before that global's type is registered. Context: - Issue 0069 (`49a383d`) added `Lowering.resolveForwardIdentifierAliases`, a fixpoint post-pass at the end of `scanDecls`, to resolve top-level identifier-RHS aliases like `A :: B; B :: s32;`. - That works for aliases used later in function bodies because the A2.4 unknown-type pass and body lowering run after `scanDecls`. - But top-level `var_decl` annotations are resolved inside the same `scanDecls` loop before `resolveForwardIdentifierAliases(decls)` is called. So `g : A = 7;` can be typed while `A` is still absent from `ProgramIndex.type_alias_map`. - Suspected area: `src/ir/lower.zig`, `Lowering.scanDecls`, especially the ordering between `.const_decl` alias collection, the new `resolveForwardIdentifierAliases`, and the `.var_decl` branch that calls `self.resolveType(ta)`. Likely fix: - Split the scan ordering so all top-level type declarations and identifier aliases converge before any top-level global annotation is resolved. - One possible shape: first scan/register function/type/alias facts, run the forward-alias fixpoint, then handle top-level `var_decl` global registration and literal module constants that require resolved annotation types. - Do not reintroduce issue 0068: `NotAType :: 123; v: NotAType` must still emit `unknown type 'NotAType'`. - Do not fabricate stubs while trying to resolve the forward alias. The alias facts should still come from `ProgramIndex.type_alias_map` and real `TypeTable.findByName` hits. Verification: - Add a focused regression, likely in the `01xx` types block: ```sx A :: B; B :: s32; g : A = 7; main :: () -> s32 { return g; } ``` - Keep `examples/0132-types-forward-type-alias.sx`, `examples/0116-types-type-alias-size-align.sx`, `examples/0201-generics-generic-struct.sx`, and `examples/1117-diagnostics-value-const-as-type-rejected.sx` green. - Run: ```sh zig build zig build test bash tests/run_examples.sh ``` Expected result: the forward-alias global program exits 7, issue 0068 remains rejected with a diagnostic, and the full suite passes.