@@ -965,9 +965,11 @@ macro_rules! tool_doc {
965965    ( 
966966        $tool:  ident, 
967967        $path:  literal, 
968-         $( rustc_private_tool = $rustc_private_tool: literal,  ) ?
969-         $( is_library = $is_library: expr, ) ?
970-         $( crates = $crates: expr) ?
968+         mode = $mode: expr
969+         $( ,  is_library = $is_library: expr ) ?
970+         $( ,  crates = $crates: expr ) ?
971+         // Subset of nightly features that are allowed to be used when documenting 
972+         $( ,  allow_features:  $allow_features: expr ) ?
971973       )  => { 
972974        #[ derive( Debug ,  Clone ,  Hash ,  PartialEq ,  Eq ) ] 
973975        pub  struct  $tool { 
@@ -988,20 +990,29 @@ macro_rules! tool_doc {
988990
989991            fn  make_run( run:  RunConfig <' _>)  { 
990992                let  target = run. target; 
991-                 let  ( build_compiler,  mode)  = if  true  $( && $rustc_private_tool) ? { 
992-                     // Rustdoc needs the rustc sysroot available to build. 
993-                     let  compilers = RustcPrivateCompilers :: new( run. builder,  run. builder. top_stage,  target) ; 
994- 
995-                     // Build rustc docs so that we generate relative links. 
996-                     run. builder. ensure( Rustc :: from_build_compiler( run. builder,  compilers. build_compiler( ) ,  target) ) ; 
997- 
998-                     ( compilers. build_compiler( ) ,  Mode :: ToolRustcPrivate ) 
999-                 }  else { 
1000-                     // bootstrap/host tools have to be documented with the stage 0 compiler 
1001-                     ( prepare_doc_compiler( run. builder,  run. builder. host_target,  1 ) ,  Mode :: ToolBootstrap ) 
993+                 let  build_compiler = match  $mode { 
994+                     Mode :: ToolRustcPrivate  => { 
995+                         // Rustdoc needs the rustc sysroot available to build. 
996+                         let  compilers = RustcPrivateCompilers :: new( run. builder,  run. builder. top_stage,  target) ; 
997+ 
998+                         // Build rustc docs so that we generate relative links. 
999+                         run. builder. ensure( Rustc :: from_build_compiler( run. builder,  compilers. build_compiler( ) ,  target) ) ; 
1000+                         compilers. build_compiler( ) 
1001+                     } 
1002+                     Mode :: ToolBootstrap  => { 
1003+                         // bootstrap/host tools should be documented with the stage 0 compiler 
1004+                         prepare_doc_compiler( run. builder,  run. builder. host_target,  1 ) 
1005+                     } 
1006+                     Mode :: ToolTarget  => { 
1007+                         // target tools should be documented with the in-tree compiler 
1008+                         prepare_doc_compiler( run. builder,  run. builder. host_target,  run. builder. top_stage) 
1009+                     } 
1010+                     _ => { 
1011+                         panic!( "Unexpected tool mode for documenting: {:?}" ,  $mode) ; 
1012+                     } 
10021013                } ; 
10031014
1004-                 run. builder. ensure( $tool {  build_compiler,  mode,  target } ) ; 
1015+                 run. builder. ensure( $tool {  build_compiler,  mode:  $mode ,  target } ) ; 
10051016            } 
10061017
10071018            /// Generates documentation for a tool. 
@@ -1032,6 +1043,15 @@ macro_rules! tool_doc {
10321043                    source_type, 
10331044                    & [ ] , 
10341045                ) ; 
1046+                 let  allow_features = { 
1047+                     let  mut  _value = "" ; 
1048+                     $(  _value = $allow_features;  ) ?
1049+                     _value
1050+                 } ; 
1051+ 
1052+                 if  !allow_features. is_empty( )  { 
1053+                     cargo. allow_features( allow_features) ; 
1054+                 } 
10351055
10361056                cargo. arg( "-Zskip-rustdoc-fingerprint" ) ; 
10371057                // Only include compiler crates, no dependencies of those, such as `libc`. 
@@ -1087,18 +1107,33 @@ macro_rules! tool_doc {
10871107tool_doc ! ( 
10881108    BuildHelper , 
10891109    "src/build_helper" , 
1090-     rustc_private_tool  = false , 
1110+     mode  = Mode :: ToolBootstrap , 
10911111    is_library = true , 
10921112    crates = [ "build_helper" ] 
10931113) ; 
1094- tool_doc ! ( Rustdoc ,  "src/tools/rustdoc" ,  crates = [ "rustdoc" ,  "rustdoc-json-types" ] ) ; 
1095- tool_doc ! ( Rustfmt ,  "src/tools/rustfmt" ,  crates = [ "rustfmt-nightly" ,  "rustfmt-config_proc_macro" ] ) ; 
1096- tool_doc ! ( Clippy ,  "src/tools/clippy" ,  crates = [ "clippy_config" ,  "clippy_utils" ] ) ; 
1097- tool_doc ! ( Miri ,  "src/tools/miri" ,  crates = [ "miri" ] ) ; 
1114+ tool_doc ! ( 
1115+     Rustdoc , 
1116+     "src/tools/rustdoc" , 
1117+     mode = Mode :: ToolRustcPrivate , 
1118+     crates = [ "rustdoc" ,  "rustdoc-json-types" ] 
1119+ ) ; 
1120+ tool_doc ! ( 
1121+     Rustfmt , 
1122+     "src/tools/rustfmt" , 
1123+     mode = Mode :: ToolRustcPrivate , 
1124+     crates = [ "rustfmt-nightly" ,  "rustfmt-config_proc_macro" ] 
1125+ ) ; 
1126+ tool_doc ! ( 
1127+     Clippy , 
1128+     "src/tools/clippy" , 
1129+     mode = Mode :: ToolRustcPrivate , 
1130+     crates = [ "clippy_config" ,  "clippy_utils" ] 
1131+ ) ; 
1132+ tool_doc ! ( Miri ,  "src/tools/miri" ,  mode = Mode :: ToolRustcPrivate ,  crates = [ "miri" ] ) ; 
10981133tool_doc ! ( 
10991134    Cargo , 
11001135    "src/tools/cargo" , 
1101-     rustc_private_tool  = false , 
1136+     mode  = Mode :: ToolTarget , 
11021137    crates = [ 
11031138        "cargo" , 
11041139        "cargo-credential" , 
@@ -1110,27 +1145,30 @@ tool_doc!(
11101145        "crates-io" , 
11111146        "mdman" , 
11121147        "rustfix" , 
1113-     ] 
1148+     ] , 
1149+     // Required because of the im-rc dependency of Cargo, which automatically opts into the 
1150+     // "specialization" feature in its build script when it detects a nightly toolchain. 
1151+     allow_features:  "specialization" 
11141152) ; 
1115- tool_doc ! ( Tidy ,  "src/tools/tidy" ,  rustc_private_tool  = false ,  crates = [ "tidy" ] ) ; 
1153+ tool_doc ! ( Tidy ,  "src/tools/tidy" ,  mode  = Mode :: ToolBootstrap ,  crates = [ "tidy" ] ) ; 
11161154tool_doc ! ( 
11171155    Bootstrap , 
11181156    "src/bootstrap" , 
1119-     rustc_private_tool  = false , 
1157+     mode  = Mode :: ToolBootstrap , 
11201158    is_library = true , 
11211159    crates = [ "bootstrap" ] 
11221160) ; 
11231161tool_doc ! ( 
11241162    RunMakeSupport , 
11251163    "src/tools/run-make-support" , 
1126-     rustc_private_tool  = false , 
1164+     mode  = Mode :: ToolBootstrap , 
11271165    is_library = true , 
11281166    crates = [ "run_make_support" ] 
11291167) ; 
11301168tool_doc ! ( 
11311169    Compiletest , 
11321170    "src/tools/compiletest" , 
1133-     rustc_private_tool  = false , 
1171+     mode  = Mode :: ToolBootstrap , 
11341172    is_library = true , 
11351173    crates = [ "compiletest" ] 
11361174) ; 
0 commit comments