Make intra-link resolve links for both trait and impl items
This commit is contained in:
parent
914adf04af
commit
fc4c9a6c7f
|
@ -232,37 +232,46 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::TyAlias,
|
||||
did,
|
||||
) => {
|
||||
// We need item's parent to know if it's
|
||||
// trait impl or struct/enum/etc impl
|
||||
let item_parent = item_opt
|
||||
// Checks if item_name belongs to `impl SomeItem`
|
||||
let impl_item = cx
|
||||
.tcx
|
||||
.inherent_impls(did)
|
||||
.iter()
|
||||
.flat_map(|imp| cx.tcx.associated_items(*imp).in_definition_order())
|
||||
.find(|item| item.ident.name == item_name);
|
||||
let trait_item = item_opt
|
||||
.and_then(|item| self.cx.as_local_hir_id(item.def_id))
|
||||
.and_then(|item_hir| {
|
||||
// Checks if item_name belongs to `impl SomeTrait for SomeItem`
|
||||
let parent_hir = self.cx.tcx.hir().get_parent_item(item_hir);
|
||||
self.cx.tcx.hir().find(parent_hir)
|
||||
let item_parent = self.cx.tcx.hir().find(parent_hir);
|
||||
match item_parent {
|
||||
Some(hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Impl { of_trait: Some(_), self_ty, .. },
|
||||
..
|
||||
})) => cx
|
||||
.tcx
|
||||
.associated_item_def_ids(self_ty.hir_id.owner)
|
||||
.iter()
|
||||
.map(|child| {
|
||||
let associated_item = cx.tcx.associated_item(*child);
|
||||
associated_item
|
||||
})
|
||||
.find(|child| child.ident.name == item_name),
|
||||
_ => None,
|
||||
}
|
||||
});
|
||||
let item = match item_parent {
|
||||
Some(hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Impl { of_trait: Some(_), self_ty, .. },
|
||||
..
|
||||
})) => {
|
||||
// trait impl
|
||||
cx.tcx
|
||||
.associated_item_def_ids(self_ty.hir_id.owner)
|
||||
.iter()
|
||||
.map(|child| {
|
||||
let associated_item = cx.tcx.associated_item(*child);
|
||||
associated_item
|
||||
})
|
||||
.find(|child| child.ident.name == item_name)
|
||||
}
|
||||
_ => {
|
||||
// struct/enum/etc. impl
|
||||
cx.tcx
|
||||
.inherent_impls(did)
|
||||
.iter()
|
||||
.flat_map(|imp| cx.tcx.associated_items(*imp).in_definition_order())
|
||||
.find(|item| item.ident.name == item_name)
|
||||
let item = match (impl_item, trait_item) {
|
||||
(Some(from_impl), Some(_)) => {
|
||||
// Although it's ambiguous, return impl version for compat. sake.
|
||||
// To handle that properly resolve() would have to support
|
||||
// something like
|
||||
// [`ambi_fn`](<SomeStruct as SomeTrait>::ambi_fn)
|
||||
Some(from_impl)
|
||||
}
|
||||
(None, Some(from_trait)) => Some(from_trait),
|
||||
(Some(from_impl), None) => Some(from_impl),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(item) = item {
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#![crate_name = "foo"]
|
||||
|
||||
pub struct Body;
|
||||
|
||||
impl Body {
|
||||
pub fn empty() -> Self {
|
||||
Body
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Default for Body {
|
||||
// @has foo/struct.Body.html '//a/@href' '../foo/struct.Body.html#method.empty'
|
||||
|
||||
/// Returns [`Body::empty()`](Body::empty).
|
||||
fn default() -> Body {
|
||||
Body::empty()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue