mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 09:27:27 +00:00
Resolve paths to assoc items for traits
This commit is contained in:
parent
7a17206646
commit
97d63d67cd
3 changed files with 32 additions and 19 deletions
|
@ -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()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2077,6 +2077,7 @@ pub struct B$0ar
|
|||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hover_intra_link_reference_to_trait_method() {
|
||||
check(
|
||||
|
|
Loading…
Reference in a new issue