scanDecls' `.identifier` alias branch registered `A :: B` into ProgramIndex.type_alias_map only when `B` was already known (in type_alias_map or the TypeTable). A forward target declared later (`MyChain :: MyInt; MyInt :: s32;`) was never present during the single forward scan, so the alias name went unregistered and the A2.4 unknown-type pass — which treats type_alias_map keys as declared types — flagged its uses as `unknown type 'MyChain'`. Add a fixpoint post-pass `resolveForwardIdentifierAliases` at the end of scanDecls that re-resolves identifier-RHS aliases until no progress, after every top-level name has been seen. A value const is never an `.identifier` node, 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 (forward alias + forward chain). Gate: zig build, zig build test, run_examples.sh -> 353/0.
25 lines
807 B
Plaintext
25 lines
807 B
Plaintext
// Forward identifier type alias — an alias whose target is declared LATER
|
|
// in the file resolves the same as an ordered one. `MyChain :: MyInt;`
|
|
// appears before `MyInt :: s32;`, yet `MyChain` resolves to `s32` and a
|
|
// forward chain (`A :: B; B :: C; C :: u8;`) converges too.
|
|
// Regression (issue 0069): the scan only registered identifier aliases whose
|
|
// target was already known, so a forward alias was falsely flagged
|
|
// `unknown type`. Now a fixpoint pass over the scanned decls resolves them.
|
|
#import "modules/std.sx";
|
|
|
|
MyChain :: MyInt;
|
|
MyInt :: s32;
|
|
|
|
A :: B;
|
|
B :: C;
|
|
C :: u8;
|
|
|
|
main :: () -> s32 {
|
|
v: MyChain = 7;
|
|
n: A = 3;
|
|
print("chain s32: {}\n", size_of(MyChain));
|
|
print("forward u8: {}\n", size_of(A));
|
|
print("v + n: {}\n", v + cast(s32) n);
|
|
return v;
|
|
}
|