Make intra-link resolve links for both trait and impl items
This commit is contained in:
parent
914adf04af
commit
fc4c9a6c7f
2 changed files with 54 additions and 26 deletions
|
@ -232,37 +232,46 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||||
DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::TyAlias,
|
DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::TyAlias,
|
||||||
did,
|
did,
|
||||||
) => {
|
) => {
|
||||||
// We need item's parent to know if it's
|
// Checks if item_name belongs to `impl SomeItem`
|
||||||
// trait impl or struct/enum/etc impl
|
let impl_item = cx
|
||||||
let item_parent = item_opt
|
.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| self.cx.as_local_hir_id(item.def_id))
|
||||||
.and_then(|item_hir| {
|
.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);
|
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 {
|
let item = match (impl_item, trait_item) {
|
||||||
Some(hir::Node::Item(hir::Item {
|
(Some(from_impl), Some(_)) => {
|
||||||
kind: hir::ItemKind::Impl { of_trait: Some(_), self_ty, .. },
|
// Although it's ambiguous, return impl version for compat. sake.
|
||||||
..
|
// To handle that properly resolve() would have to support
|
||||||
})) => {
|
// something like
|
||||||
// trait impl
|
// [`ambi_fn`](<SomeStruct as SomeTrait>::ambi_fn)
|
||||||
cx.tcx
|
Some(from_impl)
|
||||||
.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)
|
|
||||||
}
|
}
|
||||||
|
(None, Some(from_trait)) => Some(from_trait),
|
||||||
|
(Some(from_impl), None) => Some(from_impl),
|
||||||
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(item) = item {
|
if let Some(item) = item {
|
||||||
|
|
19
src/test/rustdoc/issue-72340.rs
Normal file
19
src/test/rustdoc/issue-72340.rs
Normal file
|
@ -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…
Add table
Add a link
Reference in a new issue