Skip to content

Comments

Add section on type-relative name-resolution#2187

Draft
yaahc wants to merge 2 commits intorust-lang:masterfrom
yaahc:type-relative-name-res
Draft

Add section on type-relative name-resolution#2187
yaahc wants to merge 2 commits intorust-lang:masterfrom
yaahc:type-relative-name-res

Conversation

@yaahc
Copy link
Member

@yaahc yaahc commented Feb 20, 2026

Currently doing content reviews w/ other subject matter exports. Not yet ready for editorial review.

- Types
- Expressions
- Patterns
- Structs & Tuple Structs
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be mcga related except for where it overlaps w/ enums

r[names.resolution.type-relative.stages]
These type relative paths are resolved separately in item definitions and in function bodies.

r[names.resolution.type-relative.stages.items]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's a lot more complexity in the compiler than what I've represented here, but afaict everything else is tied to unstable syntax.

This section covers the stable logic in lower_type_relative_ty_path in rustc_hir_analysis.

// or an inherent associated type (on unstable)
```

r[names.resolution.type-relative.stages.bodies]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section represents the logic in resolve_fully_qualified_call. Still seems odd to me that variants are being resolved in this function given it's name but that seems to be whats happening in the code so /shrug.

}
```

struct literals?
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double check why I thought this may be a type relative case. My guess is it probably has to do with caller's of lower_qpath and I think this might reduce down to just enum literals for which stable syntax it actually covers. If so, merge this back into the enum section as a subsection.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably TyAlias::AssocType { field1, field2, .. }, or <Enum>::Variant { field1, field2, .. } or anything similar.
The thing before braces in a struct literal is an arbitrary type path (even including generic arguments).

@yaahc yaahc force-pushed the type-relative-name-res branch from 2abea11 to 76a3139 Compare February 20, 2026 23:22
impl Trait for Foo {}

fn main() {
//<_>::inherent_func(); // ERROR: unable to get the assoc item
Copy link
Member Author

@yaahc yaahc Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is never considered because Self is an inference var and this method is an inherent method


fn main() {
//<_>::inherent_func(); // ERROR: unable to get the assoc item
//<_>::trait_method(); // ERROR: chose trait method, unable to infer the self type
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an error because candidate selection depends upon inference resolving Self. In this case Self is unconstrained so we have no candidates at all. The fact that we only have one trait_method candidate that would be considered here cannot flow backwards and help constrain the Self inference var.

fn main() {
//<_>::inherent_func(); // ERROR: unable to get the assoc item
//<_>::trait_method(); // ERROR: chose trait method, unable to infer the self type
let _: Foo = <_>::trait_method(); // OK
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self is constrained by return type annotation, we consider trait methods and find a candidate.

_Type-relative resolution_ is the process of tying paths that depend on type
information to the declarations of those entities once that type information is
available in the compiler. This stage of name resolution exclusively applies to
a subset of [Qualified Paths].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, even examples below include non-qualified paths like Type::assoc_item.

- Types
- Expressions
- Patterns
- Structs & Tuple Structs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Structs are types, and tuple structs are expressions.
(Except tuple structs in patterns which are a special production.)

associated item comes from or the definition an alias points to.

r[names.resolution.type-relative.stages]
These type relative paths are resolved separately in item definitions and in function bodies.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean in signatures and in bodies?

type Alias = Enum;
fn main() {
match Enum::Variant {
Alias::Variant => {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path pattern is used as an example for a path expression.


Fully qualified paths for enums are also resolved as type relative names. This
is mainly because the implementation is simpler this way not because this
information would not otherwise be available during primary resolution.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Enum has both a variant and an associated item called Variant, then the information about the associated item is not available during primary resolution.
But the statement still seems correct, because the disambiguation is always in favor of the variant.

fully qualified call expressions:

```rust
Type::assoc_func();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm? Why is it fully qualified? It's just a call expression.

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.

2 participants