Skip to content

Commit dd78ce7

Browse files
committed
Add Operators lint pass
1 parent b776fb8 commit dd78ce7

File tree

6 files changed

+91
-73
lines changed

6 files changed

+91
-73
lines changed

clippy_lints/src/lib.register_all.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// Manual edits will be overwritten.
44

55
store.register_group(true, "clippy::all", Some("clippy_all"), vec![
6-
LintId::of(absurd_extreme_comparisons::ABSURD_EXTREME_COMPARISONS),
76
LintId::of(almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE),
87
LintId::of(approx_const::APPROX_CONSTANT),
98
LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
@@ -260,6 +259,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
260259
LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
261260
LintId::of(octal_escapes::OCTAL_ESCAPES),
262261
LintId::of(open_options::NONSENSICAL_OPEN_OPTIONS),
262+
LintId::of(operators::ABSURD_EXTREME_COMPARISONS),
263263
LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
264264
LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
265265
LintId::of(partialeq_ne_impl::PARTIALEQ_NE_IMPL),

clippy_lints/src/lib.register_correctness.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// Manual edits will be overwritten.
44

55
store.register_group(true, "clippy::correctness", Some("clippy_correctness"), vec![
6-
LintId::of(absurd_extreme_comparisons::ABSURD_EXTREME_COMPARISONS),
76
LintId::of(approx_const::APPROX_CONSTANT),
87
LintId::of(async_yields_async::ASYNC_YIELDS_ASYNC),
98
LintId::of(attrs::DEPRECATED_SEMVER),
@@ -51,6 +50,7 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve
5150
LintId::of(misc::MODULO_ONE),
5251
LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
5352
LintId::of(open_options::NONSENSICAL_OPEN_OPTIONS),
53+
LintId::of(operators::ABSURD_EXTREME_COMPARISONS),
5454
LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
5555
LintId::of(ptr::INVALID_NULL_PTR_USAGE),
5656
LintId::of(ptr::MUT_FROM_REF),

clippy_lints/src/lib.register_lints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ store.register_lints(&[
3535
utils::internal_lints::PRODUCE_ICE,
3636
#[cfg(feature = "internal")]
3737
utils::internal_lints::UNNECESSARY_SYMBOL_STR,
38-
absurd_extreme_comparisons::ABSURD_EXTREME_COMPARISONS,
3938
almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE,
4039
approx_const::APPROX_CONSTANT,
4140
as_conversions::AS_CONVERSIONS,
@@ -437,6 +436,7 @@ store.register_lints(&[
437436
octal_escapes::OCTAL_ESCAPES,
438437
only_used_in_recursion::ONLY_USED_IN_RECURSION,
439438
open_options::NONSENSICAL_OPEN_OPTIONS,
439+
operators::ABSURD_EXTREME_COMPARISONS,
440440
option_env_unwrap::OPTION_ENV_UNWRAP,
441441
option_if_let_else::OPTION_IF_LET_ELSE,
442442
overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL,

clippy_lints/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,6 @@ mod utils;
168168
mod renamed_lints;
169169

170170
// begin lints modules, do not remove this comment, it’s used in `update_lints`
171-
mod absurd_extreme_comparisons;
172171
mod almost_complete_letter_range;
173172
mod approx_const;
174173
mod as_conversions;
@@ -336,6 +335,7 @@ mod numeric_arithmetic;
336335
mod octal_escapes;
337336
mod only_used_in_recursion;
338337
mod open_options;
338+
mod operators;
339339
mod option_env_unwrap;
340340
mod option_if_let_else;
341341
mod overflow_check_conditional;
@@ -683,7 +683,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
683683
store.register_late_pass(|| Box::new(derivable_impls::DerivableImpls));
684684
store.register_late_pass(|| Box::new(drop_forget_ref::DropForgetRef));
685685
store.register_late_pass(|| Box::new(empty_enum::EmptyEnum));
686-
store.register_late_pass(|| Box::new(absurd_extreme_comparisons::AbsurdExtremeComparisons));
687686
store.register_late_pass(|| Box::new(invalid_upcast_comparisons::InvalidUpcastComparisons));
688687
store.register_late_pass(|| Box::new(regex::Regex));
689688
store.register_late_pass(|| Box::new(copies::CopyAndPaste));
@@ -941,6 +940,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
941940
store.register_late_pass(|| Box::new(default_instead_of_iter_empty::DefaultIterEmpty));
942941
store.register_late_pass(move || Box::new(manual_rem_euclid::ManualRemEuclid::new(msrv)));
943942
store.register_late_pass(move || Box::new(manual_retain::ManualRetain::new(msrv)));
943+
store.register_late_pass(|| Box::new(operators::Operators));
944944
// add lints here, do not remove this comment, it's used in `new_lint`
945945
}
946946

clippy_lints/src/absurd_extreme_comparisons.rs renamed to clippy_lints/src/operators/absurd_extreme_comparisons.rs

Lines changed: 35 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use rustc_hir::{BinOpKind, Expr, ExprKind};
2-
use rustc_lint::{LateContext, LateLintPass};
2+
use rustc_lint::LateContext;
33
use rustc_middle::ty;
4-
use rustc_session::{declare_lint_pass, declare_tool_lint};
54

65
use clippy_utils::comparisons::{normalize_comparison, Rel};
76
use clippy_utils::consts::{constant, Constant};
@@ -10,73 +9,41 @@ use clippy_utils::source::snippet;
109
use clippy_utils::ty::is_isize_or_usize;
1110
use clippy_utils::{clip, int_bits, unsext};
1211

13-
declare_clippy_lint! {
14-
/// ### What it does
15-
/// Checks for comparisons where one side of the relation is
16-
/// either the minimum or maximum value for its type and warns if it involves a
17-
/// case that is always true or always false. Only integer and boolean types are
18-
/// checked.
19-
///
20-
/// ### Why is this bad?
21-
/// An expression like `min <= x` may misleadingly imply
22-
/// that it is possible for `x` to be less than the minimum. Expressions like
23-
/// `max < x` are probably mistakes.
24-
///
25-
/// ### Known problems
26-
/// For `usize` the size of the current compile target will
27-
/// be assumed (e.g., 64 bits on 64 bit systems). This means code that uses such
28-
/// a comparison to detect target pointer width will trigger this lint. One can
29-
/// use `mem::sizeof` and compare its value or conditional compilation
30-
/// attributes
31-
/// like `#[cfg(target_pointer_width = "64")] ..` instead.
32-
///
33-
/// ### Example
34-
/// ```rust
35-
/// let vec: Vec<isize> = Vec::new();
36-
/// if vec.len() <= 0 {}
37-
/// if 100 > i32::MAX {}
38-
/// ```
39-
#[clippy::version = "pre 1.29.0"]
40-
pub ABSURD_EXTREME_COMPARISONS,
41-
correctness,
42-
"a comparison with a maximum or minimum value that is always true or false"
43-
}
12+
use super::ABSURD_EXTREME_COMPARISONS;
4413

45-
declare_lint_pass!(AbsurdExtremeComparisons => [ABSURD_EXTREME_COMPARISONS]);
46-
47-
impl<'tcx> LateLintPass<'tcx> for AbsurdExtremeComparisons {
48-
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
49-
if let ExprKind::Binary(ref cmp, lhs, rhs) = expr.kind {
50-
if let Some((culprit, result)) = detect_absurd_comparison(cx, cmp.node, lhs, rhs) {
51-
if !expr.span.from_expansion() {
52-
let msg = "this comparison involving the minimum or maximum element for this \
53-
type contains a case that is always true or always false";
54-
55-
let conclusion = match result {
56-
AbsurdComparisonResult::AlwaysFalse => "this comparison is always false".to_owned(),
57-
AbsurdComparisonResult::AlwaysTrue => "this comparison is always true".to_owned(),
58-
AbsurdComparisonResult::InequalityImpossible => format!(
59-
"the case where the two sides are not equal never occurs, consider using `{} == {}` \
60-
instead",
61-
snippet(cx, lhs.span, "lhs"),
62-
snippet(cx, rhs.span, "rhs")
63-
),
64-
};
65-
66-
let help = format!(
67-
"because `{}` is the {} value for this type, {}",
68-
snippet(cx, culprit.expr.span, "x"),
69-
match culprit.which {
70-
ExtremeType::Minimum => "minimum",
71-
ExtremeType::Maximum => "maximum",
72-
},
73-
conclusion
74-
);
75-
76-
span_lint_and_help(cx, ABSURD_EXTREME_COMPARISONS, expr.span, msg, None, &help);
77-
}
78-
}
79-
}
14+
pub(super) fn check<'tcx>(
15+
cx: &LateContext<'tcx>,
16+
expr: &'tcx Expr<'_>,
17+
op: BinOpKind,
18+
lhs: &'tcx Expr<'_>,
19+
rhs: &'tcx Expr<'_>,
20+
) {
21+
if let Some((culprit, result)) = detect_absurd_comparison(cx, op, lhs, rhs) {
22+
let msg = "this comparison involving the minimum or maximum element for this \
23+
type contains a case that is always true or always false";
24+
25+
let conclusion = match result {
26+
AbsurdComparisonResult::AlwaysFalse => "this comparison is always false".to_owned(),
27+
AbsurdComparisonResult::AlwaysTrue => "this comparison is always true".to_owned(),
28+
AbsurdComparisonResult::InequalityImpossible => format!(
29+
"the case where the two sides are not equal never occurs, consider using `{} == {}` \
30+
instead",
31+
snippet(cx, lhs.span, "lhs"),
32+
snippet(cx, rhs.span, "rhs")
33+
),
34+
};
35+
36+
let help = format!(
37+
"because `{}` is the {} value for this type, {}",
38+
snippet(cx, culprit.expr.span, "x"),
39+
match culprit.which {
40+
ExtremeType::Minimum => "minimum",
41+
ExtremeType::Maximum => "maximum",
42+
},
43+
conclusion
44+
);
45+
46+
span_lint_and_help(cx, ABSURD_EXTREME_COMPARISONS, expr.span, msg, None, &help);
8047
}
8148
}
8249

clippy_lints/src/operators/mod.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use rustc_hir::{Expr, ExprKind};
2+
use rustc_lint::{LateContext, LateLintPass};
3+
use rustc_session::{declare_tool_lint, impl_lint_pass};
4+
5+
mod absurd_extreme_comparisons;
6+
7+
declare_clippy_lint! {
8+
/// ### What it does
9+
/// Checks for comparisons where one side of the relation is
10+
/// either the minimum or maximum value for its type and warns if it involves a
11+
/// case that is always true or always false. Only integer and boolean types are
12+
/// checked.
13+
///
14+
/// ### Why is this bad?
15+
/// An expression like `min <= x` may misleadingly imply
16+
/// that it is possible for `x` to be less than the minimum. Expressions like
17+
/// `max < x` are probably mistakes.
18+
///
19+
/// ### Known problems
20+
/// For `usize` the size of the current compile target will
21+
/// be assumed (e.g., 64 bits on 64 bit systems). This means code that uses such
22+
/// a comparison to detect target pointer width will trigger this lint. One can
23+
/// use `mem::sizeof` and compare its value or conditional compilation
24+
/// attributes
25+
/// like `#[cfg(target_pointer_width = "64")] ..` instead.
26+
///
27+
/// ### Example
28+
/// ```rust
29+
/// let vec: Vec<isize> = Vec::new();
30+
/// if vec.len() <= 0 {}
31+
/// if 100 > i32::MAX {}
32+
/// ```
33+
#[clippy::version = "pre 1.29.0"]
34+
pub ABSURD_EXTREME_COMPARISONS,
35+
correctness,
36+
"a comparison with a maximum or minimum value that is always true or false"
37+
}
38+
39+
pub struct Operators;
40+
impl_lint_pass!(Operators => [
41+
ABSURD_EXTREME_COMPARISONS,
42+
]);
43+
impl<'tcx> LateLintPass<'tcx> for Operators {
44+
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
45+
if let ExprKind::Binary(op, lhs, rhs) = e.kind {
46+
if !e.span.from_expansion() {
47+
absurd_extreme_comparisons::check(cx, e, op.node, lhs, rhs);
48+
}
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)