@@ -73,8 +73,9 @@ use crate::html::format::{
7373 print_generic_bounds, print_where_clause, Buffer , HrefError , PrintWithSpace ,
7474} ;
7575use crate :: html:: markdown:: { HeadingOffset , Markdown , MarkdownHtml , MarkdownSummaryLine } ;
76+ use crate :: html:: highlight;
7677use crate :: html:: sources;
77- use crate :: scrape_examples:: { CallData , FnCallLocations } ;
78+ use crate :: scrape_examples:: CallData ;
7879
7980/// A pair of name and its optional document.
8081crate type NameDoc = ( String , Option < String > ) ;
@@ -592,9 +593,13 @@ fn document_full_inner(
592593 }
593594 }
594595
595- match & * item. kind {
596+ let kind = match & * item. kind {
597+ clean:: ItemKind :: StrippedItem ( box kind) | kind => kind,
598+ } ;
599+
600+ match kind {
596601 clean:: ItemKind :: FunctionItem ( f) | clean:: ItemKind :: MethodItem ( f, _) => {
597- render_call_locations ( w, cx, & f . call_locations , item) ;
602+ render_call_locations ( w, cx, f . def_id , item) ;
598603 }
599604 _ => { }
600605 }
@@ -2458,14 +2463,11 @@ fn collect_paths_for_type(first_ty: clean::Type, cache: &Cache) -> Vec<String> {
24582463const MAX_FULL_EXAMPLES : usize = 5 ;
24592464
24602465/// Generates the HTML for example call locations generated via the --scrape-examples flag.
2461- fn render_call_locations (
2462- w : & mut Buffer ,
2463- cx : & Context < ' _ > ,
2464- call_locations : & Option < FnCallLocations > ,
2465- item : & clean:: Item ,
2466- ) {
2467- let call_locations = match call_locations. as_ref ( ) {
2468- Some ( call_locations) if call_locations. len ( ) > 0 => call_locations,
2466+ fn render_call_locations ( w : & mut Buffer , cx : & Context < ' _ > , def_id : DefId , item : & clean:: Item ) {
2467+ let tcx = cx. tcx ( ) ;
2468+ let key = crate :: scrape_examples:: def_id_call_key ( tcx, def_id) ;
2469+ let call_locations = match cx. shared . call_locations . get ( & key) {
2470+ Some ( call_locations) => call_locations,
24692471 _ => {
24702472 return ;
24712473 }
@@ -2483,7 +2485,6 @@ fn render_call_locations(
24832485 ) ;
24842486
24852487 // Generate the HTML for a single example, being the title and code block
2486- let tcx = cx. tcx ( ) ;
24872488 let write_example = |w : & mut Buffer , ( path, call_data) : ( & PathBuf , & CallData ) | -> bool {
24882489 let contents = match fs:: read_to_string ( & path) {
24892490 Ok ( contents) => contents,
@@ -2497,40 +2498,51 @@ fn render_call_locations(
24972498
24982499 // To reduce file sizes, we only want to embed the source code needed to understand the example, not
24992500 // the entire file. So we find the smallest byte range that covers all items enclosing examples.
2500- assert ! ( call_data. locations. len ( ) > 0 ) ;
2501+ assert ! ( ! call_data. locations. is_empty ( ) ) ;
25012502 let min_loc =
25022503 call_data. locations . iter ( ) . min_by_key ( |loc| loc. enclosing_item . byte_span . 0 ) . unwrap ( ) ;
2503- let min_byte = min_loc. enclosing_item . byte_span . 0 ;
2504- let min_line = min_loc. enclosing_item . line_span . 0 ;
2505- let max_byte =
2504+ let ( byte_offset , _ ) = min_loc. enclosing_item . byte_span ;
2505+ let ( line_offset , _ ) = min_loc. enclosing_item . line_span ;
2506+ let byte_ceiling =
25062507 call_data. locations . iter ( ) . map ( |loc| loc. enclosing_item . byte_span . 1 ) . max ( ) . unwrap ( ) ;
25072508
25082509 // The output code is limited to that byte range.
2509- let contents_subset = & contents[ ( min_byte as usize ) ..( max_byte as usize ) ] ;
2510+ let contents_subset = & contents[ ( byte_offset as usize ) ..( byte_ceiling as usize ) ] ;
25102511
25112512 // The call locations need to be updated to reflect that the size of the program has changed.
2512- // Specifically, the ranges are all subtracted by `min_byte ` since that's the new zero point.
2513+ // Specifically, the ranges are all subtracted by `byte_offset ` since that's the new zero point.
25132514 let ( byte_ranges, line_ranges) : ( Vec < _ > , Vec < _ > ) = call_data
25142515 . locations
25152516 . iter ( )
25162517 . map ( |loc| {
25172518 let ( byte_lo, byte_hi) = loc. call_expr . byte_span ;
25182519 let ( line_lo, line_hi) = loc. call_expr . line_span ;
2519- ( ( byte_lo - min_byte, byte_hi - min_byte) , ( line_lo - min_line, line_hi - min_line) )
2520+ (
2521+ ( byte_lo - byte_offset, byte_hi - byte_offset) ,
2522+ ( line_lo - line_offset, line_hi - line_offset) ,
2523+ )
25202524 } )
25212525 . unzip ( ) ;
25222526
2523- let edition = cx. shared . edition ( ) ;
2527+ let ( init_min, init_max) = line_ranges[ 0 ] ;
2528+ let line_range = if init_min == init_max {
2529+ format ! ( "line {}" , init_min + line_offset + 1 )
2530+ } else {
2531+ format ! ( "lines {}-{}" , init_min + line_offset + 1 , init_max + line_offset + 1 )
2532+ } ;
2533+
25242534 write ! (
25252535 w,
2526- r#"<div class="scraped-example" data-locs="{locations}">
2536+ r#"<div class="scraped-example" data-locs="{locations}" data-offset="{offset}" >
25272537 <div class="scraped-example-title">
2528- {name} <a href="{root}{url}" target="_blank">[src] </a>
2538+ {name} ( <a href="{root}{url}" target="_blank">{line_range} </a>)
25292539 </div>
25302540 <div class="code-wrapper">"# ,
25312541 root = cx. root_path( ) ,
25322542 url = call_data. url,
25332543 name = call_data. display_name,
2544+ line_range = line_range,
2545+ offset = line_offset,
25342546 // The locations are encoded as a data attribute, so they can be read
25352547 // later by the JS for interactions.
25362548 locations = serde_json:: to_string( & line_ranges) . unwrap( ) ,
@@ -2551,8 +2563,8 @@ fn render_call_locations(
25512563 _ => false ,
25522564 } ) ?;
25532565 Some ( rustc_span:: Span :: with_root_ctxt (
2554- file. start_pos + BytePos ( min_byte ) ,
2555- file. start_pos + BytePos ( max_byte ) ,
2566+ file. start_pos + BytePos ( byte_offset ) ,
2567+ file. start_pos + BytePos ( byte_ceiling ) ,
25562568 ) )
25572569 } ) ( )
25582570 . unwrap_or ( rustc_span:: DUMMY_SP ) ;
@@ -2566,12 +2578,12 @@ fn render_call_locations(
25662578 sources:: print_src (
25672579 w,
25682580 contents_subset,
2569- edition,
2581+ call_data . edition ,
25702582 file_span,
25712583 cx,
25722584 & root_path,
2573- Some ( min_line ) ,
2574- Some ( decoration_info) ,
2585+ Some ( line_offset ) ,
2586+ Some ( highlight :: DecorationInfo ( decoration_info) ) ,
25752587 ) ;
25762588 write ! ( w, "</div></div>" ) ;
25772589
@@ -2590,12 +2602,14 @@ fn render_call_locations(
25902602 } ;
25912603
25922604 let mut locs = call_locations. into_iter ( ) . collect :: < Vec < _ > > ( ) ;
2593- locs. sort_by_key ( |x| sort_criterion ( x ) ) ;
2605+ locs. sort_by_key ( sort_criterion) ;
25942606 locs
25952607 } ;
25962608
2597- // Write just one example that's visible by default in the method's description.
25982609 let mut it = ordered_locations. into_iter ( ) . peekable ( ) ;
2610+
2611+ // An example may fail to write if its source can't be read for some reason, so this method
2612+ // continues iterating until a write suceeds
25992613 let write_and_skip_failure = |w : & mut Buffer , it : & mut Peekable < _ > | {
26002614 while let Some ( example) = it. next ( ) {
26012615 if write_example ( & mut * w, example) {
@@ -2604,6 +2618,7 @@ fn render_call_locations(
26042618 }
26052619 } ;
26062620
2621+ // Write just one example that's visible by default in the method's description.
26072622 write_and_skip_failure ( w, & mut it) ;
26082623
26092624 // Then add the remaining examples in a hidden section.
@@ -2626,7 +2641,7 @@ fn render_call_locations(
26262641 write_and_skip_failure ( w, & mut it) ;
26272642 }
26282643
2629- // For the remaining examples, generate a <ul / > containing links to the source files.
2644+ // For the remaining examples, generate a <ul> containing links to the source files.
26302645 if it. peek ( ) . is_some ( ) {
26312646 write ! (
26322647 w,
@@ -2635,7 +2650,7 @@ fn render_call_locations(
26352650 it. for_each ( |( _, call_data) | {
26362651 write ! (
26372652 w,
2638- r#"<li><a href="{}{ }" target="_blank">{}</a></li>"# ,
2653+ r#"<li><a href="{root}{url }" target="_blank">{name }</a></li>"# ,
26392654 root = cx. root_path( ) ,
26402655 url = call_data. url,
26412656 name = call_data. display_name
0 commit comments