Fix IDE layer not resolving assoc type paths in path qualifiers

This commit is contained in:
Lukas Wirth 2023-12-11 12:59:08 +01:00
parent a892237ed4
commit 6be83b8204

View file

@ -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()))
})
}