Skip to content

Commit db8d34b

Browse files
Make all source code links point to source code
1 parent 6e0fa52 commit db8d34b

File tree

3 files changed

+42
-30
lines changed

3 files changed

+42
-30
lines changed

src/librustdoc/html/highlight.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -728,11 +728,13 @@ fn string<T: Display>(
728728
LinkFromSrc::Local(span) => context
729729
.href_from_span(*span, true)
730730
.map(|s| format!("{}{}", context_info.root_path, s)),
731-
LinkFromSrc::External(def_id) => {
732-
format::href_with_root_path(*def_id, context, Some(context_info.root_path))
733-
.ok()
734-
.map(|(url, _, _)| url)
735-
}
731+
LinkFromSrc::External(span) => context.href_from_span(*span, true).map(|s| {
732+
if s.starts_with("http://") || s.starts_with("https://") {
733+
s
734+
} else {
735+
format!("{}{}", context_info.root_path, s)
736+
}
737+
}),
736738
LinkFromSrc::Primitive(prim) => format::href_with_root_path(
737739
PrimitiveType::primitive_locations(context.tcx())[prim],
738740
context,

src/librustdoc/html/render/context.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,12 @@ impl<'tcx> Context<'tcx> {
335335
let e = ExternalCrate { crate_num: cnum };
336336
(e.name(self.tcx()), e.src_root(self.tcx()))
337337
}
338-
ExternalLocation::Unknown => return None,
338+
ExternalLocation::Unknown => {
339+
let e = ExternalCrate { crate_num: cnum };
340+
let name = e.name(self.tcx());
341+
root = name.to_string();
342+
(name, e.src_root(self.tcx()))
343+
}
339344
};
340345

341346
sources::clean_path(&src_root, file, false, |component| {

src/librustdoc/html/render/span_map.rs

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ use rustc_data_structures::fx::FxHashMap;
66
use rustc_hir::def::{DefKind, Res};
77
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
88
use rustc_hir::intravisit::{self, Visitor};
9-
use rustc_hir::{ExprKind, HirId, Mod, Node};
9+
use rustc_hir::{ExprKind, HirId, Item, ItemKind, Mod, Node};
1010
use rustc_middle::hir::nested_filter;
11-
use rustc_hir::{ExprKind, GenericParam, GenericParamKind, HirId, Item, ItemKind, Mod, Node};
1211
use rustc_middle::ty::TyCtxt;
1312
use rustc_span::Span;
1413

@@ -24,7 +23,7 @@ use std::path::{Path, PathBuf};
2423
#[derive(Debug)]
2524
pub(crate) enum LinkFromSrc {
2625
Local(clean::Span),
27-
External(DefId),
26+
External(clean::Span),
2827
Primitive(PrimitiveType),
2928
Doc(DefId),
3029
}
@@ -67,36 +66,42 @@ struct SpanMapVisitor<'tcx> {
6766
impl<'tcx> SpanMapVisitor<'tcx> {
6867
/// This function is where we handle `hir::Path` elements and add them into the "span map".
6968
fn handle_path(&mut self, path: &rustc_hir::Path<'_>, path_span: Option<Span>) {
70-
let info = match path.res {
69+
match path.res {
7170
// FIXME: For now, we only handle `DefKind` if it's not `DefKind::TyParam` or
7271
// `DefKind::Macro`. Would be nice to support them too alongside the other `DefKind`
7372
// (such as primitive types!).
7473
Res::Def(kind, def_id) if kind != DefKind::TyParam => {
7574
if matches!(kind, DefKind::Macro(_)) {
7675
return;
7776
}
78-
Some(def_id)
77+
let span = rustc_span(def_id, self.tcx);
78+
let link = if def_id.as_local().is_some() {
79+
LinkFromSrc::Local(span)
80+
} else {
81+
LinkFromSrc::External(span)
82+
};
83+
self.matches.insert(path_span.unwrap_or(path.span), link);
84+
}
85+
Res::Local(_) => {
86+
if let Some(span) = self.tcx.hir().res_span(path.res) {
87+
self.matches.insert(
88+
path_span.unwrap_or(path.span),
89+
LinkFromSrc::Local(clean::Span::new(span)),
90+
);
91+
}
7992
}
80-
Res::Local(_) => None,
8193
Res::PrimTy(p) => {
8294
// FIXME: Doesn't handle "path-like" primitives like arrays or tuples.
8395
let span = path_span.unwrap_or(path.span);
8496
self.matches.insert(span, LinkFromSrc::Primitive(PrimitiveType::from(p)));
85-
return;
8697
}
87-
Res::Err => return,
88-
_ => return,
89-
};
90-
if let Some(span) = self.tcx.hir().res_span(path.res) {
91-
self.matches
92-
.insert(path_span.unwrap_or(path.span), LinkFromSrc::Local(clean::Span::new(span)));
93-
} else if let Some(def_id) = info {
94-
self.matches.insert(path_span.unwrap_or(path.span), LinkFromSrc::External(def_id));
98+
Res::Err => {}
99+
_ => {}
95100
}
96101
}
97102

98103
/// 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) {
104+
pub(crate) fn extract_info_from_hir_id(&mut self, hir_id: HirId) {
100105
if let Some(def_id) = self.tcx.hir().opt_local_def_id(hir_id) {
101106
if let Some(span) = self.tcx.def_ident_span(def_id) {
102107
let cspan = clean::Span::new(span);
@@ -155,13 +160,13 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
155160
hir.maybe_body_owned_by(body_id).expect("a body which isn't a body"),
156161
);
157162
if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) {
158-
self.matches.insert(
159-
segment.ident.span,
160-
match hir.span_if_local(def_id) {
161-
Some(span) => LinkFromSrc::Local(clean::Span::new(span)),
162-
None => LinkFromSrc::External(def_id),
163-
},
164-
);
163+
let span = rustc_span(def_id, self.tcx);
164+
let link = if def_id.as_local().is_some() {
165+
LinkFromSrc::Local(span)
166+
} else {
167+
LinkFromSrc::External(span)
168+
};
169+
self.matches.insert(segment.ident.span, link);
165170
}
166171
}
167172
}
@@ -178,7 +183,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
178183
ItemKind::Static(_, _, _)
179184
| ItemKind::Const(_, _)
180185
| ItemKind::Fn(_, _, _)
181-
| ItemKind::Macro(_)
186+
| ItemKind::Macro(_, _)
182187
| ItemKind::TyAlias(_, _)
183188
| ItemKind::Enum(_, _)
184189
| ItemKind::Struct(_, _)

0 commit comments

Comments
 (0)