11//! Implementation of running clippy on the compiler, standard library and various tools.
2+ //!
3+ //! This serves a double purpose:
4+ //! - The first is to run Clippy itself on in-tree code, in order to test and dogfood it.
5+ //! - The second is to actually lint the in-tree codebase on CI, with a hard-coded set of rules,
6+ //! which is performed by the `x clippy ci` command.
7+ //!
8+ //! In order to prepare a build compiler for running clippy, use the
9+ //! `check::prepare_compiler_for_check` function. That prepares a compiler and a standard library
10+ //! for running Clippy. The second part (actually building Clippy) is performed inside
11+ //! [Builder::cargo_clippy_cmd]. It would be nice if this was more explicit, and we actually had
12+ //! to pass a prebuilt Clippy from the outside when running `cargo clippy`, but that would be
13+ //! (as usual) a massive undertaking/refactoring.
214
315use super :: check;
416use super :: compile:: { run_cargo, rustc_cargo, std_cargo} ;
517use super :: tool:: { RustcPrivateCompilers , SourceType , prepare_tool_cargo} ;
618use crate :: builder:: { Builder , ShouldRun } ;
19+ use crate :: core:: build_steps:: check:: prepare_compiler_for_check;
720use crate :: core:: build_steps:: compile:: std_crates_for_run_make;
821use crate :: core:: builder;
922use crate :: core:: builder:: { Alias , Kind , RunConfig , Step , StepMetadata , crate_description} ;
1023use crate :: utils:: build_stamp:: { self , BuildStamp } ;
11- use crate :: { Mode , Subcommand , TargetSelection } ;
24+ use crate :: { Compiler , Mode , Subcommand , TargetSelection } ;
1225
1326/// Disable the most spammy clippy lints
1427const IGNORED_RULES_FOR_STD_AND_RUSTC : & [ & str ] = & [
@@ -184,14 +197,35 @@ impl Step for Std {
184197 }
185198}
186199
200+ /// Lints the compiler.
201+ ///
202+ /// This will build Clippy with the `build_compiler` and use it to lint
203+ /// in-tree rustc.
187204#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
188205pub struct Rustc {
189- pub target : TargetSelection ,
206+ build_compiler : Compiler ,
207+ target : TargetSelection ,
190208 config : LintConfig ,
191209 /// Whether to lint only a subset of crates.
192210 crates : Vec < String > ,
193211}
194212
213+ impl Rustc {
214+ fn new (
215+ builder : & Builder < ' _ > ,
216+ target : TargetSelection ,
217+ config : LintConfig ,
218+ crates : Vec < String > ,
219+ ) -> Self {
220+ Self {
221+ build_compiler : prepare_compiler_for_check ( builder, target, Mode :: Rustc ) ,
222+ target,
223+ config,
224+ crates,
225+ }
226+ }
227+ }
228+
195229impl Step for Rustc {
196230 type Output = ( ) ;
197231 const ONLY_HOSTS : bool = true ;
@@ -202,33 +236,16 @@ impl Step for Rustc {
202236 }
203237
204238 fn make_run ( run : RunConfig < ' _ > ) {
239+ let builder = run. builder ;
205240 let crates = run. make_run_crates ( Alias :: Compiler ) ;
206241 let config = LintConfig :: new ( run. builder ) ;
207- run. builder . ensure ( Rustc { target : run. target , config, crates } ) ;
242+ run. builder . ensure ( Rustc :: new ( builder , run. target , config, crates) ) ;
208243 }
209244
210- /// Lints the compiler.
211- ///
212- /// This will lint the compiler for a particular stage of the build using
213- /// the `compiler` targeting the `target` architecture.
214245 fn run ( self , builder : & Builder < ' _ > ) {
215- let build_compiler = builder . compiler ( builder . top_stage , builder . config . host_target ) ;
246+ let build_compiler = self . build_compiler ;
216247 let target = self . target ;
217248
218- if !builder. download_rustc ( ) {
219- if build_compiler. stage != 0 {
220- // If we're not in stage 0, then we won't have a std from the beta
221- // compiler around. That means we need to make sure there's one in
222- // the sysroot for the compiler to find. Otherwise, we're going to
223- // fail when building crates that need to generate code (e.g., build
224- // scripts and their dependencies).
225- builder. std ( build_compiler, build_compiler. host ) ;
226- builder. std ( build_compiler, target) ;
227- } else {
228- builder. ensure ( check:: Std :: new ( build_compiler, target) ) ;
229- }
230- }
231-
232249 let mut cargo = builder:: Cargo :: new (
233250 builder,
234251 build_compiler,
@@ -267,7 +284,7 @@ impl Step for Rustc {
267284 }
268285
269286 fn metadata ( & self ) -> Option < StepMetadata > {
270- Some ( StepMetadata :: clippy ( "rustc" , self . target ) )
287+ Some ( StepMetadata :: clippy ( "rustc" , self . target ) . built_by ( self . build_compiler ) )
271288 }
272289}
273290
@@ -518,11 +535,12 @@ impl Step for CI {
518535 ] ,
519536 forbid : vec ! [ ] ,
520537 } ;
521- builder. ensure ( Rustc {
522- target : self . target ,
523- config : self . config . merge ( & compiler_clippy_cfg) ,
524- crates : vec ! [ ] ,
525- } ) ;
538+ builder. ensure ( Rustc :: new (
539+ builder,
540+ self . target ,
541+ self . config . merge ( & compiler_clippy_cfg) ,
542+ vec ! [ ] ,
543+ ) ) ;
526544
527545 let rustc_codegen_gcc = LintConfig {
528546 allow : vec ! [ ] ,
0 commit comments