Skip to content

Commit da0745a

Browse files
authored
Rollup merge of #72173 - xliiv:54172-intra-for-trait-impl, r=GuillaumeGomez
Make intra links work inside trait impl block Closes #54172
2 parents 7709688 + 617c7cd commit da0745a

File tree

2 files changed

+90
-11
lines changed

2 files changed

+90
-11
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

+55-11
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ use rustc_hir::def_id::DefId;
1212
use rustc_middle::ty;
1313
use rustc_resolve::ParentScope;
1414
use rustc_session::lint;
15-
use rustc_span::symbol::{Ident, Symbol};
15+
use rustc_span::symbol::Ident;
16+
use rustc_span::symbol::Symbol;
1617
use rustc_span::DUMMY_SP;
1718

1819
use std::ops::Range;
@@ -130,6 +131,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
130131
current_item: &Option<String>,
131132
parent_id: Option<hir::HirId>,
132133
extra_fragment: &Option<String>,
134+
item_opt: Option<&Item>,
133135
) -> Result<(Res, Option<String>), ErrorKind> {
134136
let cx = self.cx;
135137

@@ -230,16 +232,44 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
230232
DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::TyAlias,
231233
did,
232234
) => {
233-
let item = cx
234-
.tcx
235-
.inherent_impls(did)
236-
.iter()
237-
.flat_map(|imp| cx.tcx.associated_items(*imp).in_definition_order())
238-
.find(|item| item.ident.name == item_name);
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
238+
.and_then(|item| self.cx.as_local_hir_id(item.def_id))
239+
.and_then(|item_hir| {
240+
let parent_hir = self.cx.tcx.hir().get_parent_item(item_hir);
241+
self.cx.tcx.hir().find(parent_hir)
242+
});
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)
265+
}
266+
};
267+
239268
if let Some(item) = item {
240269
let out = match item.kind {
241270
ty::AssocKind::Fn if ns == ValueNS => "method",
242271
ty::AssocKind::Const if ns == ValueNS => "associatedconstant",
272+
ty::AssocKind::Type if ns == ValueNS => "associatedtype",
243273
_ => return self.variant_field(path_str, current_item, module_id),
244274
};
245275
if extra_fragment.is_some() {
@@ -484,8 +514,14 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
484514

485515
match kind {
486516
Some(ns @ ValueNS) => {
487-
match self.resolve(path_str, ns, &current_item, base_node, &extra_fragment)
488-
{
517+
match self.resolve(
518+
path_str,
519+
ns,
520+
&current_item,
521+
base_node,
522+
&extra_fragment,
523+
None,
524+
) {
489525
Ok(res) => res,
490526
Err(ErrorKind::ResolutionFailure) => {
491527
resolution_failure(cx, &item, path_str, &dox, link_range);
@@ -501,8 +537,14 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
501537
}
502538
}
503539
Some(ns @ TypeNS) => {
504-
match self.resolve(path_str, ns, &current_item, base_node, &extra_fragment)
505-
{
540+
match self.resolve(
541+
path_str,
542+
ns,
543+
&current_item,
544+
base_node,
545+
&extra_fragment,
546+
None,
547+
) {
506548
Ok(res) => res,
507549
Err(ErrorKind::ResolutionFailure) => {
508550
resolution_failure(cx, &item, path_str, &dox, link_range);
@@ -526,6 +568,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
526568
&current_item,
527569
base_node,
528570
&extra_fragment,
571+
None,
529572
) {
530573
Err(ErrorKind::AnchorFailure(msg)) => {
531574
anchor_failure(cx, &item, &ori_link, &dox, link_range, msg);
@@ -539,6 +582,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
539582
&current_item,
540583
base_node,
541584
&extra_fragment,
585+
Some(&item),
542586
) {
543587
Err(ErrorKind::AnchorFailure(msg)) => {
544588
anchor_failure(cx, &item, &ori_link, &dox, link_range, msg);
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#![crate_name = "foo"]
2+
3+
// ignore-tidy-linelength
4+
5+
pub struct MyStruct;
6+
7+
impl MyTrait for MyStruct {
8+
9+
// @has foo/struct.MyStruct.html '//a/@href' '../foo/struct.MyStruct.html#associatedtype.AssoType'
10+
11+
/// [`AssoType`]
12+
///
13+
/// [`AssoType`]: MyStruct::AssoType
14+
type AssoType = u32;
15+
16+
// @has foo/struct.MyStruct.html '//a/@href' '../foo/struct.MyStruct.html#associatedconstant.ASSO_CONST'
17+
18+
/// [`ASSO_CONST`]
19+
///
20+
/// [`ASSO_CONST`]: MyStruct::ASSO_CONST
21+
const ASSO_CONST: i32 = 10;
22+
23+
// @has foo/struct.MyStruct.html '//a/@href' '../foo/struct.MyStruct.html#method.trait_fn'
24+
25+
/// [`trait_fn`]
26+
///
27+
/// [`trait_fn`]: MyStruct::trait_fn
28+
fn trait_fn() { }
29+
}
30+
31+
pub trait MyTrait {
32+
type AssoType;
33+
const ASSO_CONST: i32 = 1;
34+
fn trait_fn();
35+
}

0 commit comments

Comments
 (0)