Skip to content

Conversation

@paldepind
Copy link
Contributor

@paldepind paldepind commented Jan 19, 2026

The goal of this PR is to handle paths that access an associated type on a concrete type (concrete meaning not a type parameter) in TypeMention.

In practise these paths fall into one of two cases:

  1. <Foo as Trait>::Assoc where Foo can be an arbitrarily complex type.
  2. Self::Assoc inside an impl block. For an impl block of the form impl Trait for Foo such a path is basically sugar for the above.

A key point is that resolving the associated type relies on how the concrete type implements the trait that the associated type is from. For instance, the added tests have examples where <Odd<i32> as GetSet>::Output is equal to bool but <Odd<bool> as GetSet>::Output is equal to char.

Today case 1 above is unhandled and case 2 is somewhat handled inside path resolution. But path resolution doesn't understand how types implement trais: For a Self::Assoc path we find all associated types with the name Assoc across all traits that Self implement. This leads to spurious path resolutions as seen in the tests.

To address the above, this PR tweaks path resolution such that a Self::Assoc path resolves to the associated type in the trait where Assoc is from (except when Assoc is defined directly in the impl block that Self belongs to). This is does not depend on type information, so it can be done correctly in path resolution.

After that we use the SatisfiesConstraint module in TypeMention to find the correct trait implementations and read the associated types off of those. When implementing this I ran into non-monotonic recursion. The problem as well as the workaround is documented in the comment for the MkTypeMention module.

@github-actions github-actions bot added the Rust Pull requests that update Rust code label Jan 19, 2026
@paldepind paldepind force-pushed the rust/self-path-assoc branch 5 times, most recently from eca7559 to 8a465bd Compare January 23, 2026 12:40
@paldepind paldepind force-pushed the rust/self-path-assoc branch from 8a465bd to 7e74844 Compare January 26, 2026 14:15

override Namespace getNamespace() {
result.isType() // can be referenced with `Self`
// `impl` blocks are refered to using `Self` paths which can appear both as

Check warning

Code scanning / CodeQL

Misspelling Warning

This comment contains the common misspelling 'refered', which should instead be 'referred'.
Comment on lines +12 to +27
/**
* Constructing the "type hierachy" (that is, the trait hierachy and how types
* implements trait) in the shared type inference library relies on type
* mentions.
*
* Furthermore, resolving type mentions such as `<Type as Trait>::AssocType`
* relies on knowing how `Type` implements `Trait`. This makes type mentions and
* the type hierachy recursively dependentent, which causes non-monotonic
* recursion.
*
* To avoid the recursion, we parameterize the `TypeMention` by a predicate for
* resolving "additional" types for paths. A first instantion uses the empty
* predicate to create `PreTypeMention` which is used to construct the type
* hierachy. Afterwards, a second instantion uses a predicate that can resolve
* paths that rely on the type hierachy to create the actual `TypeMention`.
*/

Check warning

Code scanning / CodeQL

Misspelling Warning

This comment contains the common misspelling 'hierachy', which should instead be 'hierarchy'.
typePath = TypePath::singleton(TSelfTypeParameter(this)) and
result = TSelfTypeParameter(this)
or
exists(TypeAlias alias |

Check warning

Code scanning / CodeQL

Omittable 'exists' variable Warning

This exists variable can be omitted by using a don't-care expression
in this argument
.
@paldepind paldepind force-pushed the rust/self-path-assoc branch from 7e74844 to 2f88971 Compare January 26, 2026 14:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant