Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/source_analyzer.rs')
-rw-r--r--crates/hir/src/source_analyzer.rs73
1 files changed, 59 insertions, 14 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index d05118bbc2..54b4d81012 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -16,7 +16,6 @@ use hir_def::{
hir::{BindingId, ExprId, Pat, PatId},
lang_item::LangItem,
lower::LowerCtx,
- macro_id_to_def_id,
nameres::MacroSubNs,
path::{ModPath, Path, PathKind},
resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs},
@@ -771,9 +770,7 @@ impl SourceAnalyzer {
) -> Option<MacroFileId> {
let krate = self.resolver.krate();
let macro_call_id = macro_call.as_call_id(db.upcast(), krate, |path| {
- self.resolver
- .resolve_path_as_macro(db.upcast(), &path, Some(MacroSubNs::Bang))
- .map(|(it, _)| macro_id_to_def_id(db.upcast(), it))
+ self.resolver.resolve_path_as_macro_def(db.upcast(), &path, Some(MacroSubNs::Bang))
})?;
// why the 64?
Some(macro_call_id.as_macro_file()).filter(|it| it.expansion_level(db.upcast()) < 64)
@@ -1163,9 +1160,40 @@ fn resolve_hir_path_qualifier(
resolver: &Resolver,
path: &Path,
) -> Option<PathResolution> {
- resolver
- .resolve_path_in_type_ns_fully(db.upcast(), &path)
- .map(|ty| match ty {
+ (|| {
+ let (ty, unresolved) = match path.type_anchor() {
+ Some(type_ref) => {
+ let (_, res) =
+ TyLoweringContext::new_maybe_unowned(db, resolver, resolver.type_owner())
+ .lower_ty_ext(type_ref);
+ res.map(|ty_ns| (ty_ns, path.segments().first()))
+ }
+ None => {
+ let (ty, remaining_idx, _) = resolver.resolve_path_in_type_ns(db.upcast(), path)?;
+ match remaining_idx {
+ Some(remaining_idx) => {
+ if remaining_idx + 1 == path.segments().len() {
+ Some((ty, path.segments().last()))
+ } else {
+ None
+ }
+ }
+ None => Some((ty, None)),
+ }
+ }
+ }?;
+
+ // If we are in a TypeNs for a Trait, and we have an unresolved name, try to resolve it as a type
+ // within the trait's associated types.
+ if let (Some(unresolved), &TypeNs::TraitId(trait_id)) = (&unresolved, &ty) {
+ if let Some(type_alias_id) =
+ db.trait_data(trait_id).associated_type_by_name(unresolved.name)
+ {
+ return Some(PathResolution::Def(ModuleDefId::from(type_alias_id).into()));
+ }
+ }
+
+ let res = match ty {
TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
TypeNs::GenericParam(id) => PathResolution::TypeParam(id.into()),
TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
@@ -1176,11 +1204,28 @@ fn resolve_hir_path_qualifier(
TypeNs::BuiltinType(it) => PathResolution::Def(BuiltinType::from(it).into()),
TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
TypeNs::TraitAliasId(it) => PathResolution::Def(TraitAlias::from(it).into()),
- })
- .or_else(|| {
- resolver
- .resolve_module_path_in_items(db.upcast(), path.mod_path()?)
- .take_types()
- .map(|it| PathResolution::Def(it.into()))
- })
+ };
+ match unresolved {
+ Some(unresolved) => resolver
+ .generic_def()
+ .and_then(|def| {
+ hir_ty::associated_type_shorthand_candidates(
+ db,
+ def,
+ res.in_type_ns()?,
+ |name, id| (name == unresolved.name).then_some(id),
+ )
+ })
+ .map(TypeAlias::from)
+ .map(Into::into)
+ .map(PathResolution::Def),
+ None => Some(res),
+ }
+ })()
+ .or_else(|| {
+ resolver
+ .resolve_module_path_in_items(db.upcast(), path.mod_path()?)
+ .take_types()
+ .map(|it| PathResolution::Def(it.into()))
+ })
}