@@ -9,7 +9,7 @@ use crate::core::builder::{
99} ;
1010use crate :: core:: config:: TargetSelection ;
1111use crate :: utils:: build_stamp:: { self , BuildStamp } ;
12- use crate :: { Mode , Subcommand } ;
12+ use crate :: { Compiler , Mode , Subcommand } ;
1313
1414#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
1515pub struct Std {
@@ -27,17 +27,25 @@ pub struct Std {
2727 /// passing `Builder::kind` to cargo invocations would run clippy on the entire compiler and library,
2828 /// which is not useful if we only want to lint a few crates with specific rules.
2929 override_build_kind : Option < Kind > ,
30+
31+ override_compiler : Option < Compiler > ,
3032}
3133
3234impl Std {
3335 pub fn new ( target : TargetSelection ) -> Self {
34- Self { target, crates : vec ! [ ] , override_build_kind : None }
36+ Self { target, crates : vec ! [ ] , override_build_kind : None , override_compiler : None }
3537 }
3638
3739 pub fn build_kind ( mut self , kind : Option < Kind > ) -> Self {
3840 self . override_build_kind = kind;
3941 self
4042 }
43+
44+ /// Override the compiler used. Needed when checking tools that use [`Mode::ToolStd`].
45+ pub fn with_compiler ( mut self , compiler : Compiler ) -> Self {
46+ self . override_compiler = Some ( compiler) ;
47+ self
48+ }
4149}
4250
4351impl Step for Std {
@@ -53,14 +61,21 @@ impl Step for Std {
5361
5462 fn make_run ( run : RunConfig < ' _ > ) {
5563 let crates = std_crates_for_run_make ( & run) ;
56- run. builder . ensure ( Std { target : run. target , crates, override_build_kind : None } ) ;
64+ run. builder . ensure ( Std {
65+ target : run. target ,
66+ crates,
67+ override_build_kind : None ,
68+ override_compiler : None ,
69+ } ) ;
5770 }
5871
5972 fn run ( self , builder : & Builder < ' _ > ) {
6073 builder. require_submodule ( "library/stdarch" , None ) ;
6174
6275 let target = self . target ;
63- let compiler = builder. compiler ( builder. top_stage , builder. config . build ) ;
76+ let compiler = self
77+ . override_compiler
78+ . unwrap_or_else ( || builder. compiler ( builder. top_stage , builder. config . build ) ) ;
6479
6580 let mut cargo = builder:: Cargo :: new (
6681 builder,
@@ -375,6 +390,8 @@ macro_rules! tool_check_step {
375390 // The part of this path after the final '/' is also used as a display name.
376391 path: $path: literal
377392 $( , alt_path: $alt_path: literal ) *
393+ , mode: $mode: path
394+ $( , allow_features: $allow_features: expr ) ?
378395 $( , default : $default: literal ) ?
379396 $( , ) ?
380397 }
@@ -400,7 +417,14 @@ macro_rules! tool_check_step {
400417
401418 fn run( self , builder: & Builder <' _>) {
402419 let Self { target } = self ;
403- run_tool_check_step( builder, target, stringify!( $name) , $path) ;
420+
421+ let allow_features = {
422+ let mut _value: & [ & str ] = & [ ] ;
423+ $( _value = $allow_features; ) ?
424+ _value
425+ } ;
426+
427+ run_tool_check_step( builder, target, $path, $mode, allow_features) ;
404428 }
405429 }
406430 }
@@ -410,18 +434,34 @@ macro_rules! tool_check_step {
410434fn run_tool_check_step (
411435 builder : & Builder < ' _ > ,
412436 target : TargetSelection ,
413- step_type_name : & str ,
414437 path : & str ,
438+ mode : Mode ,
439+ allow_features : & [ & str ] ,
415440) {
416441 let display_name = path. rsplit ( '/' ) . next ( ) . unwrap ( ) ;
417- let compiler = builder. compiler ( builder. top_stage , builder. config . build ) ;
418442
419- builder. ensure ( Rustc :: new ( target, builder) ) ;
443+ let host = builder. config . build ;
444+ let compiler;
445+
446+ match mode {
447+ Mode :: ToolBootstrap => {
448+ compiler = builder. compiler ( 0 , host) ;
449+ }
450+ Mode :: ToolStd => {
451+ compiler = builder. compiler ( 0 , host) ;
452+ builder. ensure ( Std :: new ( target) . with_compiler ( compiler) ) ;
453+ }
454+ Mode :: ToolRustc => {
455+ compiler = builder. compiler ( builder. top_stage , host) ;
456+ builder. ensure ( Rustc :: new ( target, builder) ) ;
457+ }
458+ _ => panic ! ( "unexpected mode for tool check step: {mode:?}" ) ,
459+ }
420460
421461 let mut cargo = prepare_tool_cargo (
422462 builder,
423463 compiler,
424- Mode :: ToolRustc ,
464+ mode ,
425465 target,
426466 builder. kind ,
427467 path,
@@ -432,39 +472,62 @@ fn run_tool_check_step(
432472 SourceType :: InTree ,
433473 & [ ] ,
434474 ) ;
475+ cargo. allow_features ( & allow_features. join ( "," ) ) ;
435476
436477 // For ./x.py clippy, don't run with --all-targets because
437478 // linting tests and benchmarks can produce very noisy results
438479 if builder. kind != Kind :: Clippy {
439480 cargo. arg ( "--all-targets" ) ;
440481 }
441482
442- let stamp = BuildStamp :: new ( & builder. cargo_out ( compiler, Mode :: ToolRustc , target) )
443- . with_prefix ( & format ! ( "{}-check" , step_type_name . to_lowercase ( ) ) ) ;
483+ let stamp = BuildStamp :: new ( & builder. cargo_out ( compiler, mode , target) )
484+ . with_prefix ( & format ! ( "{display_name }-check" ) ) ;
444485
445- let _guard = builder. msg_check ( format ! ( "{display_name} artifacts" ) , target) ;
486+ let _guard =
487+ builder. msg_tool ( builder. kind , mode, display_name, compiler. stage , & compiler. host , & target) ;
446488 run_cargo ( builder, cargo, builder. config . free_args . clone ( ) , & stamp, vec ! [ ] , true , false ) ;
447489}
448490
449- tool_check_step ! ( Rustdoc { path: "src/tools/rustdoc" , alt_path: "src/librustdoc" } ) ;
491+ // FIXME: Some of these `Mode::ToolRustc` values might be wrong.
492+ // (Historically, all tools were hardcoded to use `Mode::ToolRustc`.)
493+
494+ tool_check_step ! ( Rustdoc {
495+ path: "src/tools/rustdoc" ,
496+ alt_path: "src/librustdoc" ,
497+ mode: Mode :: ToolRustc ,
498+ } ) ;
450499// Clippy, miri and Rustfmt are hybrids. They are external tools, but use a git subtree instead
451500// of a submodule. Since the SourceType only drives the deny-warnings
452501// behavior, treat it as in-tree so that any new warnings in clippy will be
453502// rejected.
454- tool_check_step ! ( Clippy { path: "src/tools/clippy" } ) ;
455- tool_check_step ! ( Miri { path: "src/tools/miri" } ) ;
456- tool_check_step ! ( CargoMiri { path: "src/tools/miri/cargo-miri" } ) ;
457- tool_check_step ! ( Rustfmt { path: "src/tools/rustfmt" } ) ;
458- tool_check_step ! ( MiroptTestTools { path: "src/tools/miropt-test-tools" } ) ;
459- tool_check_step ! ( TestFloatParse { path: "src/etc/test-float-parse" } ) ;
460- tool_check_step ! ( FeaturesStatusDump { path: "src/tools/features-status-dump" } ) ;
461-
462- tool_check_step ! ( Bootstrap { path: "src/bootstrap" , default : false } ) ;
503+ tool_check_step ! ( Clippy { path: "src/tools/clippy" , mode: Mode :: ToolRustc } ) ;
504+ tool_check_step ! ( Miri { path: "src/tools/miri" , mode: Mode :: ToolRustc } ) ;
505+ tool_check_step ! ( CargoMiri { path: "src/tools/miri/cargo-miri" , mode: Mode :: ToolRustc } ) ;
506+ tool_check_step ! ( Rustfmt { path: "src/tools/rustfmt" , mode: Mode :: ToolRustc } ) ;
507+ tool_check_step ! ( MiroptTestTools { path: "src/tools/miropt-test-tools" , mode: Mode :: ToolRustc } ) ;
508+ tool_check_step ! ( TestFloatParse { path: "src/etc/test-float-parse" , mode: Mode :: ToolRustc } ) ;
509+ tool_check_step ! ( FeaturesStatusDump {
510+ path: "src/tools/features-status-dump" ,
511+ mode: Mode :: ToolRustc ,
512+ } ) ;
513+
514+ tool_check_step ! ( Bootstrap { path: "src/bootstrap" , mode: Mode :: ToolBootstrap , default : false } ) ;
463515
464516// `run-make-support` will be built as part of suitable run-make compiletest test steps, but support
465517// check to make it easier to work on.
466- tool_check_step ! ( RunMakeSupport { path: "src/tools/run-make-support" , default : false } ) ;
518+ tool_check_step ! ( RunMakeSupport {
519+ path: "src/tools/run-make-support" ,
520+ mode: Mode :: ToolBootstrap ,
521+ default : false ,
522+ } ) ;
467523
468524// Compiletest is implicitly "checked" when it gets built in order to run tests,
469525// so this is mainly for people working on compiletest to run locally.
470- tool_check_step ! ( Compiletest { path: "src/tools/compiletest" , default : false } ) ;
526+ //
527+ // Compiletest uses libtest internally, so it needs `Mode::ToolStd` and `#![feature(test)]`.
528+ tool_check_step ! ( Compiletest {
529+ path: "src/tools/compiletest" ,
530+ mode: Mode :: ToolStd ,
531+ allow_features: & [ "test" ] ,
532+ default : false ,
533+ } ) ;
0 commit comments