mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-26 11:59:49 +00:00
Fix IDE layer not resolving assoc type paths in path qualifiers
This commit is contained in:
parent
a892237ed4
commit
6be83b8204
1 changed files with 57 additions and 10 deletions
|
@ -1162,9 +1162,39 @@ 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(db, resolver, resolver.module().into())
|
||||
.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) => {
|
||||
|
@ -1175,11 +1205,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()))
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue