Skip to content

Commit 9fe10a9

Browse files
committed
Resolve associated types with type anchors
1 parent 444f6ca commit 9fe10a9

File tree

3 files changed

+42
-12
lines changed

3 files changed

+42
-12
lines changed

crates/hir/src/source_analyzer.rs

+19-10
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use hir_def::{
2020
use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile};
2121
use hir_ty::{
2222
diagnostics::{record_literal_missing_fields, record_pattern_missing_fields},
23-
InferenceResult, Substitution,
23+
InferenceResult, Substitution, TyLoweringContext,
2424
};
2525
use syntax::{
2626
ast::{self, AstNode},
@@ -466,7 +466,20 @@ fn resolve_hir_path_(
466466
prefer_value_ns: bool,
467467
) -> Option<PathResolution> {
468468
let types = || {
469-
let (ty, remaining) = resolver.resolve_path_in_type_ns(db.upcast(), path.mod_path())?;
469+
let (ty, unresolved) = match path.type_anchor() {
470+
Some(type_ref) => {
471+
let (_, res) = TyLoweringContext::new(db, resolver).lower_ty_ext(type_ref);
472+
res.map(|ty_ns| (ty_ns, path.segments().first()))
473+
}
474+
None => {
475+
let (ty, remaining) =
476+
resolver.resolve_path_in_type_ns(db.upcast(), path.mod_path())?;
477+
match remaining {
478+
Some(remaining) if remaining > 1 => None,
479+
_ => Some((ty, path.segments().get(1))),
480+
}
481+
}
482+
}?;
470483
let res = match ty {
471484
TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
472485
TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }),
@@ -478,18 +491,14 @@ fn resolve_hir_path_(
478491
TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
479492
TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
480493
};
481-
match remaining {
482-
Some(1) => {
483-
let unresolved = path.segments().get(1)?;
484-
res.assoc_type_shorthand_candidates(db, |name, alias| {
494+
match unresolved {
495+
Some(unresolved) => res
496+
.assoc_type_shorthand_candidates(db, |name, alias| {
485497
(name == unresolved.name).then(|| alias)
486498
})
487499
.map(TypeAlias::from)
488500
.map(Into::into)
489-
.map(PathResolution::Def)
490-
}
491-
// ambiguous
492-
Some(_) => None,
501+
.map(PathResolution::Def),
493502
None => Some(res),
494503
}
495504
};

crates/hir_ty/src/lower.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ impl<'a> TyLoweringContext<'a> {
146146
self.lower_ty_ext(type_ref).0
147147
}
148148

149-
fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
149+
pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
150150
let mut res = None;
151151
let ty = match type_ref {
152152
TypeRef::Never => TyKind::Never.intern(&Interner),

crates/ide/src/hover.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -3841,6 +3841,27 @@ fn foo() {}
38413841
r#"
38423842
fn foo<T: A>() where T::Assoc$0: {}
38433843
3844+
trait A {
3845+
type Assoc;
3846+
}"#,
3847+
expect![[r#"
3848+
*Assoc*
3849+
3850+
```rust
3851+
test
3852+
```
3853+
3854+
```rust
3855+
type Assoc
3856+
```
3857+
"#]],
3858+
);
3859+
check(
3860+
r#"
3861+
fn foo<T: A>() {
3862+
let _: <T>::Assoc$0;
3863+
}
3864+
38443865
trait A {
38453866
type Assoc;
38463867
}"#,
@@ -3874,6 +3895,6 @@ trait A where
38743895
type Assoc
38753896
```
38763897
"#]],
3877-
)
3898+
);
38783899
}
38793900
}

0 commit comments

Comments
 (0)