@@ -22,13 +22,13 @@ mod unit;
2222pub mod unit_dependencies;
2323pub mod unit_graph;
2424
25- use std:: collections:: HashSet ;
25+ use std:: collections:: { HashMap , HashSet } ;
2626use std:: env;
2727use std:: ffi:: { OsStr , OsString } ;
2828use std:: fs:: { self , File } ;
2929use std:: io:: { BufRead , Write } ;
3030use std:: path:: { Path , PathBuf } ;
31- use std:: sync:: Arc ;
31+ use std:: sync:: { Arc , Mutex } ;
3232
3333use anyhow:: { Context as _, Error } ;
3434use lazycell:: LazyCell ;
@@ -263,6 +263,7 @@ fn rustc(cx: &mut Context<'_, '_>, unit: &Unit, exec: &Arc<dyn Executor>) -> Car
263263 let script_metadata = cx. find_build_script_metadata ( unit) ;
264264 let is_local = unit. is_local ( ) ;
265265 let artifact = unit. artifact ;
266+ let completed_units = Arc :: clone ( & cx. completed_units ) ;
266267
267268 return Ok ( Work :: new ( move |state| {
268269 // Artifacts are in a different location than typical units,
@@ -292,7 +293,13 @@ fn rustc(cx: &mut Context<'_, '_>, unit: &Unit, exec: &Arc<dyn Executor>) -> Car
292293 ) ?;
293294 add_plugin_deps ( & mut rustc, & script_outputs, & build_scripts, & root_output) ?;
294295 }
295- add_custom_flags ( & mut rustc, & script_outputs, script_metadata) ?;
296+ add_custom_flags (
297+ & mut rustc,
298+ & script_outputs,
299+ script_metadata,
300+ completed_units,
301+ None ,
302+ ) ?;
296303 }
297304
298305 for output in outputs. iter ( ) {
@@ -639,9 +646,9 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Work> {
639646 let metadata = cx. metadata_for_doc_units [ unit] ;
640647 rustdoc. arg ( "-C" ) . arg ( format ! ( "metadata={}" , metadata) ) ;
641648
642- let scrape_output_path = |unit : & Unit | -> CargoResult < PathBuf > {
649+ let scrape_output_path = |unit : & Unit | -> PathBuf {
643650 let output_dir = cx. files ( ) . deps_dir ( unit) ;
644- Ok ( output_dir. join ( format ! ( "{}.examples" , unit. buildkey( ) ) ) )
651+ output_dir. join ( format ! ( "{}.examples" , unit. buildkey( ) ) )
645652 } ;
646653
647654 if unit. mode . is_doc_scrape ( ) {
@@ -651,7 +658,7 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Work> {
651658
652659 rustdoc
653660 . arg ( "--scrape-examples-output-path" )
654- . arg ( scrape_output_path ( unit) ? ) ;
661+ . arg ( scrape_output_path ( unit) ) ;
655662
656663 // Only scrape example for items from crates in the workspace, to reduce generated file size
657664 for pkg in cx. bcx . ws . members ( ) {
@@ -664,18 +671,24 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Work> {
664671 rustdoc. arg ( "--scrape-examples-target-crate" ) . arg ( name) ;
665672 }
666673 }
667- } else if cx. bcx . scrape_units . len ( ) > 0 && cx. bcx . ws . unit_needs_doc_scrape ( unit) {
674+ }
675+
676+ let scrape_units = if cx. bcx . scrape_units . len ( ) > 0 && cx. bcx . ws . unit_needs_doc_scrape ( unit) {
668677 // We only pass scraped examples to packages in the workspace
669678 // since examples are only coming from reverse-dependencies of workspace packages
670679
671680 rustdoc. arg ( "-Zunstable-options" ) ;
672681
673- for scrape_unit in & cx. bcx . scrape_units {
674- rustdoc
675- . arg ( "--with-examples" )
676- . arg ( scrape_output_path ( scrape_unit) ?) ;
677- }
678- }
682+ Some (
683+ cx. bcx
684+ . scrape_units
685+ . iter ( )
686+ . map ( |unit| ( cx. files ( ) . metadata ( unit) , scrape_output_path ( unit) ) )
687+ . collect :: < HashMap < _ , _ > > ( ) ,
688+ )
689+ } else {
690+ None
691+ } ;
679692
680693 build_deps_args ( & mut rustdoc, cx, unit) ?;
681694 rustdoc:: add_root_urls ( cx, unit, & mut rustdoc) ?;
@@ -693,11 +706,14 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Work> {
693706 let target = Target :: clone ( & unit. target ) ;
694707 let mut output_options = OutputOptions :: new ( cx, unit) ;
695708 let script_metadata = cx. find_build_script_metadata ( unit) ;
709+ let completed_units = Arc :: clone ( & cx. completed_units ) ;
696710 Ok ( Work :: new ( move |state| {
697711 add_custom_flags (
698712 & mut rustdoc,
699713 & build_script_outputs. lock ( ) . unwrap ( ) ,
700714 script_metadata,
715+ completed_units,
716+ scrape_units,
701717 ) ?;
702718 let crate_dir = doc_dir. join ( & crate_name) ;
703719 if crate_dir. exists ( ) {
@@ -706,6 +722,7 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Work> {
706722 debug ! ( "removing pre-existing doc directory {:?}" , crate_dir) ;
707723 paths:: remove_dir_all ( crate_dir) ?;
708724 }
725+
709726 state. running ( & rustdoc) ;
710727
711728 rustdoc
@@ -1165,6 +1182,8 @@ fn add_custom_flags(
11651182 cmd : & mut ProcessBuilder ,
11661183 build_script_outputs : & BuildScriptOutputs ,
11671184 metadata : Option < Metadata > ,
1185+ completed_units : Arc < Mutex < HashMap < Metadata , bool > > > ,
1186+ scrape_units : Option < HashMap < Metadata , PathBuf > > ,
11681187) -> CargoResult < ( ) > {
11691188 if let Some ( metadata) = metadata {
11701189 if let Some ( output) = build_script_outputs. get ( metadata) {
@@ -1183,6 +1202,16 @@ fn add_custom_flags(
11831202 }
11841203 }
11851204
1205+ if let Some ( scrape_units) = scrape_units {
1206+ let completed_units = completed_units. lock ( ) . unwrap ( ) ;
1207+ for ( _, output_path) in scrape_units
1208+ . iter ( )
1209+ . filter ( |( buildkey, _) | completed_units[ * buildkey] )
1210+ {
1211+ cmd. arg ( "--with-examples" ) . arg ( output_path) ;
1212+ }
1213+ }
1214+
11861215 Ok ( ( ) )
11871216}
11881217
0 commit comments