Skip to content

Commit 18edcf8

Browse files
committed
Reduce blur size, fix example width bug, add better error handling for I/O issues
Remove repository url Fix formatting Fix file_span in print_src Formatting
1 parent 55bb517 commit 18edcf8

File tree

3 files changed

+68
-29
lines changed

3 files changed

+68
-29
lines changed

src/librustdoc/html/render/context.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ crate struct SharedContext<'tcx> {
124124
crate span_correspondance_map: FxHashMap<rustc_span::Span, LinkFromSrc>,
125125
/// The [`Cache`] used during rendering.
126126
crate cache: Cache,
127-
pub(super) repository_url: Option<String>,
128127
}
129128

130129
impl SharedContext<'_> {
@@ -141,11 +140,7 @@ impl SharedContext<'_> {
141140
/// Returns the `collapsed_doc_value` of the given item if this is the main crate, otherwise
142141
/// returns the `doc_value`.
143142
crate fn maybe_collapsed_doc_value<'a>(&self, item: &'a clean::Item) -> Option<String> {
144-
if self.collapsed {
145-
item.collapsed_doc_value()
146-
} else {
147-
item.doc_value()
148-
}
143+
if self.collapsed { item.collapsed_doc_value() } else { item.doc_value() }
149144
}
150145

151146
crate fn edition(&self) -> Edition {
@@ -351,7 +346,6 @@ impl<'tcx> Context<'tcx> {
351346
let hiline = span.hi(self.sess()).line;
352347
let lines =
353348
if loline == hiline { loline.to_string() } else { format!("{}-{}", loline, hiline) };
354-
355349
Some(format!(
356350
"{root}src/{krate}/{path}#{lines}",
357351
root = Escape(&root),
@@ -395,7 +389,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
395389
generate_redirect_map,
396390
show_type_layout,
397391
generate_link_to_definition,
398-
repository_url,
399392
..
400393
} = options;
401394

@@ -487,7 +480,6 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
487480
templates,
488481
span_correspondance_map: matches,
489482
cache,
490-
repository_url,
491483
};
492484

493485
// Add the default themes to the `Vec` of stylepaths

src/librustdoc/html/render/mod.rs

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use std::collections::VecDeque;
4040
use std::default::Default;
4141
use std::fmt;
4242
use std::fs;
43+
use std::iter::Peekable;
4344
use std::path::PathBuf;
4445
use std::str;
4546
use std::string::ToString;
@@ -53,7 +54,10 @@ use rustc_hir::def_id::DefId;
5354
use rustc_hir::Mutability;
5455
use rustc_middle::middle::stability;
5556
use rustc_middle::ty::TyCtxt;
56-
use rustc_span::symbol::{kw, sym, Symbol};
57+
use rustc_span::{
58+
symbol::{kw, sym, Symbol},
59+
BytePos, FileName, RealFileName,
60+
};
5761
use serde::ser::SerializeSeq;
5862
use serde::{Serialize, Serializer};
5963

@@ -590,7 +594,7 @@ fn document_full_inner(
590594

591595
match &*item.kind {
592596
clean::ItemKind::FunctionItem(f) | clean::ItemKind::MethodItem(f, _) => {
593-
render_call_locations(w, cx, &f.call_locations);
597+
render_call_locations(w, cx, &f.call_locations, item);
594598
}
595599
_ => {}
596600
}
@@ -2458,6 +2462,7 @@ fn render_call_locations(
24582462
w: &mut Buffer,
24592463
cx: &Context<'_>,
24602464
call_locations: &Option<FnCallLocations>,
2465+
item: &clean::Item,
24612466
) {
24622467
let call_locations = match call_locations.as_ref() {
24632468
Some(call_locations) if call_locations.len() > 0 => call_locations,
@@ -2488,11 +2493,17 @@ fn render_call_locations(
24882493
};
24892494

24902495
// Generate the HTML for a single example, being the title and code block
2491-
let write_example = |w: &mut Buffer, (path, call_data): (&PathBuf, &CallData)| {
2492-
// FIXME(wcrichto): is there a better way to handle an I/O error than a panic?
2493-
// When would such an error arise?
2494-
let contents =
2495-
fs::read_to_string(&path).expect(&format!("Failed to read file: {}", path.display()));
2496+
let tcx = cx.tcx();
2497+
let write_example = |w: &mut Buffer, (path, call_data): (&PathBuf, &CallData)| -> bool {
2498+
let contents = match fs::read_to_string(&path) {
2499+
Ok(contents) => contents,
2500+
Err(err) => {
2501+
let span = item.span(tcx).inner();
2502+
tcx.sess
2503+
.span_err(span, &format!("failed to read file {}: {}", path.display(), err));
2504+
return false;
2505+
}
2506+
};
24962507

24972508
// To reduce file sizes, we only want to embed the source code needed to understand the example, not
24982509
// the entire file. So we find the smallest byte range that covers all items enclosing examples.
@@ -2522,23 +2533,42 @@ fn render_call_locations(
25222533
let edition = cx.shared.edition();
25232534
write!(
25242535
w,
2525-
r#"<div class="scraped-example" data-code="{code}" data-locs="{locations}">
2536+
r#"<div class="scraped-example" data-locs="{locations}">
25262537
<div class="scraped-example-title">{title}</div>
25272538
<div class="code-wrapper">"#,
25282539
title = example_url(call_data),
2529-
// The code and locations are encoded as data attributes, so they can be read
2540+
// The locations are encoded as a data attribute, so they can be read
25302541
// later by the JS for interactions.
2531-
code = contents_subset.replace("\"", "&quot;"),
25322542
locations = serde_json::to_string(&line_ranges).unwrap(),
25332543
);
25342544
write!(w, r#"<span class="prev">&pr;</span> <span class="next">&sc;</span>"#);
25352545
write!(w, r#"<span class="expand">&varr;</span>"#);
25362546

2537-
// FIXME(wcrichto): where should file_span and root_path come from?
2538-
let file_span = rustc_span::DUMMY_SP;
2539-
let root_path = "".to_string();
2547+
// Look for the example file in the source map if it exists, otherwise return a dummy span
2548+
let file_span = (|| {
2549+
let source_map = tcx.sess.source_map();
2550+
let crate_src = tcx.sess.local_crate_source_file.as_ref()?;
2551+
let abs_crate_src = crate_src.canonicalize().ok()?;
2552+
let crate_root = abs_crate_src.parent()?.parent()?;
2553+
let rel_path = path.strip_prefix(crate_root).ok()?;
2554+
let files = source_map.files();
2555+
let file = files.iter().find(|file| match &file.name {
2556+
FileName::Real(RealFileName::LocalPath(other_path)) => rel_path == other_path,
2557+
_ => false,
2558+
})?;
2559+
Some(rustc_span::Span::with_root_ctxt(
2560+
file.start_pos + BytePos(min_byte),
2561+
file.start_pos + BytePos(max_byte),
2562+
))
2563+
})()
2564+
.unwrap_or(rustc_span::DUMMY_SP);
2565+
2566+
// The root path is the inverse of Context::current
2567+
let root_path = vec!["../"; cx.current.len() - 1].join("");
2568+
25402569
let mut decoration_info = FxHashMap::default();
25412570
decoration_info.insert("highlight", byte_ranges);
2571+
25422572
sources::print_src(
25432573
w,
25442574
contents_subset,
@@ -2550,6 +2580,8 @@ fn render_call_locations(
25502580
Some(decoration_info),
25512581
);
25522582
write!(w, "</div></div>");
2583+
2584+
true
25532585
};
25542586

25552587
// The call locations are output in sequence, so that sequence needs to be determined.
@@ -2570,7 +2602,15 @@ fn render_call_locations(
25702602

25712603
// Write just one example that's visible by default in the method's description.
25722604
let mut it = ordered_locations.into_iter().peekable();
2573-
write_example(w, it.next().unwrap());
2605+
let write_and_skip_failure = |w: &mut Buffer, it: &mut Peekable<_>| {
2606+
while let Some(example) = it.next() {
2607+
if write_example(&mut *w, example) {
2608+
break;
2609+
}
2610+
}
2611+
};
2612+
2613+
write_and_skip_failure(w, &mut it);
25742614

25752615
// Then add the remaining examples in a hidden section.
25762616
if it.peek().is_some() {
@@ -2582,13 +2622,15 @@ fn render_call_locations(
25822622
</summary>
25832623
<div class="more-scraped-examples">
25842624
<div class="toggle-line"><div class="toggle-line-inner"></div></div>
2585-
<div>
2625+
<div class="more-scraped-examples-inner">
25862626
"#
25872627
);
25882628

25892629
// Only generate inline code for MAX_FULL_EXAMPLES number of examples. Otherwise we could
25902630
// make the page arbitrarily huge!
2591-
(&mut it).take(MAX_FULL_EXAMPLES).for_each(|ex| write_example(w, ex));
2631+
for _ in 0..MAX_FULL_EXAMPLES {
2632+
write_and_skip_failure(w, &mut it);
2633+
}
25922634

25932635
// For the remaining examples, generate a <ul /> containing links to the source files.
25942636
if it.peek().is_some() {

src/librustdoc/html/static/css/rustdoc.css

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,7 +2020,7 @@ details.undocumented[open] > summary::before {
20202020
.scraped-example:not(.expanded) .code-wrapper:before {
20212021
content: " ";
20222022
width: 100%;
2023-
height: 20px;
2023+
height: 10px;
20242024
position: absolute;
20252025
z-index: 100;
20262026
top: 0;
@@ -2030,7 +2030,7 @@ details.undocumented[open] > summary::before {
20302030
.scraped-example:not(.expanded) .code-wrapper:after {
20312031
content: " ";
20322032
width: 100%;
2033-
height: 20px;
2033+
height: 10px;
20342034
position: absolute;
20352035
z-index: 100;
20362036
bottom: 0;
@@ -2078,10 +2078,15 @@ details.undocumented[open] > summary::before {
20782078
}
20792079

20802080
.more-scraped-examples {
2081-
padding-left: 10px;
2082-
margin-left: 15px;
2081+
margin-left: 25px;
20832082
display: flex;
20842083
flex-direction: row;
2084+
width: calc(100% - 25px);
2085+
}
2086+
2087+
.more-scraped-examples-inner {
2088+
/* 20px is width of toggle-line + toggle-line-inner */
2089+
width: calc(100% - 20px);
20852090
}
20862091

20872092
.toggle-line {

0 commit comments

Comments
 (0)