Skip to content

Commit 6e0fa52

Browse files
Generate links to doc on items' definition
1 parent 3a8b014 commit 6e0fa52

File tree

4 files changed

+52
-2
lines changed

4 files changed

+52
-2
lines changed

src/librustdoc/html/format.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ impl clean::GenericArgs {
517517
}
518518

519519
// Possible errors when computing href link source for a `DefId`
520+
#[derive(Debug)]
520521
pub(crate) enum HrefError {
521522
/// This item is known to rustdoc, but from a crate that does not have documentation generated.
522523
///

src/librustdoc/html/highlight.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,11 @@ fn string<T: Display>(
740740
)
741741
.ok()
742742
.map(|(url, _, _)| url),
743+
LinkFromSrc::Doc(def_id) => {
744+
format::href_with_root_path(*def_id, context, Some(&context_info.root_path))
745+
.ok()
746+
.map(|(doc_link, _, _)| doc_link)
747+
}
743748
}
744749
})
745750
{

src/librustdoc/html/render/context.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ pub(crate) struct SharedContext<'tcx> {
116116
/// to `Some(...)`, it'll store redirections and then generate a JSON file at the top level of
117117
/// the crate.
118118
redirections: Option<RefCell<FxHashMap<String, String>>>,
119-
120119
/// Correspondance map used to link types used in the source code pages to allow to click on
121120
/// links to jump to the type's definition.
122121
pub(crate) span_correspondance_map: FxHashMap<rustc_span::Span, LinkFromSrc>,

src/librustdoc/html/render/span_map.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1+
use crate::clean::types::rustc_span;
12
use crate::clean::{self, PrimitiveType};
23
use crate::html::sources;
34

45
use rustc_data_structures::fx::FxHashMap;
56
use rustc_hir::def::{DefKind, Res};
6-
use rustc_hir::def_id::DefId;
7+
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
78
use rustc_hir::intravisit::{self, Visitor};
89
use rustc_hir::{ExprKind, HirId, Mod, Node};
910
use rustc_middle::hir::nested_filter;
11+
use rustc_hir::{ExprKind, GenericParam, GenericParamKind, HirId, Item, ItemKind, Mod, Node};
1012
use rustc_middle::ty::TyCtxt;
1113
use rustc_span::Span;
1214

@@ -24,6 +26,7 @@ pub(crate) enum LinkFromSrc {
2426
Local(clean::Span),
2527
External(DefId),
2628
Primitive(PrimitiveType),
29+
Doc(DefId),
2730
}
2831

2932
/// This function will do at most two things:
@@ -91,6 +94,21 @@ impl<'tcx> SpanMapVisitor<'tcx> {
9194
self.matches.insert(path_span.unwrap_or(path.span), LinkFromSrc::External(def_id));
9295
}
9396
}
97+
98+
/// Used to generate links on items' definition to go to their documentation page.
99+
crate fn extract_info_from_hir_id(&mut self, hir_id: HirId) {
100+
if let Some(def_id) = self.tcx.hir().opt_local_def_id(hir_id) {
101+
if let Some(span) = self.tcx.def_ident_span(def_id) {
102+
let cspan = clean::Span::new(span);
103+
let def_id = def_id.to_def_id();
104+
// If the span isn't from the current crate, we ignore it.
105+
if cspan.is_dummy() || cspan.cnum(self.tcx.sess) != LOCAL_CRATE {
106+
return;
107+
}
108+
self.matches.insert(span, LinkFromSrc::Doc(def_id));
109+
}
110+
}
111+
}
94112
}
95113

96114
impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
@@ -117,6 +135,9 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
117135
LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)),
118136
);
119137
}
138+
} else {
139+
// If it's a "mod foo {}", we want to look to its documentation page.
140+
self.extract_info_from_hir_id(id);
120141
}
121142
intravisit::walk_mod(self, m, id);
122143
}
@@ -151,4 +172,28 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
151172
self.handle_path(path, None);
152173
intravisit::walk_use(self, path, id);
153174
}
175+
176+
fn visit_item(&mut self, item: &'tcx Item<'tcx>) {
177+
match item.kind {
178+
ItemKind::Static(_, _, _)
179+
| ItemKind::Const(_, _)
180+
| ItemKind::Fn(_, _, _)
181+
| ItemKind::Macro(_)
182+
| ItemKind::TyAlias(_, _)
183+
| ItemKind::Enum(_, _)
184+
| ItemKind::Struct(_, _)
185+
| ItemKind::Union(_, _)
186+
| ItemKind::Trait(_, _, _, _, _)
187+
| ItemKind::TraitAlias(_, _) => self.extract_info_from_hir_id(item.hir_id()),
188+
ItemKind::Impl(_)
189+
| ItemKind::Use(_, _)
190+
| ItemKind::ExternCrate(_)
191+
| ItemKind::ForeignMod { .. }
192+
| ItemKind::GlobalAsm(_)
193+
| ItemKind::OpaqueTy(_)
194+
// We already have "visit_mod" above so no need to check it here.
195+
| ItemKind::Mod(_) => {}
196+
}
197+
intravisit::walk_item(self, item);
198+
}
154199
}

0 commit comments

Comments
 (0)