Skip to content

Commit 61e2e2f

Browse files
committed
add MSRV to more lints specified in rust-lang#6097
update tests
1 parent 50bca8a commit 61e2e2f

7 files changed

+126
-19
lines changed

clippy_lints/src/checked_conversions.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ use rustc_errors::Applicability;
66
use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind, QPath, TyKind};
77
use rustc_lint::{LateContext, LateLintPass, LintContext};
88
use rustc_middle::lint::in_external_macro;
9-
use rustc_session::{declare_lint_pass, declare_tool_lint};
9+
use rustc_semver::RustcVersion;
10+
use rustc_session::{impl_lint_pass, declare_tool_lint};
1011

11-
use crate::utils::{snippet_with_applicability, span_lint_and_sugg, SpanlessEq};
12+
use crate::utils::{meets_msrv, snippet_with_applicability, span_lint_and_sugg, SpanlessEq};
13+
14+
const CHECKED_CONVERSIONS_MSRV: RustcVersion = RustcVersion::new(1, 34, 0);
1215

1316
declare_clippy_lint! {
1417
/// **What it does:** Checks for explicit bounds checking when casting.
@@ -39,10 +42,26 @@ declare_clippy_lint! {
3942
"`try_from` could replace manual bounds checking when casting"
4043
}
4144

42-
declare_lint_pass!(CheckedConversions => [CHECKED_CONVERSIONS]);
45+
pub struct CheckedConversions {
46+
msrv: Option<RustcVersion>,
47+
}
48+
49+
impl CheckedConversions {
50+
#[must_use]
51+
pub fn new(msrv: Option<RustcVersion>) -> Self {
52+
Self { msrv }
53+
}
54+
}
55+
56+
impl_lint_pass!(CheckedConversions => [CHECKED_CONVERSIONS]);
4357

4458
impl<'tcx> LateLintPass<'tcx> for CheckedConversions {
4559
fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) {
60+
61+
if !meets_msrv(self.msrv.as_ref(), &CHECKED_CONVERSIONS_MSRV) {
62+
return;
63+
}
64+
4665
let result = if_chain! {
4766
if !in_external_macro(cx.sess(), item.span);
4867
if let ExprKind::Binary(op, ref left, ref right) = &item.kind;
@@ -74,6 +93,8 @@ impl<'tcx> LateLintPass<'tcx> for CheckedConversions {
7493
}
7594
}
7695
}
96+
97+
extract_msrv_attr!(LateContext);
7798
}
7899

79100
/// Searches for a single check from unsigned to _ is done

clippy_lints/src/lib.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,10 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10021002
store.register_late_pass(move || box matches::Matches::new(msrv));
10031003
store.register_early_pass(move || box manual_non_exhaustive::ManualNonExhaustive::new(msrv));
10041004
store.register_late_pass(move || box manual_strip::ManualStrip::new(msrv));
1005+
store.register_early_pass(move || box redundant_static_lifetimes::RedundantStaticLifetimes::new(msrv));
1006+
store.register_early_pass(move || box redundant_field_names::RedundantFieldNames::new(msrv));
1007+
store.register_late_pass(move || box checked_conversions::CheckedConversions::new(msrv));
1008+
10051009
store.register_late_pass(|| box size_of_in_element_count::SizeOfInElementCount);
10061010
store.register_late_pass(|| box map_clone::MapClone);
10071011
store.register_late_pass(|| box map_err_ignore::MapErrIgnore);
@@ -1108,7 +1112,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
11081112
store.register_late_pass(|| box missing_const_for_fn::MissingConstForFn);
11091113
store.register_late_pass(|| box transmuting_null::TransmutingNull);
11101114
store.register_late_pass(|| box path_buf_push_overwrite::PathBufPushOverwrite);
1111-
store.register_late_pass(|| box checked_conversions::CheckedConversions);
11121115
store.register_late_pass(|| box integer_division::IntegerDivision);
11131116
store.register_late_pass(|| box inherent_to_string::InherentToString);
11141117
let max_trait_bounds = conf.max_trait_bounds;
@@ -1137,7 +1140,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
11371140
store.register_early_pass(|| box redundant_else::RedundantElse);
11381141
store.register_late_pass(|| box create_dir::CreateDir);
11391142
store.register_early_pass(|| box needless_arbitrary_self_type::NeedlessArbitrarySelfType);
1140-
store.register_early_pass(|| box redundant_static_lifetimes::RedundantStaticLifetimes);
11411143
store.register_late_pass(|| box cargo_common_metadata::CargoCommonMetadata);
11421144
store.register_late_pass(|| box multiple_crate_versions::MultipleCrateVersions);
11431145
store.register_late_pass(|| box wildcard_dependencies::WildcardDependencies);
@@ -1177,7 +1179,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
11771179
store.register_late_pass(|| box mut_mutex_lock::MutMutexLock);
11781180
store.register_late_pass(|| box match_on_vec_items::MatchOnVecItems);
11791181
store.register_late_pass(|| box manual_async_fn::ManualAsyncFn);
1180-
store.register_early_pass(|| box redundant_field_names::RedundantFieldNames);
11811182
store.register_late_pass(|| box vec_resize_to_zero::VecResizeToZero);
11821183
store.register_late_pass(|| box panic_in_result_fn::PanicInResultFn);
11831184
let single_char_binding_names_threshold = conf.single_char_binding_names_threshold;

clippy_lints/src/methods/mod.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -1509,7 +1509,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
15091509
["next", "iter"] => lint_iter_next(cx, expr, arg_lists[1]),
15101510
["map", "filter"] => lint_filter_map(cx, expr, arg_lists[1], arg_lists[0]),
15111511
["map", "filter_map"] => lint_filter_map_map(cx, expr, arg_lists[1], arg_lists[0]),
1512-
["next", "filter_map"] => lint_filter_map_next(cx, expr, arg_lists[1]),
1512+
["next", "filter_map"] => lint_filter_map_next(cx, expr, arg_lists[1], self.msrv.as_ref()),
15131513
["map", "find"] => lint_find_map(cx, expr, arg_lists[1], arg_lists[0]),
15141514
["flat_map", "filter"] => lint_filter_flat_map(cx, expr, arg_lists[1], arg_lists[0]),
15151515
["flat_map", "filter_map"] => lint_filter_map_flat_map(cx, expr, arg_lists[1], arg_lists[0]),
@@ -2923,9 +2923,16 @@ fn lint_filter_map<'tcx>(
29232923
}
29242924
}
29252925

2926+
const FILTER_MAP_NEXT_MSRV: RustcVersion = RustcVersion::new(1, 30, 0);
2927+
29262928
/// lint use of `filter_map().next()` for `Iterators`
2927-
fn lint_filter_map_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, filter_args: &'tcx [hir::Expr<'_>]) {
2929+
fn lint_filter_map_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, filter_args: &'tcx [hir::Expr<'_>], msrv: Option<&RustcVersion>) {
29282930
if match_trait_method(cx, expr, &paths::ITERATOR) {
2931+
2932+
if !meets_msrv(msrv, &FILTER_MAP_NEXT_MSRV) {
2933+
return;
2934+
}
2935+
29292936
let msg = "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling \
29302937
`.find_map(..)` instead.";
29312938
let filter_snippet = snippet(cx, filter_args[1].span, "..");

clippy_lints/src/redundant_field_names.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
use crate::utils::span_lint_and_sugg;
1+
use crate::utils::{meets_msrv, span_lint_and_sugg};
22
use rustc_ast::ast::{Expr, ExprKind};
33
use rustc_errors::Applicability;
44
use rustc_lint::{EarlyContext, EarlyLintPass};
55
use rustc_middle::lint::in_external_macro;
6-
use rustc_session::{declare_lint_pass, declare_tool_lint};
6+
use rustc_semver::RustcVersion;
7+
use rustc_session::{impl_lint_pass, declare_tool_lint};
8+
9+
const REDUNDANT_FIELD_NAMES_MSRV: RustcVersion = RustcVersion::new(1, 17, 0);
710

811
declare_clippy_lint! {
912
/// **What it does:** Checks for fields in struct literals where shorthands
@@ -33,10 +36,26 @@ declare_clippy_lint! {
3336
"checks for fields in struct literals where shorthands could be used"
3437
}
3538

36-
declare_lint_pass!(RedundantFieldNames => [REDUNDANT_FIELD_NAMES]);
39+
pub struct RedundantFieldNames {
40+
msrv: Option<RustcVersion>,
41+
}
42+
43+
impl RedundantFieldNames {
44+
#[must_use]
45+
pub fn new(msrv: Option<RustcVersion>) -> Self {
46+
Self { msrv }
47+
}
48+
}
49+
50+
impl_lint_pass!(RedundantFieldNames => [REDUNDANT_FIELD_NAMES]);
3751

3852
impl EarlyLintPass for RedundantFieldNames {
3953
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
54+
55+
if !meets_msrv(self.msrv.as_ref(), &REDUNDANT_FIELD_NAMES_MSRV) {
56+
return;
57+
}
58+
4059
if in_external_macro(cx.sess, expr.span) {
4160
return;
4261
}
@@ -64,4 +83,6 @@ impl EarlyLintPass for RedundantFieldNames {
6483
}
6584
}
6685
}
86+
87+
extract_msrv_attr!(EarlyContext);
6788
}

clippy_lints/src/redundant_static_lifetimes.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
use crate::utils::{snippet, span_lint_and_then};
1+
use crate::utils::{meets_msrv, snippet, span_lint_and_then};
22
use rustc_ast::ast::{Item, ItemKind, Ty, TyKind};
33
use rustc_errors::Applicability;
44
use rustc_lint::{EarlyContext, EarlyLintPass};
5-
use rustc_session::{declare_lint_pass, declare_tool_lint};
5+
use rustc_semver::RustcVersion;
6+
use rustc_session::{impl_lint_pass, declare_tool_lint};
7+
8+
const REDUNDANT_STATIC_LIFETIMES_MSRV: RustcVersion = RustcVersion::new(1, 17, 0);
69

710
declare_clippy_lint! {
811
/// **What it does:** Checks for constants and statics with an explicit `'static` lifetime.
@@ -29,7 +32,18 @@ declare_clippy_lint! {
2932
"Using explicit `'static` lifetime for constants or statics when elision rules would allow omitting them."
3033
}
3134

32-
declare_lint_pass!(RedundantStaticLifetimes => [REDUNDANT_STATIC_LIFETIMES]);
35+
pub struct RedundantStaticLifetimes {
36+
msrv: Option<RustcVersion>,
37+
}
38+
39+
impl RedundantStaticLifetimes {
40+
#[must_use]
41+
pub fn new(msrv: Option<RustcVersion>) -> Self {
42+
Self { msrv }
43+
}
44+
}
45+
46+
impl_lint_pass!(RedundantStaticLifetimes => [REDUNDANT_STATIC_LIFETIMES]);
3347

3448
impl RedundantStaticLifetimes {
3549
// Recursively visit types
@@ -84,6 +98,11 @@ impl RedundantStaticLifetimes {
8498

8599
impl EarlyLintPass for RedundantStaticLifetimes {
86100
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
101+
102+
if !meets_msrv(self.msrv.as_ref(), &REDUNDANT_STATIC_LIFETIMES_MSRV) {
103+
return;
104+
}
105+
87106
if !item.span.from_expansion() {
88107
if let ItemKind::Const(_, ref var_type, _) = item.kind {
89108
self.visit_type(var_type, cx, "constants have by default a `'static` lifetime");
@@ -96,4 +115,6 @@ impl EarlyLintPass for RedundantStaticLifetimes {
96115
}
97116
}
98117
}
118+
119+
extract_msrv_attr!(EarlyContext);
99120
}

tests/ui/min_rust_version_attr.rs

+37-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#![feature(custom_inner_attributes)]
33
#![clippy::msrv = "1.0.0"]
44

5-
use std::ops::Deref;
5+
use std::ops::{RangeFrom, Deref};
66

77
fn option_as_ref_deref() {
88
let mut opt = Some(String::from("123"));
@@ -42,7 +42,43 @@ pub fn manual_strip_msrv() {
4242
}
4343
}
4444

45+
pub fn redundant_fieldnames() {
46+
let start = 0;
47+
let _ = RangeFrom { start: start };
48+
}
49+
50+
pub fn redundant_static_lifetime() {
51+
const VAR_ONE: &'static str = "Test constant #1";
52+
}
53+
54+
pub fn checked_conversion() {
55+
let value: i64 = 42;
56+
let _ = value <= (u32::max_value() as i64) && value >= 0;
57+
let _ = value <= (u32::MAX as i64) && value >= 0;
58+
}
59+
60+
pub fn filter_map_next() {
61+
let a = ["1", "lol", "3", "NaN", "5"];
62+
63+
#[rustfmt::skip]
64+
let _: Option<u32> = vec![1, 2, 3, 4, 5, 6]
65+
.into_iter()
66+
.filter_map(|x| {
67+
if x == 2 {
68+
Some(x * 2)
69+
} else {
70+
None
71+
}
72+
})
73+
.next();
74+
}
75+
76+
4577
fn main() {
78+
filter_map_next();
79+
checked_conversion();
80+
redundant_fieldnames();
81+
redundant_static_lifetime();
4682
option_as_ref_deref();
4783
match_like_matches();
4884
match_same_arms();

tests/ui/min_rust_version_attr.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
error: stripping a prefix manually
2-
--> $DIR/min_rust_version_attr.rs:60:24
2+
--> $DIR/min_rust_version_attr.rs:96:24
33
|
44
LL | assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
55
| ^^^^^^^^^^^^^^^^^^^^
66
|
77
= note: `-D clippy::manual-strip` implied by `-D warnings`
88
note: the prefix was tested here
9-
--> $DIR/min_rust_version_attr.rs:59:9
9+
--> $DIR/min_rust_version_attr.rs:95:9
1010
|
1111
LL | if s.starts_with("hello, ") {
1212
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,13 +17,13 @@ LL | assert_eq!(<stripped>.to_uppercase(), "WORLD!");
1717
|
1818

1919
error: stripping a prefix manually
20-
--> $DIR/min_rust_version_attr.rs:72:24
20+
--> $DIR/min_rust_version_attr.rs:108:24
2121
|
2222
LL | assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
2323
| ^^^^^^^^^^^^^^^^^^^^
2424
|
2525
note: the prefix was tested here
26-
--> $DIR/min_rust_version_attr.rs:71:9
26+
--> $DIR/min_rust_version_attr.rs:107:9
2727
|
2828
LL | if s.starts_with("hello, ") {
2929
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)