@@ -32,19 +32,19 @@ impl<T> Context for io::Result<T> {
32
32
/// # Errors
33
33
///
34
34
/// This function errors out if the files couldn't be created or written to.
35
- pub fn create ( pass : Option < & str > , lint_name : Option < & str > , category : Option < & str > ) -> io:: Result < ( ) > {
35
+ pub fn create ( pass : Option < & str > , lint_name : Option < & str > , category : Option < & str > , msrv : bool ) -> io:: Result < ( ) > {
36
36
let lint = LintData {
37
37
pass : pass. expect ( "`pass` argument is validated by clap" ) ,
38
38
name : lint_name. expect ( "`name` argument is validated by clap" ) ,
39
39
category : category. expect ( "`category` argument is validated by clap" ) ,
40
40
project_root : clippy_project_root ( ) ,
41
41
} ;
42
42
43
- create_lint ( & lint) . context ( "Unable to create lint implementation" ) ?;
43
+ create_lint ( & lint, msrv ) . context ( "Unable to create lint implementation" ) ?;
44
44
create_test ( & lint) . context ( "Unable to create a test for the new lint" )
45
45
}
46
46
47
- fn create_lint ( lint : & LintData < ' _ > ) -> io:: Result < ( ) > {
47
+ fn create_lint ( lint : & LintData < ' _ > , enable_msrv : bool ) -> io:: Result < ( ) > {
48
48
let ( pass_type, pass_lifetimes, pass_import, context_import) = match lint. pass {
49
49
"early" => ( "EarlyLintPass" , "" , "use rustc_ast::ast::*;" , "EarlyContext" ) ,
50
50
"late" => ( "LateLintPass" , "<'_>" , "use rustc_hir::*;" , "LateContext" ) ,
@@ -55,13 +55,15 @@ fn create_lint(lint: &LintData<'_>) -> io::Result<()> {
55
55
56
56
let camel_case_name = to_camel_case ( lint. name ) ;
57
57
let lint_contents = get_lint_file_contents (
58
+ lint. pass ,
58
59
pass_type,
59
60
pass_lifetimes,
60
61
lint. name ,
61
62
& camel_case_name,
62
63
lint. category ,
63
64
pass_import,
64
65
context_import,
66
+ enable_msrv,
65
67
) ;
66
68
67
69
let lint_path = format ! ( "clippy_lints/src/{}.rs" , lint. name) ;
@@ -155,20 +157,49 @@ publish = false
155
157
}
156
158
157
159
fn get_lint_file_contents (
160
+ pass_name : & str ,
158
161
pass_type : & str ,
159
162
pass_lifetimes : & str ,
160
163
lint_name : & str ,
161
164
camel_case_name : & str ,
162
165
category : & str ,
163
166
pass_import : & str ,
164
167
context_import : & str ,
168
+ enable_msrv : bool ,
165
169
) -> String {
166
- format ! (
167
- "use rustc_lint::{{{type}, {context_import}}};
168
- use rustc_session::{{declare_lint_pass, declare_tool_lint}};
170
+ let mut result = String :: new ( ) ;
171
+
172
+ let name_camel = camel_case_name;
173
+ let name_upper = lint_name. to_uppercase ( ) ;
174
+
175
+ result. push_str ( & if enable_msrv {
176
+ format ! (
177
+ "use clippy_utils::msrvs;
169
178
{pass_import}
179
+ use rustc_lint::{{{context_import}, {pass_type}, LintContext}};
180
+ use rustc_semver::RustcVersion;
181
+ use rustc_session::{{declare_tool_lint, impl_lint_pass}};
182
+
183
+ " ,
184
+ pass_type = pass_type,
185
+ pass_import = pass_import,
186
+ context_import = context_import,
187
+ )
188
+ } else {
189
+ format ! (
190
+ "{pass_import}
191
+ use rustc_lint::{{{context_import}, {pass_type}}};
192
+ use rustc_session::{{declare_lint_pass, declare_tool_lint}};
193
+
194
+ " ,
195
+ pass_import = pass_import,
196
+ pass_type = pass_type,
197
+ context_import = context_import
198
+ )
199
+ } ) ;
170
200
171
- declare_clippy_lint! {{
201
+ result. push_str ( & format ! (
202
+ "declare_clippy_lint! {{
172
203
/// ### What it does
173
204
///
174
205
/// ### Why is this bad?
@@ -184,20 +215,65 @@ declare_clippy_lint! {{
184
215
pub {name_upper},
185
216
{category},
186
217
\" default lint description\"
218
+ }}" ,
219
+ name_upper = name_upper,
220
+ category = category,
221
+ ) ) ;
222
+
223
+ result. push_str ( & if enable_msrv {
224
+ format ! (
225
+ "
226
+ pub struct {name_camel} {{
227
+ msrv: Option<RustcVersion>,
228
+ }}
229
+
230
+ impl {name_camel} {{
231
+ #[must_use]
232
+ pub fn new(msrv: Option<RustcVersion>) -> Self {{
233
+ Self {{ msrv }}
234
+ }}
235
+ }}
236
+
237
+ impl_lint_pass!({name_camel} => [{name_upper}]);
238
+
239
+ impl {pass_type}{pass_lifetimes} for {name_camel} {{
240
+ extract_msrv_attr!({context_import});
187
241
}}
188
242
243
+ // TODO: Register the lint pass in `clippy_lints/src/lib.rs`,
244
+ // e.g. store.register_{pass_name}_pass(move || Box::new({module_name}::{name_camel}::new(msrv)));
245
+ // TODO: Add MSRV level to `clippy_utils/src/msrvs.rs` if needed.
246
+ // TODO: Add MSRV test to `tests/ui/min_rust_version_attr.rs`.
247
+ // TODO: Update msrv config comment in `clippy_lints/src/utils/conf.rs`
248
+ " ,
249
+ pass_type = pass_type,
250
+ pass_lifetimes = pass_lifetimes,
251
+ pass_name = pass_name,
252
+ name_upper = name_upper,
253
+ name_camel = name_camel,
254
+ module_name = lint_name,
255
+ context_import = context_import,
256
+ )
257
+ } else {
258
+ format ! (
259
+ "
189
260
declare_lint_pass!({name_camel} => [{name_upper}]);
190
261
191
- impl {type}{lifetimes} for {name_camel} {{}}
262
+ impl {pass_type}{pass_lifetimes} for {name_camel} {{}}
263
+ //
264
+ // TODO: Register the lint pass in `clippy_lints/src/lib.rs`,
265
+ // e.g. store.register_{pass_name}_pass(|| Box::new({module_name}::{name_camel}));
192
266
" ,
193
- type =pass_type,
194
- lifetimes=pass_lifetimes,
195
- name_upper=lint_name. to_uppercase( ) ,
196
- name_camel=camel_case_name,
197
- category=category,
198
- pass_import=pass_import,
199
- context_import=context_import
200
- )
267
+ pass_type = pass_type,
268
+ pass_lifetimes = pass_lifetimes,
269
+ pass_name = pass_name,
270
+ name_upper = name_upper,
271
+ name_camel = name_camel,
272
+ module_name = lint_name,
273
+ )
274
+ } ) ;
275
+
276
+ result
201
277
}
202
278
203
279
#[ test]
0 commit comments