fix(R1): own const_decl pending alias wins over flat imports (issue 0107)

When a module declares `A :: B; B :: u64;` and both a flat import and a
namespaced import export `B :: u8`, the flat import's B was discovered by
flatTypeAuthorCount before the own B :: u64 was processed — binding A to
u8 and silently truncating values.

Fix: ownConstDeclIsPendingAlias guard added to selectNominalLeaf between
the own-alias check and the flat-import walk. If the querying module has
an own const_decl for the name that is not yet in type_aliases_by_source,
return .pending so the forward-alias fixpoint resolves it correctly.

Regression: examples/0830-modules-flat-ns-same-name-forward-alias.sx
(x : A = 300 prints 300, not 44). 541/541 tests pass.
This commit is contained in:
agra
2026-06-09 22:16:47 +03:00
parent 5ed54a08ee
commit 010e644897
8 changed files with 61 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
# RESOLVED — 0107: forward alias binds to flat-import same-name type during initial scanDecls
**Root cause:** `selectNominalLeaf` checked flat-import authors (`flatTypeAuthorCount`) before
checking whether the querying module's own `const_decl` for the same name was still pending.
When both a flat import AND a namespaced import exported `B :: u8`, and the own module had
`A :: B; B :: u64;` (B declared after A), the flat import's `u8` was returned as `.resolved`
before the own `B :: u64` was processed — binding A to `u8` and silently truncating values.
**Symptom:** `x : A = 300` printed `44` (u8 truncation of 300) when both imports had `B :: u8`.
The namespaced import alone was not sufficient; both flat AND namespaced were required.
**Fix:** Added `ownConstDeclIsPendingAlias(from, name)` check between the own-alias check and
the flat-import walk in `selectNominalLeaf`. If the querying module has an own `const_decl` for
`name` that is not yet in `type_aliases_by_source`, return `.pending` — deferring to the
forward-alias fixpoint instead of accepting a flat import's version.
**Regression test:** `examples/0830-modules-flat-ns-same-name-forward-alias.sx` (exit 0,
prints 300 — the u64 value, not the u8 truncation).
**Fix in:** `src/ir/lower.zig``selectNominalLeaf` + new `ownConstDeclIsPendingAlias`.