Skip to content

Commit da76c06

Browse files
author
Michael Wright
committed
Add --msrv option to new_lint command
1 parent 22144c0 commit da76c06

File tree

2 files changed

+98
-16
lines changed

2 files changed

+98
-16
lines changed

clippy_dev/src/main.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ fn main() {
2828
matches.value_of("pass"),
2929
matches.value_of("name"),
3030
matches.value_of("category"),
31+
matches.is_present("msrv"),
3132
) {
3233
Ok(_) => update_lints::run(update_lints::UpdateMode::Change),
3334
Err(e) => eprintln!("Unable to create lint: {}", e),
@@ -147,6 +148,11 @@ fn get_clap_config<'a>() -> ArgMatches<'a> {
147148
"internal_warn",
148149
])
149150
.takes_value(true),
151+
)
152+
.arg(
153+
Arg::with_name("msrv")
154+
.long("msrv")
155+
.help("Add MSRV config code to the lint"),
150156
),
151157
)
152158
.subcommand(

clippy_dev/src/new_lint.rs

Lines changed: 92 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

157159
fn 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+
"
189260
declare_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

Comments
 (0)