@@ -20,14 +20,12 @@ const IGNORED_RULES_FOR_STD_AND_RUSTC: &[&str] = &[
2020 "wrong_self_convention" ,
2121] ;
2222
23- fn lint_args ( builder : & Builder < ' _ > , ignored_rules : & [ & str ] ) -> Vec < String > {
23+ fn lint_args ( builder : & Builder < ' _ > , config : & LintConfig , ignored_rules : & [ & str ] ) -> Vec < String > {
2424 fn strings < ' a > ( arr : & ' a [ & str ] ) -> impl Iterator < Item = String > + ' a {
2525 arr. iter ( ) . copied ( ) . map ( String :: from)
2626 }
2727
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 {
3129 unreachable ! ( "clippy::lint_args can only be called from `clippy` subcommands." ) ;
3230 } ;
3331
@@ -53,12 +51,12 @@ fn lint_args(builder: &Builder<'_>, ignored_rules: &[&str]) -> Vec<String> {
5351
5452 args. extend ( strings ( & [ "--" ] ) ) ;
5553
56- if deny. is_empty ( ) && forbid. is_empty ( ) {
54+ if config . deny . is_empty ( ) && config . forbid . is_empty ( ) {
5755 args. extend ( strings ( & [ "--cap-lints" , "warn" ] ) ) ;
5856 }
5957
6058 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 ) ) ;
6260
6361 args. extend ( ignored_rules. iter ( ) . map ( |lint| format ! ( "-Aclippy::{}" , lint) ) ) ;
6462 args. extend ( builder. config . free_args . clone ( ) ) ;
@@ -68,21 +66,17 @@ fn lint_args(builder: &Builder<'_>, ignored_rules: &[&str]) -> Vec<String> {
6866/// We need to keep the order of the given clippy lint rules before passing them.
6967/// Since clap doesn't offer any useful interface for this purpose out of the box,
7068/// 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 > {
7870 let mut result = vec ! [ ] ;
7971
8072 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 ) ]
8274 {
8375 item. iter ( ) . for_each ( |v| {
8476 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 ) ;
8680 result. push ( ( position, rule) ) ;
8781 } ) ;
8882 }
@@ -91,9 +85,42 @@ pub(crate) fn get_clippy_rules_in_order(
9185 result. into_iter ( ) . map ( |v| v. 1 ) . collect ( )
9286}
9387
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+
94120#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
95121pub struct Std {
96122 pub target : TargetSelection ,
123+ config : LintConfig ,
97124 /// Whether to lint only a subset of crates.
98125 crates : Vec < String > ,
99126}
@@ -108,7 +135,8 @@ impl Step for Std {
108135
109136 fn make_run ( run : RunConfig < ' _ > ) {
110137 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 } ) ;
112140 }
113141
114142 fn run ( self , builder : & Builder < ' _ > ) {
@@ -138,7 +166,7 @@ impl Step for Std {
138166 run_cargo (
139167 builder,
140168 cargo,
141- lint_args ( builder, IGNORED_RULES_FOR_STD_AND_RUSTC ) ,
169+ lint_args ( builder, & self . config , IGNORED_RULES_FOR_STD_AND_RUSTC ) ,
142170 & libstd_stamp ( builder, compiler, target) ,
143171 vec ! [ ] ,
144172 true ,
@@ -150,6 +178,7 @@ impl Step for Std {
150178#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
151179pub struct Rustc {
152180 pub target : TargetSelection ,
181+ config : LintConfig ,
153182 /// Whether to lint only a subset of crates.
154183 crates : Vec < String > ,
155184}
@@ -165,7 +194,8 @@ impl Step for Rustc {
165194
166195 fn make_run ( run : RunConfig < ' _ > ) {
167196 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 } ) ;
169199 }
170200
171201 /// Lints the compiler.
@@ -212,7 +242,7 @@ impl Step for Rustc {
212242 run_cargo (
213243 builder,
214244 cargo,
215- lint_args ( builder, IGNORED_RULES_FOR_STD_AND_RUSTC ) ,
245+ lint_args ( builder, & self . config , IGNORED_RULES_FOR_STD_AND_RUSTC ) ,
216246 & librustc_stamp ( builder, compiler, target) ,
217247 vec ! [ ] ,
218248 true ,
@@ -232,6 +262,7 @@ macro_rules! lint_any {
232262 #[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
233263 pub struct $name {
234264 pub target: TargetSelection ,
265+ config: LintConfig ,
235266 }
236267
237268 impl Step for $name {
@@ -243,8 +274,10 @@ macro_rules! lint_any {
243274 }
244275
245276 fn make_run( run: RunConfig <' _>) {
277+ let config = LintConfig :: new( run. builder) ;
246278 run. builder. ensure( $name {
247279 target: run. target,
280+ config,
248281 } ) ;
249282 }
250283
@@ -281,7 +314,7 @@ macro_rules! lint_any {
281314 run_cargo(
282315 builder,
283316 cargo,
284- lint_args( builder, & [ ] ) ,
317+ lint_args( builder, & self . config , & [ ] ) ,
285318 & stamp,
286319 vec![ ] ,
287320 true ,
@@ -319,3 +352,58 @@ lint_any!(
319352 Tidy , "src/tools/tidy" , "tidy" ;
320353 TestFloatParse , "src/etc/test-float-parse" , "test-float-parse" ;
321354) ;
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