Skip to content

Commit a7cfffe

Browse files
committed
add MSRV to more lints specified in rust-lang#6097
update tests
1 parent b02b0c7 commit a7cfffe

11 files changed

+282
-68
lines changed

clippy_lints/src/checked_conversions.rs

+23-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::{declare_tool_lint, impl_lint_pass};
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,25 @@ 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+
if !meets_msrv(self.msrv.as_ref(), &CHECKED_CONVERSIONS_MSRV) {
61+
return;
62+
}
63+
4664
let result = if_chain! {
4765
if !in_external_macro(cx.sess(), item.span);
4866
if let ExprKind::Binary(op, ref left, ref right) = &item.kind;
@@ -74,6 +92,8 @@ impl<'tcx> LateLintPass<'tcx> for CheckedConversions {
7492
}
7593
}
7694
}
95+
96+
extract_msrv_attr!(LateContext);
7797
}
7898

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

clippy_lints/src/lib.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,14 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10031003
store.register_late_pass(move || box matches::Matches::new(msrv));
10041004
store.register_early_pass(move || box manual_non_exhaustive::ManualNonExhaustive::new(msrv));
10051005
store.register_late_pass(move || box manual_strip::ManualStrip::new(msrv));
1006+
store.register_early_pass(move || box redundant_static_lifetimes::RedundantStaticLifetimes::new(msrv));
1007+
store.register_early_pass(move || box redundant_field_names::RedundantFieldNames::new(msrv));
1008+
store.register_late_pass(move || box checked_conversions::CheckedConversions::new(msrv));
1009+
store.register_late_pass(move || box mem_replace::MemReplace::new(msrv));
1010+
store.register_late_pass(move || box ranges::Ranges::new(msrv));
1011+
store.register_late_pass(move || box use_self::UseSelf::new(msrv));
1012+
store.register_late_pass(move || box missing_const_for_fn::MissingConstForFn::new(msrv));
1013+
10061014
store.register_late_pass(|| box size_of_in_element_count::SizeOfInElementCount);
10071015
store.register_late_pass(|| box map_clone::MapClone);
10081016
store.register_late_pass(|| box map_err_ignore::MapErrIgnore);
@@ -1013,7 +1021,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10131021
store.register_late_pass(|| box main_recursion::MainRecursion::default());
10141022
store.register_late_pass(|| box lifetimes::Lifetimes);
10151023
store.register_late_pass(|| box entry::HashMapPass);
1016-
store.register_late_pass(|| box ranges::Ranges);
10171024
store.register_late_pass(|| box types::Casts);
10181025
let type_complexity_threshold = conf.type_complexity_threshold;
10191026
store.register_late_pass(move || box types::TypeComplexity::new(type_complexity_threshold));
@@ -1058,7 +1065,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10581065
store.register_late_pass(|| box neg_multiply::NegMultiply);
10591066
store.register_late_pass(|| box mem_discriminant::MemDiscriminant);
10601067
store.register_late_pass(|| box mem_forget::MemForget);
1061-
store.register_late_pass(|| box mem_replace::MemReplace);
10621068
store.register_late_pass(|| box arithmetic::Arithmetic::default());
10631069
store.register_late_pass(|| box assign_ops::AssignOps);
10641070
store.register_late_pass(|| box let_if_seq::LetIfSeq);
@@ -1080,7 +1086,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10801086
store.register_late_pass(move || box pass_by_ref_or_value);
10811087
store.register_late_pass(|| box ref_option_ref::RefOptionRef);
10821088
store.register_late_pass(|| box try_err::TryErr);
1083-
store.register_late_pass(|| box use_self::UseSelf);
10841089
store.register_late_pass(|| box bytecount::ByteCount);
10851090
store.register_late_pass(|| box infinite_iter::InfiniteIter);
10861091
store.register_late_pass(|| box inline_fn_without_body::InlineFnWithoutBody);
@@ -1106,10 +1111,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
11061111
store.register_late_pass(|| box unnecessary_wraps::UnnecessaryWraps);
11071112
store.register_late_pass(|| box types::RefToMut);
11081113
store.register_late_pass(|| box assertions_on_constants::AssertionsOnConstants);
1109-
store.register_late_pass(|| box missing_const_for_fn::MissingConstForFn);
11101114
store.register_late_pass(|| box transmuting_null::TransmutingNull);
11111115
store.register_late_pass(|| box path_buf_push_overwrite::PathBufPushOverwrite);
1112-
store.register_late_pass(|| box checked_conversions::CheckedConversions);
11131116
store.register_late_pass(|| box integer_division::IntegerDivision);
11141117
store.register_late_pass(|| box inherent_to_string::InherentToString);
11151118
let max_trait_bounds = conf.max_trait_bounds;
@@ -1138,7 +1141,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
11381141
store.register_early_pass(|| box redundant_else::RedundantElse);
11391142
store.register_late_pass(|| box create_dir::CreateDir);
11401143
store.register_early_pass(|| box needless_arbitrary_self_type::NeedlessArbitrarySelfType);
1141-
store.register_early_pass(|| box redundant_static_lifetimes::RedundantStaticLifetimes);
11421144
store.register_late_pass(|| box cargo_common_metadata::CargoCommonMetadata);
11431145
store.register_late_pass(|| box multiple_crate_versions::MultipleCrateVersions);
11441146
store.register_late_pass(|| box wildcard_dependencies::WildcardDependencies);
@@ -1178,7 +1180,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
11781180
store.register_late_pass(|| box mut_mutex_lock::MutMutexLock);
11791181
store.register_late_pass(|| box match_on_vec_items::MatchOnVecItems);
11801182
store.register_late_pass(|| box manual_async_fn::ManualAsyncFn);
1181-
store.register_early_pass(|| box redundant_field_names::RedundantFieldNames);
11821183
store.register_late_pass(|| box vec_resize_to_zero::VecResizeToZero);
11831184
store.register_late_pass(|| box panic_in_result_fn::PanicInResultFn);
11841185
let single_char_binding_names_threshold = conf.single_char_binding_names_threshold;

clippy_lints/src/mem_replace.rs

+22-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use crate::utils::{
2-
in_macro, match_def_path, match_qpath, paths, snippet, snippet_with_applicability, span_lint_and_help,
2+
in_macro, match_def_path, match_qpath, meets_msrv, paths, snippet, snippet_with_applicability, span_lint_and_help,
33
span_lint_and_sugg, span_lint_and_then,
44
};
55
use if_chain::if_chain;
66
use rustc_errors::Applicability;
77
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, QPath};
8-
use rustc_lint::{LateContext, LateLintPass};
8+
use rustc_lint::{LateContext, LateLintPass, LintContext};
99
use rustc_middle::lint::in_external_macro;
10-
use rustc_session::{declare_lint_pass, declare_tool_lint};
10+
use rustc_semver::RustcVersion;
11+
use rustc_session::{declare_tool_lint, impl_lint_pass};
1112
use rustc_span::source_map::Span;
1213
use rustc_span::symbol::sym;
1314

@@ -94,7 +95,7 @@ declare_clippy_lint! {
9495
"replacing a value of type `T` with `T::default()` instead of using `std::mem::take`"
9596
}
9697

97-
declare_lint_pass!(MemReplace =>
98+
impl_lint_pass!(MemReplace =>
9899
[MEM_REPLACE_OPTION_WITH_NONE, MEM_REPLACE_WITH_UNINIT, MEM_REPLACE_WITH_DEFAULT]);
99100

100101
fn check_replace_option_with_none(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'_>, expr_span: Span) {
@@ -224,6 +225,19 @@ fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<
224225
}
225226
}
226227

228+
const MEM_REPLACE_WITH_DEFAULT_MSRV: RustcVersion = RustcVersion::new(1, 40, 0);
229+
230+
pub struct MemReplace {
231+
msrv: Option<RustcVersion>,
232+
}
233+
234+
impl MemReplace {
235+
#[must_use]
236+
pub fn new(msrv: Option<RustcVersion>) -> Self {
237+
Self { msrv }
238+
}
239+
}
240+
227241
impl<'tcx> LateLintPass<'tcx> for MemReplace {
228242
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
229243
if_chain! {
@@ -236,8 +250,11 @@ impl<'tcx> LateLintPass<'tcx> for MemReplace {
236250
then {
237251
check_replace_option_with_none(cx, src, dest, expr.span);
238252
check_replace_with_uninit(cx, src, dest, expr.span);
239-
check_replace_with_default(cx, src, dest, expr.span);
253+
if meets_msrv(self.msrv.as_ref(), &MEM_REPLACE_WITH_DEFAULT_MSRV) {
254+
check_replace_with_default(cx, src, dest, expr.span);
255+
}
240256
}
241257
}
242258
}
259+
extract_msrv_attr!(LateContext);
243260
}

clippy_lints/src/methods/mod.rs

+20-3
Original file line numberDiff line numberDiff line change
@@ -1487,7 +1487,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
14871487
["expect", ..] => lint_expect(cx, expr, arg_lists[0]),
14881488
["unwrap_or", "map"] => option_map_unwrap_or::lint(cx, expr, arg_lists[1], arg_lists[0], method_spans[1]),
14891489
["unwrap_or_else", "map"] => {
1490-
if !lint_map_unwrap_or_else(cx, expr, arg_lists[1], arg_lists[0]) {
1490+
if !lint_map_unwrap_or_else(cx, expr, arg_lists[1], arg_lists[0], self.msrv.as_ref()) {
14911491
unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "unwrap_or");
14921492
}
14931493
},
@@ -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]),
@@ -2733,14 +2733,20 @@ fn lint_map_flatten<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, map
27332733
}
27342734
}
27352735

2736+
const MAP_UNWRAP_OR_MSRV: RustcVersion = RustcVersion::new(1, 41, 0);
2737+
27362738
/// lint use of `map().unwrap_or_else()` for `Option`s and `Result`s
27372739
/// Return true if lint triggered
27382740
fn lint_map_unwrap_or_else<'tcx>(
27392741
cx: &LateContext<'tcx>,
27402742
expr: &'tcx hir::Expr<'_>,
27412743
map_args: &'tcx [hir::Expr<'_>],
27422744
unwrap_args: &'tcx [hir::Expr<'_>],
2745+
msrv: Option<&RustcVersion>,
27432746
) -> bool {
2747+
if !meets_msrv(msrv, &MAP_UNWRAP_OR_MSRV) {
2748+
return false;
2749+
}
27442750
// lint if the caller of `map()` is an `Option`
27452751
let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_args[0]), sym::option_type);
27462752
let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(&map_args[0]), sym::result_type);
@@ -2923,9 +2929,20 @@ fn lint_filter_map<'tcx>(
29232929
}
29242930
}
29252931

2932+
const FILTER_MAP_NEXT_MSRV: RustcVersion = RustcVersion::new(1, 30, 0);
2933+
29262934
/// 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<'_>]) {
2935+
fn lint_filter_map_next<'tcx>(
2936+
cx: &LateContext<'tcx>,
2937+
expr: &'tcx hir::Expr<'_>,
2938+
filter_args: &'tcx [hir::Expr<'_>],
2939+
msrv: Option<&RustcVersion>,
2940+
) {
29282941
if match_trait_method(cx, expr, &paths::ITERATOR) {
2942+
if !meets_msrv(msrv, &FILTER_MAP_NEXT_MSRV) {
2943+
return;
2944+
}
2945+
29292946
let msg = "called `filter_map(..).next()` on an `Iterator`. This is more succinctly expressed by calling \
29302947
`.find_map(..)` instead.";
29312948
let filter_snippet = snippet(cx, filter_args[1].span, "..");

clippy_lints/src/missing_const_for_fn.rs

+25-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
use crate::utils::qualify_min_const_fn::is_min_const_fn;
2-
use crate::utils::{fn_has_unsatisfiable_preds, has_drop, is_entrypoint_fn, span_lint, trait_ref_of_method};
2+
use crate::utils::{
3+
fn_has_unsatisfiable_preds, has_drop, is_entrypoint_fn, meets_msrv, span_lint, trait_ref_of_method,
4+
};
35
use rustc_hir as hir;
46
use rustc_hir::intravisit::FnKind;
57
use rustc_hir::{Body, Constness, FnDecl, GenericParamKind, HirId};
6-
use rustc_lint::{LateContext, LateLintPass};
8+
use rustc_lint::{LateContext, LateLintPass, LintContext};
79
use rustc_middle::lint::in_external_macro;
8-
use rustc_session::{declare_lint_pass, declare_tool_lint};
10+
use rustc_semver::RustcVersion;
11+
use rustc_session::{declare_tool_lint, impl_lint_pass};
912
use rustc_span::Span;
1013
use rustc_typeck::hir_ty_to_ty;
1114

15+
const MISSING_CONST_FOR_FN_MSRV: RustcVersion = RustcVersion::new(1, 37, 0);
16+
1217
declare_clippy_lint! {
1318
/// **What it does:**
1419
///
@@ -69,7 +74,18 @@ declare_clippy_lint! {
6974
"Lint functions definitions that could be made `const fn`"
7075
}
7176

72-
declare_lint_pass!(MissingConstForFn => [MISSING_CONST_FOR_FN]);
77+
impl_lint_pass!(MissingConstForFn => [MISSING_CONST_FOR_FN]);
78+
79+
pub struct MissingConstForFn {
80+
msrv: Option<RustcVersion>,
81+
}
82+
83+
impl MissingConstForFn {
84+
#[must_use]
85+
pub fn new(msrv: Option<RustcVersion>) -> Self {
86+
Self { msrv }
87+
}
88+
}
7389

7490
impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
7591
fn check_fn(
@@ -81,6 +97,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
8197
span: Span,
8298
hir_id: HirId,
8399
) {
100+
if !meets_msrv(self.msrv.as_ref(), &MISSING_CONST_FOR_FN_MSRV) {
101+
return;
102+
}
103+
84104
let def_id = cx.tcx.hir().local_def_id(hir_id);
85105

86106
if in_external_macro(cx.tcx.sess, span) || is_entrypoint_fn(cx, def_id.to_def_id()) {
@@ -126,6 +146,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
126146
span_lint(cx, MISSING_CONST_FOR_FN, span, "this could be a `const fn`");
127147
}
128148
}
149+
extract_msrv_attr!(LateContext);
129150
}
130151

131152
/// Returns true if any of the method parameters is a type that implements `Drop`. The method

clippy_lints/src/ranges.rs

+23-6
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@ use if_chain::if_chain;
33
use rustc_ast::ast::RangeLimits;
44
use rustc_errors::Applicability;
55
use rustc_hir::{BinOpKind, Expr, ExprKind, PathSegment, QPath};
6-
use rustc_lint::{LateContext, LateLintPass};
6+
use rustc_lint::{LateContext, LateLintPass, LintContext};
77
use rustc_middle::ty;
8-
use rustc_session::{declare_lint_pass, declare_tool_lint};
8+
use rustc_semver::RustcVersion;
9+
use rustc_session::{declare_tool_lint, impl_lint_pass};
910
use rustc_span::source_map::{Span, Spanned};
1011
use rustc_span::sym;
1112
use rustc_span::symbol::Ident;
1213
use std::cmp::Ordering;
1314

1415
use crate::utils::sugg::Sugg;
1516
use crate::utils::{
16-
get_parent_expr, is_integer_const, single_segment_path, snippet, snippet_opt, snippet_with_applicability,
17-
span_lint, span_lint_and_sugg, span_lint_and_then,
17+
get_parent_expr, is_integer_const, meets_msrv, single_segment_path, snippet, snippet_opt,
18+
snippet_with_applicability, span_lint, span_lint_and_sugg, span_lint_and_then,
1819
};
1920
use crate::utils::{higher, SpanlessEq};
2021

@@ -160,7 +161,20 @@ declare_clippy_lint! {
160161
"manually reimplementing {`Range`, `RangeInclusive`}`::contains`"
161162
}
162163

163-
declare_lint_pass!(Ranges => [
164+
const MANUAL_RANGE_CONTAINS_MSRV: RustcVersion = RustcVersion::new(1, 35, 0);
165+
166+
pub struct Ranges {
167+
msrv: Option<RustcVersion>,
168+
}
169+
170+
impl Ranges {
171+
#[must_use]
172+
pub fn new(msrv: Option<RustcVersion>) -> Self {
173+
Self { msrv }
174+
}
175+
}
176+
177+
impl_lint_pass!(Ranges => [
164178
RANGE_ZIP_WITH_LEN,
165179
RANGE_PLUS_ONE,
166180
RANGE_MINUS_ONE,
@@ -175,7 +189,9 @@ impl<'tcx> LateLintPass<'tcx> for Ranges {
175189
check_range_zip_with_len(cx, path, args, expr.span);
176190
},
177191
ExprKind::Binary(ref op, ref l, ref r) => {
178-
check_possible_range_contains(cx, op.node, l, r, expr.span);
192+
if meets_msrv(self.msrv.as_ref(), &MANUAL_RANGE_CONTAINS_MSRV) {
193+
check_possible_range_contains(cx, op.node, l, r, expr.span);
194+
}
179195
},
180196
_ => {},
181197
}
@@ -184,6 +200,7 @@ impl<'tcx> LateLintPass<'tcx> for Ranges {
184200
check_inclusive_range_minus_one(cx, expr);
185201
check_reversed_empty_range(cx, expr);
186202
}
203+
extract_msrv_attr!(LateContext);
187204
}
188205

189206
fn check_possible_range_contains(cx: &LateContext<'_>, op: BinOpKind, l: &Expr<'_>, r: &Expr<'_>, span: Span) {

0 commit comments

Comments
 (0)