aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-04-01 20:52:07 +0100
committerLukas Wirth <[email protected]>2021-04-01 20:52:07 +0100
commit9fe10a96069ea0f617ff86049bb50922b5424fae (patch)
treebacb0a041f8bdf04199e9a11f6de4fb5365a761d /crates
parent444f6caababc3335b1ed51d08eeedac106fd8077 (diff)
Resolve associated types with type anchors
Diffstat (limited to 'crates')
-rw-r--r--crates/hir/src/source_analyzer.rs29
-rw-r--r--crates/hir_ty/src/lower.rs2
-rw-r--r--crates/ide/src/hover.rs23
3 files changed, 42 insertions, 12 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 8423dd101..8e9ea0a03 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -20,7 +20,7 @@ use hir_def::{
20use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; 20use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile};
21use hir_ty::{ 21use hir_ty::{
22 diagnostics::{record_literal_missing_fields, record_pattern_missing_fields}, 22 diagnostics::{record_literal_missing_fields, record_pattern_missing_fields},
23 InferenceResult, Substitution, 23 InferenceResult, Substitution, TyLoweringContext,
24}; 24};
25use syntax::{ 25use syntax::{
26 ast::{self, AstNode}, 26 ast::{self, AstNode},
@@ -466,7 +466,20 @@ fn resolve_hir_path_(
466 prefer_value_ns: bool, 466 prefer_value_ns: bool,
467) -> Option<PathResolution> { 467) -> Option<PathResolution> {
468 let types = || { 468 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 }?;
470 let res = match ty { 483 let res = match ty {
471 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), 484 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
472 TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), 485 TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }),
@@ -478,18 +491,14 @@ fn resolve_hir_path_(
478 TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()), 491 TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
479 TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), 492 TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
480 }; 493 };
481 match remaining { 494 match unresolved {
482 Some(1) => { 495 Some(unresolved) => res
483 let unresolved = path.segments().get(1)?; 496 .assoc_type_shorthand_candidates(db, |name, alias| {
484 res.assoc_type_shorthand_candidates(db, |name, alias| {
485 (name == unresolved.name).then(|| alias) 497 (name == unresolved.name).then(|| alias)
486 }) 498 })
487 .map(TypeAlias::from) 499 .map(TypeAlias::from)
488 .map(Into::into) 500 .map(Into::into)
489 .map(PathResolution::Def) 501 .map(PathResolution::Def),
490 }
491 // ambiguous
492 Some(_) => None,
493 None => Some(res), 502 None => Some(res),
494 } 503 }
495 }; 504 };
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index afbfa12d5..14f34d73c 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -146,7 +146,7 @@ impl<'a> TyLoweringContext<'a> {
146 self.lower_ty_ext(type_ref).0 146 self.lower_ty_ext(type_ref).0
147 } 147 }
148 148
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>) {
150 let mut res = None; 150 let mut res = None;
151 let ty = match type_ref { 151 let ty = match type_ref {
152 TypeRef::Never => TyKind::Never.intern(&Interner), 152 TypeRef::Never => TyKind::Never.intern(&Interner),
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 8f98056c1..28e2e17dc 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -3858,6 +3858,27 @@ trait A {
3858 ); 3858 );
3859 check( 3859 check(
3860 r#" 3860 r#"
3861fn foo<T: A>() {
3862 let _: <T>::Assoc$0;
3863}
3864
3865trait A {
3866 type Assoc;
3867}"#,
3868 expect![[r#"
3869 *Assoc*
3870
3871 ```rust
3872 test
3873 ```
3874
3875 ```rust
3876 type Assoc
3877 ```
3878 "#]],
3879 );
3880 check(
3881 r#"
3861trait A where 3882trait A where
3862 Self::Assoc$0: , 3883 Self::Assoc$0: ,
3863{ 3884{
@@ -3874,6 +3895,6 @@ trait A where
3874 type Assoc 3895 type Assoc
3875 ``` 3896 ```
3876 "#]], 3897 "#]],
3877 ) 3898 );
3878 } 3899 }
3879} 3900}