diff options
author | Lukas Wirth <[email protected]> | 2021-04-01 20:52:07 +0100 |
---|---|---|
committer | Lukas Wirth <[email protected]> | 2021-04-01 20:52:07 +0100 |
commit | 9fe10a96069ea0f617ff86049bb50922b5424fae (patch) | |
tree | bacb0a041f8bdf04199e9a11f6de4fb5365a761d /crates | |
parent | 444f6caababc3335b1ed51d08eeedac106fd8077 (diff) |
Resolve associated types with type anchors
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 29 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 2 | ||||
-rw-r--r-- | crates/ide/src/hover.rs | 23 |
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::{ | |||
20 | use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; | 20 | use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; |
21 | use hir_ty::{ | 21 | use 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 | }; |
25 | use syntax::{ | 25 | use 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#" |
3861 | fn foo<T: A>() { | ||
3862 | let _: <T>::Assoc$0; | ||
3863 | } | ||
3864 | |||
3865 | trait 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#" | ||
3861 | trait A where | 3882 | trait 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 | } |