@@ -621,12 +621,20 @@ impl Step for SharedAssets {
621621 }
622622}
623623
624+ /// Document the standard library using `build_compiler`.
625+ #[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
626+ enum StdWorkspace {
627+ Std ,
628+ Stdarch ,
629+ }
630+
624631/// Document the standard library using `build_compiler`.
625632#[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
626633pub struct Std {
627634 build_compiler : Compiler ,
628635 target : TargetSelection ,
629636 format : DocumentationFormat ,
637+ workspace : StdWorkspace ,
630638 crates : Vec < String > ,
631639}
632640
@@ -636,7 +644,7 @@ impl Std {
636644 target : TargetSelection ,
637645 format : DocumentationFormat ,
638646 ) -> Self {
639- Std { build_compiler, target, format, crates : vec ! [ ] }
647+ Std { build_compiler, target, format, workspace : StdWorkspace :: Std , crates : vec ! [ ] }
640648 }
641649}
642650
@@ -645,29 +653,88 @@ impl Step for Std {
645653 type Output = PathBuf ;
646654
647655 fn should_run ( run : ShouldRun < ' _ > ) -> ShouldRun < ' _ > {
648- run. crate_or_deps ( "sysroot" ) . path ( "library" )
656+ run. crate_or_deps ( "sysroot" )
657+ . path ( "library" )
658+ . path ( "library/stdarch" )
659+ . path ( "library/stdarch/crates/core_arch" )
660+ . path ( "library/stdarch/examples" )
649661 }
650662
651663 fn is_default_step ( builder : & Builder < ' _ > ) -> bool {
652664 builder. config . docs
653665 }
654666
655667 fn make_run ( run : RunConfig < ' _ > ) {
656- let crates = compile:: std_crates_for_run_make ( & run) ;
657- let target_is_no_std = run. builder . no_std ( run. target ) . unwrap_or ( false ) ;
658- if crates. is_empty ( ) && target_is_no_std {
668+ let builder = run. builder ;
669+ let build_compiler = builder. compiler_for_std ( builder. top_stage ) ;
670+ let format = if builder. config . cmd . json ( ) {
671+ DocumentationFormat :: Json
672+ } else {
673+ DocumentationFormat :: Html
674+ } ;
675+
676+ if run. paths . is_empty ( ) {
677+ let crates = compile:: std_crates_for_run_make ( & run) ;
678+ let target_is_no_std = builder. no_std ( run. target ) . unwrap_or ( false ) ;
679+ if crates. is_empty ( ) && target_is_no_std {
680+ return ;
681+ }
682+ builder. ensure ( Std {
683+ build_compiler,
684+ target : run. target ,
685+ format,
686+ workspace : StdWorkspace :: Std ,
687+ crates,
688+ } ) ;
659689 return ;
660690 }
661- run. builder . ensure ( Std {
662- build_compiler : run. builder . compiler_for_std ( run. builder . top_stage ) ,
663- target : run. target ,
664- format : if run. builder . config . cmd . json ( ) {
665- DocumentationFormat :: Json
666- } else {
667- DocumentationFormat :: Html
668- } ,
669- crates,
670- } ) ;
691+
692+ let mut std_crates = Vec :: new ( ) ;
693+ let mut stdarch_crates = Vec :: new ( ) ;
694+ let mut stdarch_requested = false ;
695+
696+ for pathset in & run. paths {
697+ let path = & pathset. assert_single_path ( ) . path ;
698+ if path. starts_with ( "library/stdarch" ) {
699+ stdarch_requested = true ;
700+ if let Some ( krate) = builder. crate_paths . get ( path) {
701+ stdarch_crates. push ( krate. clone ( ) ) ;
702+ }
703+ } else if let Some ( krate) = builder. crate_paths . get ( path) {
704+ std_crates. push ( krate. clone ( ) ) ;
705+ }
706+ }
707+
708+ std_crates. sort ( ) ;
709+ std_crates. dedup ( ) ;
710+ stdarch_crates. sort ( ) ;
711+ stdarch_crates. dedup ( ) ;
712+
713+ if stdarch_requested && stdarch_crates. is_empty ( ) {
714+ stdarch_crates. push ( "core_arch" . to_owned ( ) ) ;
715+ if !builder. no_std ( run. target ) . unwrap_or ( false ) {
716+ stdarch_crates. push ( "stdarch_examples" . to_owned ( ) ) ;
717+ }
718+ }
719+
720+ if !std_crates. is_empty ( ) {
721+ builder. ensure ( Std {
722+ build_compiler,
723+ target : run. target ,
724+ format,
725+ workspace : StdWorkspace :: Std ,
726+ crates : std_crates,
727+ } ) ;
728+ }
729+ if !stdarch_crates. is_empty ( ) {
730+ builder. ensure ( Std {
731+ build_compiler,
732+ target : run. target ,
733+ format,
734+ workspace : StdWorkspace :: Stdarch ,
735+ crates : stdarch_crates,
736+ } ) ;
737+ }
671738 }
672739
673740 /// Compile all standard library documentation.
@@ -676,14 +743,29 @@ impl Step for Std {
676743 /// dependencies. This is largely just a wrapper around `cargo doc`.
677744 fn run ( self , builder : & Builder < ' _ > ) -> Self :: Output {
678745 let target = self . target ;
679- let crates = if self . crates . is_empty ( ) {
680- builder
681- . in_tree_crates ( "sysroot" , Some ( target) )
682- . iter ( )
683- . map ( |c| c. name . to_string ( ) )
684- . collect ( )
685- } else {
686- self . crates
746+ let crates = match self . workspace {
747+ StdWorkspace :: Std => {
748+ if self . crates . is_empty ( ) {
749+ builder
750+ . in_tree_crates ( "sysroot" , Some ( target) )
751+ . iter ( )
752+ . map ( |c| c. name . to_string ( ) )
753+ . collect ( )
754+ } else {
755+ self . crates
756+ }
757+ }
758+ StdWorkspace :: Stdarch => {
759+ if self . crates . is_empty ( ) {
760+ let mut crates = vec ! [ "core_arch" . to_owned( ) ] ;
761+ if !builder. no_std ( target) . unwrap_or ( false ) {
762+ crates. push ( "stdarch_examples" . to_owned ( ) ) ;
763+ }
764+ crates
765+ } else {
766+ self . crates
767+ }
768+ }
687769 } ;
688770
689771 let out = match self . format {
@@ -693,45 +775,72 @@ impl Step for Std {
693775
694776 t ! ( fs:: create_dir_all( & out) ) ;
695777
696- if self . format == DocumentationFormat :: Html {
778+ if self . format == DocumentationFormat :: Html && self . workspace == StdWorkspace :: Std {
697779 builder. ensure ( SharedAssets { target : self . target } ) ;
698780 }
699781
700- let index_page = builder
701- . src
702- . join ( "src/doc/index.md" )
703- . into_os_string ( )
704- . into_string ( )
705- . expect ( "non-utf8 paths are unsupported" ) ;
706- let mut extra_args = match self . format {
707- DocumentationFormat :: Html => {
708- vec ! [ "--markdown-css" , "rust.css" , "--markdown-no-toc" , "--index-page" , & index_page]
709- }
710- DocumentationFormat :: Json => vec ! [ "--output-format" , "json" ] ,
711- } ;
782+ match self . workspace {
783+ StdWorkspace :: Std => {
784+ let index_page = builder
785+ . src
786+ . join ( "src/doc/index.md" )
787+ . into_os_string ( )
788+ . into_string ( )
789+ . expect ( "non-utf8 paths are unsupported" ) ;
790+ let mut extra_args = match self . format {
791+ DocumentationFormat :: Html => vec ! [
792+ "--markdown-css" ,
793+ "rust.css" ,
794+ "--markdown-no-toc" ,
795+ "--index-page" ,
796+ & index_page,
797+ ] ,
798+ DocumentationFormat :: Json => vec ! [ "--output-format" , "json" ] ,
799+ } ;
712800
713- if !builder. config . docs_minification {
714- extra_args. push ( "--disable-minification" ) ;
715- }
716- // For `--index-page` and `--output-format=json`.
717- extra_args. push ( "-Zunstable-options" ) ;
801+ if !builder. config . docs_minification {
802+ extra_args. push ( "--disable-minification" ) ;
803+ }
804+ // For `--index-page` and `--output-format=json`.
805+ extra_args. push ( "-Zunstable-options" ) ;
718806
719- doc_std ( builder, self . format , self . build_compiler , target, & out, & extra_args, & crates) ;
807+ doc_std (
808+ builder,
809+ self . format ,
810+ self . build_compiler ,
811+ target,
812+ & out,
813+ & extra_args,
814+ & crates,
815+ ) ;
816+ }
817+ StdWorkspace :: Stdarch => {
818+ doc_stdarch ( builder, self . format , self . build_compiler , target, & out, & crates) ;
819+ }
820+ }
720821
721822 // Open if the format is HTML
722823 if let DocumentationFormat :: Html = self . format {
723- if builder. paths . iter ( ) . any ( |path| path. ends_with ( "library" ) ) {
724- // For `x.py doc library --open`, open `std` by default.
725- let index = out. join ( "std" ) . join ( "index.html" ) ;
726- builder. maybe_open_in_browser :: < Self > ( index) ;
727- } else {
728- for requested_crate in crates {
729- if STD_PUBLIC_CRATES . iter ( ) . any ( |& k| k == requested_crate) {
730- let index = out. join ( requested_crate) . join ( "index.html" ) ;
824+ match self . workspace {
825+ StdWorkspace :: Std => {
826+ if builder. paths . iter ( ) . any ( |path| path. ends_with ( "library" ) ) {
827+ // For `x.py doc library --open`, open `std` by default.
828+ let index = out. join ( "std" ) . join ( "index.html" ) ;
731829 builder. maybe_open_in_browser :: < Self > ( index) ;
732- break ;
830+ } else {
831+ for requested_crate in crates {
832+ if STD_PUBLIC_CRATES . iter ( ) . any ( |& k| k == requested_crate) {
833+ let index = out. join ( requested_crate) . join ( "index.html" ) ;
834+ builder. maybe_open_in_browser :: < Self > ( index) ;
835+ break ;
836+ }
837+ }
733838 }
734839 }
840+ StdWorkspace :: Stdarch => {
841+ let index = out. join ( & crates[ 0 ] ) . join ( "index.html" ) ;
842+ builder. maybe_open_in_browser :: < Self > ( index) ;
843+ }
735844 }
736845 }
737846
@@ -740,13 +849,33 @@ impl Step for Std {
740849
741850 fn metadata ( & self ) -> Option < StepMetadata > {
742851 Some (
743- StepMetadata :: doc ( "std" , self . target )
744- . built_by ( self . build_compiler )
745- . with_metadata ( format ! ( "crates=[{}]" , self . crates. join( "," ) ) ) ,
852+ StepMetadata :: doc (
853+ match self . workspace {
854+ StdWorkspace :: Std => "std" ,
855+ StdWorkspace :: Stdarch => "stdarch" ,
856+ } ,
857+ self . target ,
858+ )
859+ . built_by ( self . build_compiler )
860+ . with_metadata ( format ! ( "crates=[{}]" , self . crates. join( "," ) ) ) ,
746861 )
747862 }
748863}
749864
865+ #[ cfg( test) ]
866+ impl Std {
867+ pub ( crate ) fn workspace_name ( & self ) -> & ' static str {
868+ match self . workspace {
869+ StdWorkspace :: Std => "std" ,
870+ StdWorkspace :: Stdarch => "stdarch" ,
871+ }
872+ }
873+
874+ pub ( crate ) fn crate_names ( & self ) -> & [ String ] {
875+ & self . crates
876+ }
877+ }
878+
750879/// Name of the crates that are visible to consumers of the standard library.
751880/// Documentation for internal crates is handled by the rustc step, so internal crates will show
752881/// up there.
@@ -829,6 +958,56 @@ fn doc_std(
829958 builder. cp_link_r ( & out_dir, out) ;
830959}
831960
961+ fn doc_stdarch (
962+ builder : & Builder < ' _ > ,
963+ format : DocumentationFormat ,
964+ build_compiler : Compiler ,
965+ target : TargetSelection ,
966+ out : & Path ,
967+ requested_crates : & [ String ] ,
968+ ) {
969+ let target_doc_dir_name =
970+ if format == DocumentationFormat :: Json { "stdarch-json-doc" } else { "stdarch-doc" } ;
971+ let target_dir =
972+ builder. stage_out ( build_compiler, Mode :: Std ) . join ( target) . join ( target_doc_dir_name) ;
973+ let out_dir = target_dir. join ( target) . join ( "doc" ) ;
974+
975+ let mut cargo = builder:: Cargo :: new (
976+ builder,
977+ build_compiler,
978+ Mode :: Std ,
979+ SourceType :: InTree ,
980+ target,
981+ Kind :: Doc ,
982+ ) ;
983+ cargo. arg ( "--manifest-path" ) . arg ( builder. src . join ( "library/stdarch/Cargo.toml" ) ) ;
984+ for krate in requested_crates {
985+ cargo. arg ( "-p" ) . arg ( krate) ;
986+ }
987+ cargo
988+ . arg ( "--no-deps" )
989+ . arg ( "--target-dir" )
990+ . arg ( & * target_dir. to_string_lossy ( ) )
991+ . arg ( "-Zskip-rustdoc-fingerprint" )
992+ . rustdocflag ( "--resource-suffix" )
993+ . rustdocflag ( & builder. version ) ;
994+
995+ if format == DocumentationFormat :: Json {
996+ cargo. arg ( "--output-format" ) . arg ( "json" ) . rustdocflag ( "-Zunstable-options" ) ;
997+ }
998+
999+ if builder. config . library_docs_private_items {
1000+ cargo. rustdocflag ( "--document-private-items" ) . rustdocflag ( "--document-hidden-items" ) ;
1001+ }
1002+
1003+ let description =
1004+ format ! ( "stdarch{} in {} format" , crate_description( requested_crates) , format. as_str( ) ) ;
1005+ let _guard = builder. msg ( Kind :: Doc , description, Mode :: Std , build_compiler, target) ;
1006+
1007+ cargo. into_cmd ( ) . run ( builder) ;
1008+ builder. cp_link_r ( & out_dir, out) ;
1009+ }
1010+
8321011/// Prepare a compiler that will be able to document something for `target` at `stage`.
8331012pub fn prepare_doc_compiler (
8341013 builder : & Builder < ' _ > ,
0 commit comments