1
1
//! 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.
2
14
3
15
use super :: check;
4
16
use super :: compile:: { run_cargo, rustc_cargo, std_cargo} ;
5
17
use super :: tool:: { RustcPrivateCompilers , SourceType , prepare_tool_cargo} ;
6
18
use crate :: builder:: { Builder , ShouldRun } ;
19
+ use crate :: core:: build_steps:: check:: prepare_compiler_for_check;
7
20
use crate :: core:: build_steps:: compile:: std_crates_for_run_make;
8
21
use crate :: core:: builder;
9
22
use crate :: core:: builder:: { Alias , Kind , RunConfig , Step , StepMetadata , crate_description} ;
10
23
use crate :: utils:: build_stamp:: { self , BuildStamp } ;
11
- use crate :: { Mode , Subcommand , TargetSelection } ;
24
+ use crate :: { Compiler , Mode , Subcommand , TargetSelection } ;
12
25
13
26
/// Disable the most spammy clippy lints
14
27
const IGNORED_RULES_FOR_STD_AND_RUSTC : & [ & str ] = & [
@@ -179,14 +192,35 @@ impl Step for Std {
179
192
}
180
193
}
181
194
195
+ /// Lints the compiler.
196
+ ///
197
+ /// This will build Clippy with the `build_compiler` and use it to lint
198
+ /// in-tree rustc.
182
199
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
183
200
pub struct Rustc {
184
- pub target : TargetSelection ,
201
+ build_compiler : Compiler ,
202
+ target : TargetSelection ,
185
203
config : LintConfig ,
186
204
/// Whether to lint only a subset of crates.
187
205
crates : Vec < String > ,
188
206
}
189
207
208
+ impl Rustc {
209
+ fn new (
210
+ builder : & Builder < ' _ > ,
211
+ target : TargetSelection ,
212
+ config : LintConfig ,
213
+ crates : Vec < String > ,
214
+ ) -> Self {
215
+ Self {
216
+ build_compiler : prepare_compiler_for_check ( builder, target, Mode :: Rustc ) ,
217
+ target,
218
+ config,
219
+ crates,
220
+ }
221
+ }
222
+ }
223
+
190
224
impl Step for Rustc {
191
225
type Output = ( ) ;
192
226
const ONLY_HOSTS : bool = true ;
@@ -197,43 +231,26 @@ impl Step for Rustc {
197
231
}
198
232
199
233
fn make_run ( run : RunConfig < ' _ > ) {
234
+ let builder = run. builder ;
200
235
let crates = run. make_run_crates ( Alias :: Compiler ) ;
201
236
let config = LintConfig :: new ( run. builder ) ;
202
- run. builder . ensure ( Rustc { target : run. target , config, crates } ) ;
237
+ run. builder . ensure ( Rustc :: new ( builder , run. target , config, crates) ) ;
203
238
}
204
239
205
- /// Lints the compiler.
206
- ///
207
- /// This will lint the compiler for a particular stage of the build using
208
- /// the `compiler` targeting the `target` architecture.
209
240
fn run ( self , builder : & Builder < ' _ > ) {
210
- let compiler = builder . compiler ( builder . top_stage , builder . config . host_target ) ;
241
+ let build_compiler = self . build_compiler ;
211
242
let target = self . target ;
212
243
213
- if !builder. download_rustc ( ) {
214
- if compiler. stage != 0 {
215
- // If we're not in stage 0, then we won't have a std from the beta
216
- // compiler around. That means we need to make sure there's one in
217
- // the sysroot for the compiler to find. Otherwise, we're going to
218
- // fail when building crates that need to generate code (e.g., build
219
- // scripts and their dependencies).
220
- builder. std ( compiler, compiler. host ) ;
221
- builder. std ( compiler, target) ;
222
- } else {
223
- builder. ensure ( check:: Std :: new ( compiler, target) ) ;
224
- }
225
- }
226
-
227
244
let mut cargo = builder:: Cargo :: new (
228
245
builder,
229
- compiler ,
246
+ build_compiler ,
230
247
Mode :: Rustc ,
231
248
SourceType :: InTree ,
232
249
target,
233
250
Kind :: Clippy ,
234
251
) ;
235
252
236
- rustc_cargo ( builder, & mut cargo, target, & compiler , & self . crates ) ;
253
+ rustc_cargo ( builder, & mut cargo, target, & self . build_compiler , & self . crates ) ;
237
254
238
255
// Explicitly pass -p for all compiler crates -- this will force cargo
239
256
// to also lint the tests/benches/examples for these crates, rather
@@ -249,15 +266,15 @@ impl Step for Rustc {
249
266
builder,
250
267
cargo,
251
268
lint_args ( builder, & self . config , IGNORED_RULES_FOR_STD_AND_RUSTC ) ,
252
- & build_stamp:: librustc_stamp ( builder, compiler , target) ,
269
+ & build_stamp:: librustc_stamp ( builder, build_compiler , target) ,
253
270
vec ! [ ] ,
254
271
true ,
255
272
false ,
256
273
) ;
257
274
}
258
275
259
276
fn metadata ( & self ) -> Option < StepMetadata > {
260
- Some ( StepMetadata :: clippy ( "rustc" , self . target ) )
277
+ Some ( StepMetadata :: clippy ( "rustc" , self . target ) . built_by ( self . build_compiler ) )
261
278
}
262
279
}
263
280
@@ -515,11 +532,12 @@ impl Step for CI {
515
532
] ,
516
533
forbid : vec ! [ ] ,
517
534
} ;
518
- builder. ensure ( Rustc {
519
- target : self . target ,
520
- config : self . config . merge ( & compiler_clippy_cfg) ,
521
- crates : vec ! [ ] ,
522
- } ) ;
535
+ builder. ensure ( Rustc :: new (
536
+ builder,
537
+ self . target ,
538
+ self . config . merge ( & compiler_clippy_cfg) ,
539
+ vec ! [ ] ,
540
+ ) ) ;
523
541
524
542
let rustc_codegen_gcc = LintConfig {
525
543
allow : vec ! [ ] ,
0 commit comments