feat(imports): buildImportFacts raw-fact store (ModuleRawDeclIndex + NamespaceEdges) [stdlib A]

Phase A of the unified resolver (R5 locked design). Additive infrastructure
with NO behavior change — builds the import-side raw-fact store; nothing
consumes it yet.

- imports.zig: add RawDeclRef / RawAuthor / ModuleRawDeclIndex / ModuleDecls /
  NamespaceTarget / NamespaceEdges, plus buildImportFacts (mirrors
  buildModuleFns) producing a scalar per-module name→RawDeclRef index + the
  namespace edges. Callable without IR lowering (LSP reuses it later).
- ast.zig: NamespaceDecl gains target_module_path, captured at resolution time
  (the resolved_path otherwise lost on the node) so the namespace edge records
  the alias target.
- imports.zig: same-module duplicate top-level name is now DIAGNOSED
  ("duplicate top-level declaration 'X'") where addOwnDecl would silently drop
  the second author — replaces the discarded `_ =` at the three call sites.
- program_index.zig: borrowed views module_decls / namespace_edges (like
  module_fns); deinit does not free them.
- core.zig: build the facts alongside buildModuleFns and point the borrowed
  views at them.
- imports.test.zig: index unit tests (flat / directory / namespaced file /
  namespaced directory / C-import namespace / same-name fn / same-name struct /
  value-vs-type same spelling / raw const_decl) + the duplicate-name diagnostic
  regression (fails pre-fix, passes after).

Gate (worktree): zig build, zig build test (incl. LSP corpus sweep), and
run_examples (471, byte-identical) all green; m3te ios-sim build exits 0.
This commit is contained in:
agra
2026-06-06 23:34:32 +03:00
parent db7af02950
commit b5ec121645
5 changed files with 443 additions and 4 deletions

View File

@@ -680,6 +680,12 @@ pub const NamespaceDecl = struct {
/// (`ns.fn`) so `pkg.fn(...)` resolves to a unique FuncId distinct from a
/// same-named function in another module (issue 0100).
own_decls: []const *Node = &.{},
/// The resolved path of the module this alias targets — the importing file's
/// own path for a `#import c` namespace (its members are synthesized there).
/// Captured at import-resolution time (the `resolved_path` that is otherwise
/// not retained on the node) so `buildImportFacts` can record the namespace
/// edge without re-walking the import graph.
target_module_path: []const u8,
/// True when the namespace NAME was a backtick raw identifier — exempt
/// from the reserved-type-name decl check (issue 0089).
is_raw: bool = false,