Resolve paths to assoc items for traits

This commit is contained in:
Lukas Wirth 2021-07-19 20:36:44 +02:00
parent 7a17206646
commit 97d63d67cd
3 changed files with 32 additions and 19 deletions

View file

@ -114,16 +114,15 @@ fn resolve_doc_path(
let path = ast::Path::parse(link).ok()?;
let modpath = ModPath::from_src(db.upcast(), path, &Hygiene::new_unhygienic()).unwrap();
let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
if resolved == PerNs::none() {
if let Some(trait_id) = resolver.resolve_module_path_in_trait_items(db.upcast(), &modpath) {
return Some(ModuleDefId::TraitId(trait_id));
};
}
let def = match ns {
Some(Namespace::Types) => resolved.take_types()?,
Some(Namespace::Values) => resolved.take_values()?,
Some(Namespace::Macros) => return None,
None => resolved.iter_items().find_map(|it| it.as_module_def_id())?,
let resolved = if resolved == PerNs::none() {
resolver.resolve_module_path_in_trait_assoc_items(db.upcast(), &modpath)?
} else {
resolved
};
Some(def)
match ns {
Some(Namespace::Types) => resolved.take_types(),
Some(Namespace::Values) => resolved.take_values(),
Some(Namespace::Macros) => None,
None => resolved.iter_items().find_map(|it| it.as_module_def_id()),
}
}

View file

@ -20,10 +20,10 @@ use crate::{
path::{ModPath, PathKind},
per_ns::PerNs,
visibility::{RawVisibility, Visibility},
AdtId, AssocContainerId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId,
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, LifetimeParamId, LocalModuleId,
Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId,
VariantId,
AdtId, AssocContainerId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId,
EnumVariantId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, LifetimeParamId,
LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId,
TypeParamId, VariantId,
};
#[derive(Debug, Clone, Default)]
@ -144,15 +144,28 @@ impl Resolver {
self.resolve_module_path(db, path, BuiltinShadowMode::Module)
}
pub fn resolve_module_path_in_trait_items(
pub fn resolve_module_path_in_trait_assoc_items(
&self,
db: &dyn DefDatabase,
path: &ModPath,
) -> Option<TraitId> {
) -> Option<PerNs> {
let (item_map, module) = self.module_scope()?;
let (module_res, ..) = item_map.resolve_path(db, module, path, BuiltinShadowMode::Module);
let (module_res, idx) = item_map.resolve_path(db, module, path, BuiltinShadowMode::Module);
match module_res.take_types()? {
ModuleDefId::TraitId(it) => Some(it),
ModuleDefId::TraitId(it) => {
let idx = idx?;
let unresolved = &path.segments()[idx..];
let assoc = match unresolved {
[it] => it,
_ => return None,
};
let &(_, assoc) = db.trait_data(it).items.iter().find(|(n, _)| n == assoc)?;
Some(match assoc {
AssocItemId::FunctionId(it) => PerNs::values(it.into(), Visibility::Public),
AssocItemId::ConstId(it) => PerNs::values(it.into(), Visibility::Public),
AssocItemId::TypeAliasId(it) => PerNs::types(it.into(), Visibility::Public),
})
}
_ => None,
}
}

View file

@ -2077,6 +2077,7 @@ pub struct B$0ar
"#]],
);
}
#[test]
fn test_hover_intra_link_reference_to_trait_method() {
check(