Skip to content

Commit ef24747

Browse files
committed
rustdoc: use more precise URLs for jump-to-definition links
As an example, this cuts down <https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_middle/ty/mod.rs.html> by about 11%. $ du -h new_mod.rs.html old_mod.rs.html 296K new_mod.rs.html 332K old_mod.rs.html
1 parent 35a0407 commit ef24747

File tree

3 files changed

+39
-4
lines changed

3 files changed

+39
-4
lines changed

src/librustdoc/html/highlight.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ pub(crate) struct HrefContext<'a, 'b, 'c> {
2929
/// This field is used to know "how far" from the top of the directory we are to link to either
3030
/// documentation pages or other source pages.
3131
pub(crate) root_path: &'c str,
32+
/// This field is used to calculate precise local URLs.
33+
pub(crate) current_href: &'c str,
3234
}
3335

3436
/// Decorations are represented as a map from CSS class to vector of character ranges.
@@ -977,9 +979,9 @@ fn string_without_closing_tag<T: Display>(
977979
// a link to their definition can be generated using this:
978980
// https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338
979981
match href {
980-
LinkFromSrc::Local(span) => context
981-
.href_from_span(*span, true)
982-
.map(|s| format!("{}{}", href_context.root_path, s)),
982+
LinkFromSrc::Local(span) => {
983+
context.href_from_span_relative(*span, href_context.current_href)
984+
}
983985
LinkFromSrc::External(def_id) => {
984986
format::href_with_root_path(*def_id, context, Some(href_context.root_path))
985987
.ok()

src/librustdoc/html/render/context.rs

+30
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use crate::formats::FormatRenderer;
3131
use crate::html::escape::Escape;
3232
use crate::html::format::{join_with_double_colon, Buffer};
3333
use crate::html::markdown::{self, plain_text_summary, ErrorCodes, IdMap};
34+
use crate::html::url_parts_builder::UrlPartsBuilder;
3435
use crate::html::{layout, sources};
3536
use crate::scrape_examples::AllCallLocations;
3637
use crate::try_err;
@@ -370,6 +371,35 @@ impl<'tcx> Context<'tcx> {
370371
anchor = anchor
371372
))
372373
}
374+
375+
pub(crate) fn href_from_span_relative(
376+
&self,
377+
span: clean::Span,
378+
relative_to: &str,
379+
) -> Option<String> {
380+
self.href_from_span(span, false).map(|s| {
381+
let mut url = UrlPartsBuilder::new();
382+
let mut dest_href_parts = s.split('/');
383+
let mut cur_href_parts = relative_to.split('/');
384+
for (cur_href_part, dest_href_part) in (&mut cur_href_parts).zip(&mut dest_href_parts) {
385+
if cur_href_part != dest_href_part {
386+
url.push(dest_href_part);
387+
break;
388+
}
389+
}
390+
for dest_href_part in dest_href_parts {
391+
url.push(dest_href_part);
392+
}
393+
let loline = span.lo(self.sess()).line;
394+
let hiline = span.hi(self.sess()).line;
395+
format!(
396+
"{}{}#{}",
397+
"../".repeat(cur_href_parts.count()),
398+
url.finish(),
399+
if loline == hiline { loline.to_string() } else { format!("{loline}-{hiline}") }
400+
)
401+
})
402+
}
373403
}
374404

375405
/// Generates the documentation for `crate` into the directory `dst`

src/librustdoc/html/sources.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,14 @@ pub(crate) fn print_src(
288288
}
289289
}
290290
line_numbers.write_str("</pre>");
291+
let current_href = &context
292+
.href_from_span(clean::Span::new(file_span), false)
293+
.expect("only local crates should have sources emitted");
291294
highlight::render_source_with_highlighting(
292295
s,
293296
buf,
294297
line_numbers,
295-
highlight::HrefContext { context, file_span, root_path },
298+
highlight::HrefContext { context, file_span, root_path, current_href },
296299
decoration_info,
297300
);
298301
}

0 commit comments

Comments
 (0)