1
1
use crate :: utils:: { clippy_project_root, clippy_version} ;
2
+ use clap:: ValueEnum ;
2
3
use indoc:: { formatdoc, writedoc} ;
3
- use std:: fmt;
4
- use std:: fmt:: Write as _;
4
+ use std:: fmt:: { self , Write as _} ;
5
5
use std:: fs:: { self , OpenOptions } ;
6
6
use std:: io:: prelude:: * ;
7
7
use std:: io:: { self , ErrorKind } ;
8
8
use std:: path:: { Path , PathBuf } ;
9
9
10
+ #[ derive( Clone , Copy , PartialEq , ValueEnum ) ]
11
+ pub enum Pass {
12
+ Early ,
13
+ Late ,
14
+ }
15
+
16
+ impl fmt:: Display for Pass {
17
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
18
+ f. write_str ( match self {
19
+ Pass :: Early => "early" ,
20
+ Pass :: Late => "late" ,
21
+ } )
22
+ }
23
+ }
24
+
10
25
struct LintData < ' a > {
11
- pass : & ' a str ,
26
+ pass : Pass ,
12
27
name : & ' a str ,
13
28
category : & ' a str ,
14
29
ty : Option < & ' a str > ,
@@ -36,7 +51,7 @@ impl<T> Context for io::Result<T> {
36
51
/// # Errors
37
52
///
38
53
/// This function errors out if the files couldn't be created or written to.
39
- pub fn create ( pass : & str , name : & str , category : & str , mut ty : Option < & str > , msrv : bool ) -> io:: Result < ( ) > {
54
+ pub fn create ( pass : Pass , name : & str , category : & str , mut ty : Option < & str > , msrv : bool ) -> io:: Result < ( ) > {
40
55
if category == "cargo" && ty. is_none ( ) {
41
56
// `cargo` is a special category, these lints should always be in `clippy_lints/src/cargo`
42
57
ty = Some ( "cargo" ) ;
@@ -57,7 +72,7 @@ pub fn create(pass: &str, name: &str, category: &str, mut ty: Option<&str>, msrv
57
72
add_lint ( & lint, msrv) . context ( "Unable to add lint to clippy_lints/src/lib.rs" ) ?;
58
73
}
59
74
60
- if pass == "early" {
75
+ if pass == Pass :: Early {
61
76
println ! (
62
77
"\n \
63
78
NOTE: Use a late pass unless you need something specific from\n \
@@ -137,23 +152,17 @@ fn add_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {
137
152
let mut lib_rs = fs:: read_to_string ( path) . context ( "reading" ) ?;
138
153
139
154
let comment_start = lib_rs. find ( "// add lints here," ) . expect ( "Couldn't find comment" ) ;
155
+ let ctor_arg = if lint. pass == Pass :: Late { "_" } else { "" } ;
156
+ let lint_pass = lint. pass ;
157
+ let module_name = lint. name ;
158
+ let camel_name = to_camel_case ( lint. name ) ;
140
159
141
160
let new_lint = if enable_msrv {
142
161
format ! (
143
162
"store.register_{lint_pass}_pass(move |{ctor_arg}| Box::new({module_name}::{camel_name}::new(conf)));\n " ,
144
- lint_pass = lint. pass,
145
- ctor_arg = if lint. pass == "late" { "_" } else { "" } ,
146
- module_name = lint. name,
147
- camel_name = to_camel_case( lint. name) ,
148
163
)
149
164
} else {
150
- format ! (
151
- "store.register_{lint_pass}_pass(|{ctor_arg}| Box::new({module_name}::{camel_name}));\n " ,
152
- lint_pass = lint. pass,
153
- ctor_arg = if lint. pass == "late" { "_" } else { "" } ,
154
- module_name = lint. name,
155
- camel_name = to_camel_case( lint. name) ,
156
- )
165
+ format ! ( "store.register_{lint_pass}_pass(|{ctor_arg}| Box::new({module_name}::{camel_name}));\n " , )
157
166
} ;
158
167
159
168
lib_rs. insert_str ( comment_start, & new_lint) ;
@@ -243,11 +252,16 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
243
252
let mut result = String :: new ( ) ;
244
253
245
254
let ( pass_type, pass_lifetimes, pass_import, context_import) = match lint. pass {
246
- "early" => ( "EarlyLintPass" , "" , "use rustc_ast::ast::*;" , "EarlyContext" ) ,
247
- "late" => ( "LateLintPass" , "<'_>" , "use rustc_hir::*;" , "LateContext" ) ,
248
- _ => {
249
- unreachable ! ( "`pass_type` should only ever be `early` or `late`!" ) ;
250
- } ,
255
+ Pass :: Early => ( "EarlyLintPass" , "" , "use rustc_ast::ast::*;" , "EarlyContext" ) ,
256
+ Pass :: Late => ( "LateLintPass" , "<'_>" , "use rustc_hir::*;" , "LateContext" ) ,
257
+ } ;
258
+ let ( msrv_ty, msrv_ctor, extract_msrv) = match lint. pass {
259
+ Pass :: Early => (
260
+ "MsrvStack" ,
261
+ "MsrvStack::new(conf.msrv)" ,
262
+ "\n extract_msrv_attr!();\n " ,
263
+ ) ,
264
+ Pass :: Late => ( "Msrv" , "conf.msrv" , "" ) ,
251
265
} ;
252
266
253
267
let lint_name = lint. name ;
@@ -258,10 +272,10 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
258
272
result. push_str ( & if enable_msrv {
259
273
formatdoc ! (
260
274
r"
261
- use clippy_utils::msrvs::{{self, Msrv }};
275
+ use clippy_utils::msrvs::{{self, {msrv_ty} }};
262
276
use clippy_config::Conf;
263
277
{pass_import}
264
- use rustc_lint::{{{context_import}, {pass_type}, LintContext }};
278
+ use rustc_lint::{{{context_import}, {pass_type}}};
265
279
use rustc_session::impl_lint_pass;
266
280
267
281
"
@@ -283,20 +297,18 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
283
297
formatdoc ! (
284
298
r"
285
299
pub struct {name_camel} {{
286
- msrv: Msrv ,
300
+ msrv: {msrv_ty} ,
287
301
}}
288
302
289
303
impl {name_camel} {{
290
304
pub fn new(conf: &'static Conf) -> Self {{
291
- Self {{ msrv: conf.msrv.clone() }}
305
+ Self {{ msrv: {msrv_ctor} }}
292
306
}}
293
307
}}
294
308
295
309
impl_lint_pass!({name_camel} => [{name_upper}]);
296
310
297
- impl {pass_type}{pass_lifetimes} for {name_camel} {{
298
- extract_msrv_attr!({context_import});
299
- }}
311
+ impl {pass_type}{pass_lifetimes} for {name_camel} {{{extract_msrv}}}
300
312
301
313
// TODO: Add MSRV level to `clippy_config/src/msrvs.rs` if needed.
302
314
// TODO: Update msrv config comment in `clippy_config/src/conf.rs`
@@ -372,9 +384,9 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R
372
384
373
385
let mod_file_path = ty_dir. join ( "mod.rs" ) ;
374
386
let context_import = setup_mod_file ( & mod_file_path, lint) ?;
375
- let pass_lifetimes = match context_import {
376
- "LateContext" => "<'_>" ,
377
- _ => "" ,
387
+ let ( pass_lifetimes, msrv_ty , msrv_ref , msrv_cx ) = match context_import {
388
+ "LateContext" => ( "<'_>" , "Msrv" , "" , "cx, " ) ,
389
+ _ => ( "" , "MsrvStack" , "&" , "" ) ,
378
390
} ;
379
391
380
392
let name_upper = lint. name . to_uppercase ( ) ;
@@ -384,14 +396,14 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R
384
396
let _: fmt:: Result = writedoc ! (
385
397
lint_file_contents,
386
398
r#"
387
- use clippy_utils::msrvs::{{self, Msrv }};
399
+ use clippy_utils::msrvs::{{self, {msrv_ty} }};
388
400
use rustc_lint::{{{context_import}, LintContext}};
389
401
390
402
use super::{name_upper};
391
403
392
404
// TODO: Adjust the parameters as necessary
393
- pub(super) fn check(cx: &{context_import}{pass_lifetimes}, msrv: &Msrv ) {{
394
- if !msrv.meets(todo!("Add a new entry in `clippy_utils/src/msrvs`")) {{
405
+ pub(super) fn check(cx: &{context_import}{pass_lifetimes}, msrv: {msrv_ref}{msrv_ty} ) {{
406
+ if !msrv.meets({msrv_cx} todo!("Add a new entry in `clippy_utils/src/msrvs`")) {{
395
407
return;
396
408
}}
397
409
todo!();
0 commit comments