@@ -20,14 +20,12 @@ const IGNORED_RULES_FOR_STD_AND_RUSTC: &[&str] = &[
20
20
"wrong_self_convention" ,
21
21
] ;
22
22
23
- fn lint_args ( builder : & Builder < ' _ > , ignored_rules : & [ & str ] ) -> Vec < String > {
23
+ fn lint_args ( builder : & Builder < ' _ > , config : & LintConfig , ignored_rules : & [ & str ] ) -> Vec < String > {
24
24
fn strings < ' a > ( arr : & ' a [ & str ] ) -> impl Iterator < Item = String > + ' a {
25
25
arr. iter ( ) . copied ( ) . map ( String :: from)
26
26
}
27
27
28
- let Subcommand :: Clippy { fix, allow_dirty, allow_staged, allow, deny, warn, forbid } =
29
- & builder. config . cmd
30
- else {
28
+ let Subcommand :: Clippy { fix, allow_dirty, allow_staged, .. } = & builder. config . cmd else {
31
29
unreachable ! ( "clippy::lint_args can only be called from `clippy` subcommands." ) ;
32
30
} ;
33
31
@@ -53,12 +51,12 @@ fn lint_args(builder: &Builder<'_>, ignored_rules: &[&str]) -> Vec<String> {
53
51
54
52
args. extend ( strings ( & [ "--" ] ) ) ;
55
53
56
- if deny. is_empty ( ) && forbid. is_empty ( ) {
54
+ if config . deny . is_empty ( ) && config . forbid . is_empty ( ) {
57
55
args. extend ( strings ( & [ "--cap-lints" , "warn" ] ) ) ;
58
56
}
59
57
60
58
let all_args = std:: env:: args ( ) . collect :: < Vec < _ > > ( ) ;
61
- args. extend ( get_clippy_rules_in_order ( & all_args, allow , deny , warn , forbid ) ) ;
59
+ args. extend ( get_clippy_rules_in_order ( & all_args, config ) ) ;
62
60
63
61
args. extend ( ignored_rules. iter ( ) . map ( |lint| format ! ( "-Aclippy::{}" , lint) ) ) ;
64
62
args. extend ( builder. config . free_args . clone ( ) ) ;
@@ -68,21 +66,17 @@ fn lint_args(builder: &Builder<'_>, ignored_rules: &[&str]) -> Vec<String> {
68
66
/// We need to keep the order of the given clippy lint rules before passing them.
69
67
/// Since clap doesn't offer any useful interface for this purpose out of the box,
70
68
/// we have to handle it manually.
71
- pub ( crate ) fn get_clippy_rules_in_order (
72
- all_args : & [ String ] ,
73
- allow_rules : & [ String ] ,
74
- deny_rules : & [ String ] ,
75
- warn_rules : & [ String ] ,
76
- forbid_rules : & [ String ] ,
77
- ) -> Vec < String > {
69
+ pub fn get_clippy_rules_in_order ( all_args : & [ String ] , config : & LintConfig ) -> Vec < String > {
78
70
let mut result = vec ! [ ] ;
79
71
80
72
for ( prefix, item) in
81
- [ ( "-A" , allow_rules ) , ( "-D" , deny_rules ) , ( "-W" , warn_rules ) , ( "-F" , forbid_rules ) ]
73
+ [ ( "-A" , & config . allow ) , ( "-D" , & config . deny ) , ( "-W" , & config . warn ) , ( "-F" , & config . forbid ) ]
82
74
{
83
75
item. iter ( ) . for_each ( |v| {
84
76
let rule = format ! ( "{prefix}{v}" ) ;
85
- let position = all_args. iter ( ) . position ( |t| t == & rule || t == v) . unwrap ( ) ;
77
+ // Arguments added by bootstrap in LintConfig won't show up in the all_args list, so
78
+ // put them at the end of the command line.
79
+ let position = all_args. iter ( ) . position ( |t| t == & rule || t == v) . unwrap_or ( usize:: MAX ) ;
86
80
result. push ( ( position, rule) ) ;
87
81
} ) ;
88
82
}
@@ -91,9 +85,42 @@ pub(crate) fn get_clippy_rules_in_order(
91
85
result. into_iter ( ) . map ( |v| v. 1 ) . collect ( )
92
86
}
93
87
88
+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
89
+ pub struct LintConfig {
90
+ pub allow : Vec < String > ,
91
+ pub warn : Vec < String > ,
92
+ pub deny : Vec < String > ,
93
+ pub forbid : Vec < String > ,
94
+ }
95
+
96
+ impl LintConfig {
97
+ fn new ( builder : & Builder < ' _ > ) -> Self {
98
+ match builder. config . cmd . clone ( ) {
99
+ Subcommand :: Clippy { allow, deny, warn, forbid, .. } => {
100
+ Self { allow, warn, deny, forbid }
101
+ }
102
+ _ => unreachable ! ( "LintConfig can only be called from `clippy` subcommands." ) ,
103
+ }
104
+ }
105
+
106
+ fn merge ( & self , other : & Self ) -> Self {
107
+ let merged = |self_attr : & [ String ] , other_attr : & [ String ] | -> Vec < String > {
108
+ self_attr. iter ( ) . cloned ( ) . chain ( other_attr. iter ( ) . cloned ( ) ) . collect ( )
109
+ } ;
110
+ // This is written this way to ensure we get a compiler error if we add a new field.
111
+ Self {
112
+ allow : merged ( & self . allow , & other. allow ) ,
113
+ warn : merged ( & self . warn , & other. warn ) ,
114
+ deny : merged ( & self . deny , & other. deny ) ,
115
+ forbid : merged ( & self . forbid , & other. forbid ) ,
116
+ }
117
+ }
118
+ }
119
+
94
120
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
95
121
pub struct Std {
96
122
pub target : TargetSelection ,
123
+ config : LintConfig ,
97
124
/// Whether to lint only a subset of crates.
98
125
crates : Vec < String > ,
99
126
}
@@ -108,7 +135,8 @@ impl Step for Std {
108
135
109
136
fn make_run ( run : RunConfig < ' _ > ) {
110
137
let crates = std_crates_for_run_make ( & run) ;
111
- run. builder . ensure ( Std { target : run. target , crates } ) ;
138
+ let config = LintConfig :: new ( run. builder ) ;
139
+ run. builder . ensure ( Std { target : run. target , config, crates } ) ;
112
140
}
113
141
114
142
fn run ( self , builder : & Builder < ' _ > ) {
@@ -138,7 +166,7 @@ impl Step for Std {
138
166
run_cargo (
139
167
builder,
140
168
cargo,
141
- lint_args ( builder, IGNORED_RULES_FOR_STD_AND_RUSTC ) ,
169
+ lint_args ( builder, & self . config , IGNORED_RULES_FOR_STD_AND_RUSTC ) ,
142
170
& libstd_stamp ( builder, compiler, target) ,
143
171
vec ! [ ] ,
144
172
true ,
@@ -150,6 +178,7 @@ impl Step for Std {
150
178
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
151
179
pub struct Rustc {
152
180
pub target : TargetSelection ,
181
+ config : LintConfig ,
153
182
/// Whether to lint only a subset of crates.
154
183
crates : Vec < String > ,
155
184
}
@@ -165,7 +194,8 @@ impl Step for Rustc {
165
194
166
195
fn make_run ( run : RunConfig < ' _ > ) {
167
196
let crates = run. make_run_crates ( Alias :: Compiler ) ;
168
- run. builder . ensure ( Rustc { target : run. target , crates } ) ;
197
+ let config = LintConfig :: new ( run. builder ) ;
198
+ run. builder . ensure ( Rustc { target : run. target , config, crates } ) ;
169
199
}
170
200
171
201
/// Lints the compiler.
@@ -212,7 +242,7 @@ impl Step for Rustc {
212
242
run_cargo (
213
243
builder,
214
244
cargo,
215
- lint_args ( builder, IGNORED_RULES_FOR_STD_AND_RUSTC ) ,
245
+ lint_args ( builder, & self . config , IGNORED_RULES_FOR_STD_AND_RUSTC ) ,
216
246
& librustc_stamp ( builder, compiler, target) ,
217
247
vec ! [ ] ,
218
248
true ,
@@ -232,6 +262,7 @@ macro_rules! lint_any {
232
262
#[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
233
263
pub struct $name {
234
264
pub target: TargetSelection ,
265
+ config: LintConfig ,
235
266
}
236
267
237
268
impl Step for $name {
@@ -243,8 +274,10 @@ macro_rules! lint_any {
243
274
}
244
275
245
276
fn make_run( run: RunConfig <' _>) {
277
+ let config = LintConfig :: new( run. builder) ;
246
278
run. builder. ensure( $name {
247
279
target: run. target,
280
+ config,
248
281
} ) ;
249
282
}
250
283
@@ -281,7 +314,7 @@ macro_rules! lint_any {
281
314
run_cargo(
282
315
builder,
283
316
cargo,
284
- lint_args( builder, & [ ] ) ,
317
+ lint_args( builder, & self . config , & [ ] ) ,
285
318
& stamp,
286
319
vec![ ] ,
287
320
true ,
@@ -319,3 +352,58 @@ lint_any!(
319
352
Tidy , "src/tools/tidy" , "tidy" ;
320
353
TestFloatParse , "src/etc/test-float-parse" , "test-float-parse" ;
321
354
) ;
355
+
356
+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
357
+ pub struct CI {
358
+ target : TargetSelection ,
359
+ config : LintConfig ,
360
+ }
361
+
362
+ impl Step for CI {
363
+ type Output = ( ) ;
364
+ const DEFAULT : bool = false ;
365
+
366
+ fn should_run ( run : ShouldRun < ' _ > ) -> ShouldRun < ' _ > {
367
+ run. alias ( "ci" )
368
+ }
369
+
370
+ fn make_run ( run : RunConfig < ' _ > ) {
371
+ let config = LintConfig :: new ( run. builder ) ;
372
+ run. builder . ensure ( CI { target : run. target , config } ) ;
373
+ }
374
+
375
+ fn run ( self , builder : & Builder < ' _ > ) -> Self :: Output {
376
+ builder. ensure ( Bootstrap {
377
+ target : self . target ,
378
+ config : self . config . merge ( & LintConfig {
379
+ allow : vec ! [ ] ,
380
+ warn : vec ! [ ] ,
381
+ deny : vec ! [ "warnings" . into( ) ] ,
382
+ forbid : vec ! [ ] ,
383
+ } ) ,
384
+ } ) ;
385
+ let library_clippy_cfg = LintConfig {
386
+ allow : vec ! [ "clippy::all" . into( ) ] ,
387
+ warn : vec ! [ ] ,
388
+ deny : vec ! [ "clippy::correctness" . into( ) ] ,
389
+ forbid : vec ! [ ] ,
390
+ } ;
391
+ let compiler_clippy_cfg = LintConfig {
392
+ allow : vec ! [ "clippy::all" . into( ) ] ,
393
+ warn : vec ! [ ] ,
394
+ deny : vec ! [ "clippy::correctness" . into( ) , "clippy::clone_on_ref_ptr" . into( ) ] ,
395
+ forbid : vec ! [ ] ,
396
+ } ;
397
+
398
+ builder. ensure ( Std {
399
+ target : self . target ,
400
+ config : self . config . merge ( & library_clippy_cfg) ,
401
+ crates : vec ! [ ] ,
402
+ } ) ;
403
+ builder. ensure ( Rustc {
404
+ target : self . target ,
405
+ config : self . config . merge ( & compiler_clippy_cfg) ,
406
+ crates : vec ! [ ] ,
407
+ } ) ;
408
+ }
409
+ }
0 commit comments