@@ -32,19 +32,19 @@ impl<T> Context for io::Result<T> {
3232/// # Errors
3333///
3434/// 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 < ( ) > {
3636 let lint = LintData {
3737 pass : pass. expect ( "`pass` argument is validated by clap" ) ,
3838 name : lint_name. expect ( "`name` argument is validated by clap" ) ,
3939 category : category. expect ( "`category` argument is validated by clap" ) ,
4040 project_root : clippy_project_root ( ) ,
4141 } ;
4242
43- create_lint ( & lint) . context ( "Unable to create lint implementation" ) ?;
43+ create_lint ( & lint, msrv ) . context ( "Unable to create lint implementation" ) ?;
4444 create_test ( & lint) . context ( "Unable to create a test for the new lint" )
4545}
4646
47- fn create_lint ( lint : & LintData < ' _ > ) -> io:: Result < ( ) > {
47+ fn create_lint ( lint : & LintData < ' _ > , enable_msrv : bool ) -> io:: Result < ( ) > {
4848 let ( pass_type, pass_lifetimes, pass_import, context_import) = match lint. pass {
4949 "early" => ( "EarlyLintPass" , "" , "use rustc_ast::ast::*;" , "EarlyContext" ) ,
5050 "late" => ( "LateLintPass" , "<'_>" , "use rustc_hir::*;" , "LateContext" ) ,
@@ -55,13 +55,15 @@ fn create_lint(lint: &LintData<'_>) -> io::Result<()> {
5555
5656 let camel_case_name = to_camel_case ( lint. name ) ;
5757 let lint_contents = get_lint_file_contents (
58+ lint. pass ,
5859 pass_type,
5960 pass_lifetimes,
6061 lint. name ,
6162 & camel_case_name,
6263 lint. category ,
6364 pass_import,
6465 context_import,
66+ enable_msrv,
6567 ) ;
6668
6769 let lint_path = format ! ( "clippy_lints/src/{}.rs" , lint. name) ;
@@ -155,20 +157,49 @@ publish = false
155157}
156158
157159fn get_lint_file_contents (
160+ pass_name : & str ,
158161 pass_type : & str ,
159162 pass_lifetimes : & str ,
160163 lint_name : & str ,
161164 camel_case_name : & str ,
162165 category : & str ,
163166 pass_import : & str ,
164167 context_import : & str ,
168+ enable_msrv : bool ,
165169) -> 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;
169178{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+ } ) ;
170200
171- declare_clippy_lint! {{
201+ result. push_str ( & format ! (
202+ "declare_clippy_lint! {{
172203 /// ### What it does
173204 ///
174205 /// ### Why is this bad?
@@ -184,20 +215,65 @@ declare_clippy_lint! {{
184215 pub {name_upper},
185216 {category},
186217 \" 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});
187241}}
188242
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+ "
189260declare_lint_pass!({name_camel} => [{name_upper}]);
190261
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}));
192266" ,
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
201277}
202278
203279#[ test]
0 commit comments