1212//! to pass a prebuilt Clippy from the outside when running `cargo clippy`, but that would be
1313//! (as usual) a massive undertaking/refactoring.
1414
15+ use build_helper:: exit;
16+
1517use super :: compile:: { run_cargo, rustc_cargo, std_cargo} ;
1618use super :: tool:: { SourceType , prepare_tool_cargo} ;
1719use crate :: builder:: { Builder , ShouldRun } ;
@@ -154,6 +156,15 @@ impl Std {
154156 crates,
155157 }
156158 }
159+
160+ fn from_build_compiler (
161+ build_compiler : Compiler ,
162+ target : TargetSelection ,
163+ config : LintConfig ,
164+ crates : Vec < String > ,
165+ ) -> Self {
166+ Self { build_compiler, target, config, crates }
167+ }
157168}
158169
159170impl Step for Std {
@@ -479,6 +490,7 @@ lint_any!(
479490 TestFloatParse , "src/tools/test-float-parse" , "test-float-parse" , Mode :: ToolStd ;
480491) ;
481492
493+ /// Runs Clippy on in-tree sources of selected projects using in-tree CLippy.
482494#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
483495pub struct CI {
484496 target : TargetSelection ,
@@ -499,7 +511,20 @@ impl Step for CI {
499511 }
500512
501513 fn run ( self , builder : & Builder < ' _ > ) -> Self :: Output {
514+ if builder. top_stage != 2 {
515+ eprintln ! ( "ERROR: `x clippy ci` should always be executed with --stage 2" ) ;
516+ exit ! ( 1 ) ;
517+ }
518+
519+ // We want to check in-tree source using in-tree clippy. However, if we naively did
520+ // a stage 2 `x clippy ci`, it would *build* a stage 2 rustc, in order to lint stage 2
521+ // std, which is wasteful.
522+ // So we want to lint stage 2 [bootstrap/rustc/...], but only stage 1 std rustc_codegen_gcc.
523+ // We thus construct the compilers in this step manually, to optimize the number of
524+ // steps that get built.
525+
502526 builder. ensure ( Bootstrap {
527+ // This will be the stage 1 compiler
503528 build_compiler : prepare_compiler_for_check ( builder, self . target , Mode :: ToolTarget ) ,
504529 target : self . target ,
505530 config : self . config . merge ( & LintConfig {
@@ -509,6 +534,7 @@ impl Step for CI {
509534 forbid : vec ! [ ] ,
510535 } ) ,
511536 } ) ;
537+
512538 let library_clippy_cfg = LintConfig {
513539 allow : vec ! [ "clippy::all" . into( ) ] ,
514540 warn : vec ! [ ] ,
@@ -526,8 +552,9 @@ impl Step for CI {
526552 ] ,
527553 forbid : vec ! [ ] ,
528554 } ;
529- builder. ensure ( Std :: new (
530- builder,
555+ builder. ensure ( Std :: from_build_compiler (
556+ // This will be the stage 1 compiler, to avoid building rustc stage 2 just to lint std
557+ builder. compiler ( 1 , self . target ) ,
531558 self . target ,
532559 self . config . merge ( & library_clippy_cfg) ,
533560 vec ! [ ] ,
@@ -552,6 +579,7 @@ impl Step for CI {
552579 ] ,
553580 forbid : vec ! [ ] ,
554581 } ;
582+ // This will lint stage 2 rustc using stage 1 Clippy
555583 builder. ensure ( Rustc :: new (
556584 builder,
557585 self . target ,
@@ -565,6 +593,7 @@ impl Step for CI {
565593 deny : vec ! [ "warnings" . into( ) ] ,
566594 forbid : vec ! [ ] ,
567595 } ;
596+ // This will check stage 2 rustc
568597 builder. ensure ( CodegenGcc :: new (
569598 builder,
570599 self . target ,
0 commit comments