diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 80a18038272c7..4825ddc5a2034 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -79,6 +79,7 @@ use crate::html::sources; use crate::html::static_files::SCRAPE_EXAMPLES_HELP_MD; use crate::scrape_examples::{CallData, CallLocation}; use crate::try_none; +use crate::DOC_RUST_LANG_ORG_CHANNEL; /// A pair of name and its optional document. crate type NameDoc = (String, Option); @@ -463,17 +464,22 @@ fn settings(root_path: &str, suffix: &str, theme_names: Vec) -> Result) -> String { - let content = SCRAPE_EXAMPLES_HELP_MD; + let mut content = SCRAPE_EXAMPLES_HELP_MD.to_owned(); + content.push_str(&format!( + "## More information\n\n\ + If you want more information about this feature, please read the [corresponding chapter in the Rustdoc book]({}/rustdoc/scraped-examples.html).", + DOC_RUST_LANG_ORG_CHANNEL)); + let mut ids = IdMap::default(); format!( - "
+ "
\

\ About scraped examples\

\
\
{}
", Markdown { - content, + content: &content, links: &[], ids: &mut ids, error_codes: shared.codes, diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index bddc4326b7468..0da490f3cd6c8 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -71,14 +71,14 @@ crate struct SyntaxRange { } impl SyntaxRange { - fn new(span: rustc_span::Span, file: &SourceFile) -> Self { + fn new(span: rustc_span::Span, file: &SourceFile) -> Option { let get_pos = |bytepos: BytePos| file.original_relative_byte_pos(bytepos).0; - let get_line = |bytepos: BytePos| file.lookup_line(bytepos).unwrap(); + let get_line = |bytepos: BytePos| file.lookup_line(bytepos); - SyntaxRange { + Some(SyntaxRange { byte_span: (get_pos(span.lo()), get_pos(span.hi())), - line_span: (get_line(span.lo()), get_line(span.hi())), - } + line_span: (get_line(span.lo())?, get_line(span.hi())?), + }) } } @@ -95,12 +95,12 @@ impl CallLocation { ident_span: rustc_span::Span, enclosing_item_span: rustc_span::Span, source_file: &SourceFile, - ) -> Self { - CallLocation { - call_expr: SyntaxRange::new(expr_span, source_file), - call_ident: SyntaxRange::new(ident_span, source_file), - enclosing_item: SyntaxRange::new(enclosing_item_span, source_file), - } + ) -> Option { + Some(CallLocation { + call_expr: SyntaxRange::new(expr_span, source_file)?, + call_ident: SyntaxRange::new(ident_span, source_file)?, + enclosing_item: SyntaxRange::new(enclosing_item_span, source_file)?, + }) } } @@ -178,7 +178,7 @@ where // If this span comes from a macro expansion, then the source code may not actually show // a use of the given item, so it would be a poor example. Hence, we skip all uses in macros. if call_span.from_expansion() { - trace!("Rejecting expr from macro: {:?}", call_span); + trace!("Rejecting expr from macro: {call_span:?}"); return; } @@ -188,7 +188,7 @@ where .hir() .span_with_body(tcx.hir().local_def_id_to_hir_id(tcx.hir().get_parent_item(ex.hir_id))); if enclosing_item_span.from_expansion() { - trace!("Rejecting expr ({:?}) from macro item: {:?}", call_span, enclosing_item_span); + trace!("Rejecting expr ({call_span:?}) from macro item: {enclosing_item_span:?}"); return; } @@ -224,11 +224,27 @@ where }; if let Some(file_path) = file_path { - let abs_path = fs::canonicalize(file_path.clone()).unwrap(); + let abs_path = match fs::canonicalize(file_path.clone()) { + Ok(abs_path) => abs_path, + Err(_) => { + trace!("Could not canonicalize file path: {}", file_path.display()); + return; + } + }; + let cx = &self.cx; + let clean_span = crate::clean::types::Span::new(call_span); + let url = match cx.href_from_span(clean_span, false) { + Some(url) => url, + None => { + trace!( + "Rejecting expr ({call_span:?}) whose clean span ({clean_span:?}) cannot be turned into a link" + ); + return; + } + }; + let mk_call_data = || { - let clean_span = crate::clean::types::Span::new(call_span); - let url = cx.href_from_span(clean_span, false).unwrap(); let display_name = file_path.display().to_string(); let edition = call_span.edition(); CallData { locations: Vec::new(), url, display_name, edition } @@ -240,7 +256,14 @@ where trace!("Including expr: {:?}", call_span); let enclosing_item_span = source_map.span_extend_to_prev_char(enclosing_item_span, '\n', false); - let location = CallLocation::new(call_span, ident_span, enclosing_item_span, &file); + let location = + match CallLocation::new(call_span, ident_span, enclosing_item_span, &file) { + Some(location) => location, + None => { + trace!("Could not get serializable call location for {call_span:?}"); + return; + } + }; fn_entries.entry(abs_path).or_insert_with(mk_call_data).locations.push(location); } } @@ -274,8 +297,8 @@ crate fn run( .map(|(crate_num, _)| **crate_num) .collect::>(); - debug!("All crates in TyCtxt: {:?}", all_crates); - debug!("Scrape examples target_crates: {:?}", target_crates); + debug!("All crates in TyCtxt: {all_crates:?}"); + debug!("Scrape examples target_crates: {target_crates:?}"); // Run call-finder on all items let mut calls = FxHashMap::default();