Skip to content

Commit 3d5f130

Browse files
authored
Rollup merge of #72347 - xliiv:72340-impl-for-default, r=GuillaumeGomez
Make intra-link resolve links for both trait and impl items Closes #72340
2 parents dc65fd4 + fc4c9a6 commit 3d5f130

File tree

2 files changed

+54
-26
lines changed

2 files changed

+54
-26
lines changed

Diff for: src/librustdoc/passes/collect_intra_doc_links.rs

+35-26
Original file line numberDiff line numberDiff line change
@@ -232,37 +232,46 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
232232
DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::TyAlias,
233233
did,
234234
) => {
235-
// We need item's parent to know if it's
236-
// trait impl or struct/enum/etc impl
237-
let item_parent = item_opt
235+
// Checks if item_name belongs to `impl SomeItem`
236+
let impl_item = cx
237+
.tcx
238+
.inherent_impls(did)
239+
.iter()
240+
.flat_map(|imp| cx.tcx.associated_items(*imp).in_definition_order())
241+
.find(|item| item.ident.name == item_name);
242+
let trait_item = item_opt
238243
.and_then(|item| self.cx.as_local_hir_id(item.def_id))
239244
.and_then(|item_hir| {
245+
// Checks if item_name belongs to `impl SomeTrait for SomeItem`
240246
let parent_hir = self.cx.tcx.hir().get_parent_item(item_hir);
241-
self.cx.tcx.hir().find(parent_hir)
247+
let item_parent = self.cx.tcx.hir().find(parent_hir);
248+
match item_parent {
249+
Some(hir::Node::Item(hir::Item {
250+
kind: hir::ItemKind::Impl { of_trait: Some(_), self_ty, .. },
251+
..
252+
})) => cx
253+
.tcx
254+
.associated_item_def_ids(self_ty.hir_id.owner)
255+
.iter()
256+
.map(|child| {
257+
let associated_item = cx.tcx.associated_item(*child);
258+
associated_item
259+
})
260+
.find(|child| child.ident.name == item_name),
261+
_ => None,
262+
}
242263
});
243-
let item = match item_parent {
244-
Some(hir::Node::Item(hir::Item {
245-
kind: hir::ItemKind::Impl { of_trait: Some(_), self_ty, .. },
246-
..
247-
})) => {
248-
// trait impl
249-
cx.tcx
250-
.associated_item_def_ids(self_ty.hir_id.owner)
251-
.iter()
252-
.map(|child| {
253-
let associated_item = cx.tcx.associated_item(*child);
254-
associated_item
255-
})
256-
.find(|child| child.ident.name == item_name)
257-
}
258-
_ => {
259-
// struct/enum/etc. impl
260-
cx.tcx
261-
.inherent_impls(did)
262-
.iter()
263-
.flat_map(|imp| cx.tcx.associated_items(*imp).in_definition_order())
264-
.find(|item| item.ident.name == item_name)
264+
let item = match (impl_item, trait_item) {
265+
(Some(from_impl), Some(_)) => {
266+
// Although it's ambiguous, return impl version for compat. sake.
267+
// To handle that properly resolve() would have to support
268+
// something like
269+
// [`ambi_fn`](<SomeStruct as SomeTrait>::ambi_fn)
270+
Some(from_impl)
265271
}
272+
(None, Some(from_trait)) => Some(from_trait),
273+
(Some(from_impl), None) => Some(from_impl),
274+
_ => None,
266275
};
267276

268277
if let Some(item) = item {

Diff for: src/test/rustdoc/issue-72340.rs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![crate_name = "foo"]
2+
3+
pub struct Body;
4+
5+
impl Body {
6+
pub fn empty() -> Self {
7+
Body
8+
}
9+
10+
}
11+
12+
impl Default for Body {
13+
// @has foo/struct.Body.html '//a/@href' '../foo/struct.Body.html#method.empty'
14+
15+
/// Returns [`Body::empty()`](Body::empty).
16+
fn default() -> Body {
17+
Body::empty()
18+
}
19+
}

0 commit comments

Comments
 (0)