Skip to content

Resolve relative multi-segment type paths - #127

Merged
philpax merged 1 commit into
mainfrom
fix/multi-segment-type-paths
Aug 10, 2026
Merged

Resolve relative multi-segment type paths#127
philpax merged 1 commit into
mainfrom
fix/multi-segment-type-paths

Conversation

@philpax

@philpax philpax commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Closes #125

Qualified type paths such as Outer::Header (a nested item referenced from inside Outer's own body) or sub::inner::Header (module-relative) previously either reported a misleading leaf-only NotFound or stalled with "type resolution will not terminate".

Fix

  • TypeRegistry::resolve_path / NameIndex::resolve_path now scan empty() ∪ scope bases prefixed onto the path (mirroring the doc-links resolver), so relative multi-segment paths resolve inline; a miss reports the full written path.
  • collect_value_refs resolves qualified Ident paths through the index so the owner is awaited — the stall is gone.
  • ItemPath::join_path shares the base-join between both resolves.
  • C++ backend: nested type declarations now emit before the parent's fields (value items after), so a field can reference a nested type by name; plus a same-module guard in the dep walker to avoid a bogus #include self-include. (Operator-directed.)
  • Semantic tests for qualified/relative/bare-nested cases, extended codegen corpus (same-body qualified nested references), docs update.

Verification

  • python test.py green (clippy, nightly fmt, unit, corpus across all backends, doc build).
  • pyxis-defs Rust + C++ build checks both pass (JustCause2/3, MadMax).
  • Two independent reviews (general-purpose + nat-code-reviewer): no critical/high/medium findings.

Notes / follow-ups (out of scope)

  • Relative resolution for indirect targets (*Outer::Header pointees).
  • Cross-module nested refs through a use'd outer module (use main::Outer then Outer::Header).

A qualified type path such as `Outer::Header` (a nested item referenced
from inside `Outer`'s own body) or `sub::inner::Header` (module-relative)
either reported a misleading leaf-only `NotFound` or stalled with "type
resolution will not terminate".

Fix both halves of the resolution path:
- `TypeRegistry::resolve_path` / `NameIndex::resolve_path` now try each
  base in empty() U scope prefixed onto the path (mirroring the doc-links
  resolver), so a relative multi-segment path resolves inline. A miss
  reports the full written path, not just the leaf.
- `collect_value_refs` resolves a qualified `Ident` path through the
  index, so the referencing item's owner is awaited and the build no
  longer stalls.

Add `ItemPath::join_path` to share the base-join between the two
resolves. The C++ backend now emits nested type declarations before the
parent's fields (and value items after), so a field may reference a
nested type by name; add a same-module guard in the dep walker to avoid
a bogus self-include. Add semantic tests for the qualified/relative/
bare-nested cases, extend the codegen corpus to exercise same-body
qualified nested references, and update the language reference.

Closes #125
@philpax
philpax merged commit 8ee72b9 into main Aug 10, 2026
4 checks passed
@philpax
philpax deleted the fix/multi-segment-type-paths branch August 10, 2026 00:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multi-segment type paths only resolve absolutely

1 participant