Skip to content

Commit dbd1a28

Browse files
committed
Add Operators lint pass
1 parent 5b1a4c0 commit dbd1a28

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),
@@ -253,6 +252,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
253252
LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
254253
LintId::of(octal_escapes::OCTAL_ESCAPES),
255254
LintId::of(open_options::NONSENSICAL_OPEN_OPTIONS),
255+
LintId::of(operators::ABSURD_EXTREME_COMPARISONS),
256256
LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
257257
LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
258258
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
@@ -33,7 +33,6 @@ store.register_lints(&[
3333
utils::internal_lints::PRODUCE_ICE,
3434
#[cfg(feature = "internal")]
3535
utils::internal_lints::UNNECESSARY_SYMBOL_STR,
36-
absurd_extreme_comparisons::ABSURD_EXTREME_COMPARISONS,
3736
almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE,
3837
approx_const::APPROX_CONSTANT,
3938
arithmetic::FLOAT_ARITHMETIC,
@@ -425,6 +424,7 @@ store.register_lints(&[
425424
octal_escapes::OCTAL_ESCAPES,
426425
only_used_in_recursion::ONLY_USED_IN_RECURSION,
427426
open_options::NONSENSICAL_OPEN_OPTIONS,
427+
operators::ABSURD_EXTREME_COMPARISONS,
428428
option_env_unwrap::OPTION_ENV_UNWRAP,
429429
option_if_let_else::OPTION_IF_LET_ELSE,
430430
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
@@ -167,7 +167,6 @@ mod utils;
167167
mod renamed_lints;
168168

169169
// begin lints modules, do not remove this comment, it’s used in `update_lints`
170-
mod absurd_extreme_comparisons;
171170
mod almost_complete_letter_range;
172171
mod approx_const;
173172
mod arithmetic;
@@ -333,6 +332,7 @@ mod nonstandard_macro_braces;
333332
mod octal_escapes;
334333
mod only_used_in_recursion;
335334
mod open_options;
335+
mod operators;
336336
mod option_env_unwrap;
337337
mod option_if_let_else;
338338
mod overflow_check_conditional;
@@ -657,7 +657,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
657657
store.register_late_pass(|| Box::new(derivable_impls::DerivableImpls));
658658
store.register_late_pass(|| Box::new(drop_forget_ref::DropForgetRef));
659659
store.register_late_pass(|| Box::new(empty_enum::EmptyEnum));
660-
store.register_late_pass(|| Box::new(absurd_extreme_comparisons::AbsurdExtremeComparisons));
661660
store.register_late_pass(|| Box::new(invalid_upcast_comparisons::InvalidUpcastComparisons));
662661
store.register_late_pass(|| Box::new(regex::Regex));
663662
store.register_late_pass(|| Box::new(copies::CopyAndPaste));
@@ -913,6 +912,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
913912
store.register_late_pass(|| Box::new(get_first::GetFirst));
914913
store.register_early_pass(|| Box::new(unused_rounding::UnusedRounding));
915914
store.register_early_pass(move || Box::new(almost_complete_letter_range::AlmostCompleteLetterRange::new(msrv)));
915+
store.register_late_pass(|| Box::new(operators::Operators));
916916
// add lints here, do not remove this comment, it's used in `new_lint`
917917
}
918918

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)