diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-04-01 22:11:06 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-04-01 22:11:06 +0100 |
commit | 5ef0c7a21387c219478754393bf9ac1b1cebf0d4 (patch) | |
tree | a154c84cb2baee3f83d5b5da331f0cee5ef8ef2f /crates/hir | |
parent | 1c936dcbe1be90e094ac436a0b62ec070bd6953d (diff) | |
parent | 9fe10a96069ea0f617ff86049bb50922b5424fae (diff) |
Merge #8283
8283: Resolve associated types r=flodiebold a=Veykril
Prior we were only resolving paths until the first type was found, then discarding the result if the path wasn't fully consumed. That of course causes associated types to not resolve. Fixes #5003
Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/hir')
-rw-r--r-- | crates/hir/src/semantics.rs | 6 | ||||
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 30 |
2 files changed, 31 insertions, 5 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index d3caeef4e..3bf722d2a 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -76,9 +76,11 @@ impl PathResolution { | |||
76 | pub fn assoc_type_shorthand_candidates<R>( | 76 | pub fn assoc_type_shorthand_candidates<R>( |
77 | &self, | 77 | &self, |
78 | db: &dyn HirDatabase, | 78 | db: &dyn HirDatabase, |
79 | mut cb: impl FnMut(TypeAlias) -> Option<R>, | 79 | mut cb: impl FnMut(&Name, TypeAlias) -> Option<R>, |
80 | ) -> Option<R> { | 80 | ) -> Option<R> { |
81 | associated_type_shorthand_candidates(db, self.in_type_ns()?, |_, _, id| cb(id.into())) | 81 | associated_type_shorthand_candidates(db, self.in_type_ns()?, |name, _, id| { |
82 | cb(name, id.into()) | ||
83 | }) | ||
82 | } | 84 | } |
83 | } | 85 | } |
84 | 86 | ||
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 37d162b32..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,21 @@ 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 | resolver.resolve_path_in_type_ns_fully(db.upcast(), path.mod_path()).map(|ty| match ty { | 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 | }?; | ||
483 | let res = match ty { | ||
470 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), | 484 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), |
471 | TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), | 485 | TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), |
472 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { | 486 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { |
@@ -476,7 +490,17 @@ fn resolve_hir_path_( | |||
476 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), | 490 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), |
477 | TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()), | 491 | TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()), |
478 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), | 492 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), |
479 | }) | 493 | }; |
494 | match unresolved { | ||
495 | Some(unresolved) => res | ||
496 | .assoc_type_shorthand_candidates(db, |name, alias| { | ||
497 | (name == unresolved.name).then(|| alias) | ||
498 | }) | ||
499 | .map(TypeAlias::from) | ||
500 | .map(Into::into) | ||
501 | .map(PathResolution::Def), | ||
502 | None => Some(res), | ||
503 | } | ||
480 | }; | 504 | }; |
481 | 505 | ||
482 | let body_owner = resolver.body_owner(); | 506 | let body_owner = resolver.body_owner(); |