Skip to content

Commit 68bb900

Browse files
authored
Merge pull request #3473 from lucasloisp/additional-bool-comparisons
Adds inequality cases to bool comparison (#3438)
2 parents 8b2eb06 + 3930148 commit 68bb900

File tree

3 files changed

+95
-65
lines changed

3 files changed

+95
-65
lines changed

clippy_lints/src/needless_bool.rs

+66-64
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::rustc_errors::Applicability;
1818
use crate::syntax::ast::LitKind;
1919
use crate::syntax::source_map::Spanned;
2020
use crate::utils::sugg::Sugg;
21-
use crate::utils::{in_macro, snippet_with_applicability, span_lint, span_lint_and_sugg};
21+
use crate::utils::{in_macro, span_lint, span_lint_and_sugg};
2222

2323
/// **What it does:** Checks for expressions of the form `if c { true } else {
2424
/// false }`
@@ -45,8 +45,8 @@ declare_clippy_lint! {
4545
"if-statements with plain booleans in the then- and else-clause, e.g. `if p { true } else { false }`"
4646
}
4747

48-
/// **What it does:** Checks for expressions of the form `x == true` (or vice
49-
/// versa) and suggest using the variable directly.
48+
/// **What it does:** Checks for expressions of the form `x == true` and
49+
/// `x != true` (or vice versa) and suggest using the variable directly.
5050
///
5151
/// **Why is this bad?** Unnecessary code.
5252
///
@@ -59,7 +59,7 @@ declare_clippy_lint! {
5959
declare_clippy_lint! {
6060
pub BOOL_COMPARISON,
6161
complexity,
62-
"comparing a variable to a boolean, e.g. `if x == true`"
62+
"comparing a variable to a boolean, e.g. `if x == true` or `if x != true`"
6363
}
6464

6565
#[derive(Copy, Clone)]
@@ -138,76 +138,78 @@ impl LintPass for BoolComparison {
138138

139139
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison {
140140
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
141-
use self::Expression::*;
142-
143141
if in_macro(e.span) {
144142
return;
145143
}
146144

147-
if let ExprKind::Binary(
148-
Spanned {
149-
node: BinOpKind::Eq, ..
150-
},
151-
ref left_side,
152-
ref right_side,
153-
) = e.node
154-
{
155-
let mut applicability = Applicability::MachineApplicable;
156-
match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
157-
(Bool(true), Other) => {
158-
let hint = snippet_with_applicability(cx, right_side.span, "..", &mut applicability);
159-
span_lint_and_sugg(
160-
cx,
161-
BOOL_COMPARISON,
162-
e.span,
163-
"equality checks against true are unnecessary",
164-
"try simplifying it as shown",
165-
hint.to_string(),
166-
applicability,
167-
);
168-
},
169-
(Other, Bool(true)) => {
170-
let hint = snippet_with_applicability(cx, left_side.span, "..", &mut applicability);
171-
span_lint_and_sugg(
172-
cx,
173-
BOOL_COMPARISON,
174-
e.span,
175-
"equality checks against true are unnecessary",
176-
"try simplifying it as shown",
177-
hint.to_string(),
178-
applicability,
179-
);
180-
},
181-
(Bool(false), Other) => {
182-
let hint = Sugg::hir_with_applicability(cx, right_side, "..", &mut applicability);
183-
span_lint_and_sugg(
184-
cx,
185-
BOOL_COMPARISON,
186-
e.span,
187-
"equality checks against false can be replaced by a negation",
188-
"try simplifying it as shown",
189-
(!hint).to_string(),
190-
applicability,
191-
);
192-
},
193-
(Other, Bool(false)) => {
194-
let hint = Sugg::hir_with_applicability(cx, left_side, "..", &mut applicability);
195-
span_lint_and_sugg(
196-
cx,
197-
BOOL_COMPARISON,
198-
e.span,
199-
"equality checks against false can be replaced by a negation",
200-
"try simplifying it as shown",
201-
(!hint).to_string(),
202-
applicability,
203-
);
204-
},
145+
if let ExprKind::Binary(Spanned { node, .. }, ..) = e.node {
146+
match node {
147+
BinOpKind::Eq => check_comparison(
148+
cx,
149+
e,
150+
"equality checks against true are unnecessary",
151+
"equality checks against false can be replaced by a negation",
152+
|h| h,
153+
|h| !h,
154+
),
155+
BinOpKind::Ne => check_comparison(
156+
cx,
157+
e,
158+
"inequality checks against true can be replaced by a negation",
159+
"inequality checks against false are unnecessary",
160+
|h| !h,
161+
|h| h,
162+
),
205163
_ => (),
206164
}
207165
}
208166
}
209167
}
210168

169+
fn check_comparison<'a, 'tcx>(
170+
cx: &LateContext<'a, 'tcx>,
171+
e: &'tcx Expr,
172+
true_message: &str,
173+
false_message: &str,
174+
true_hint: impl FnOnce(Sugg<'_>) -> Sugg<'_>,
175+
false_hint: impl FnOnce(Sugg<'_>) -> Sugg<'_>,
176+
) {
177+
use self::Expression::*;
178+
179+
if let ExprKind::Binary(_, ref left_side, ref right_side) = e.node {
180+
let applicability = Applicability::MachineApplicable;
181+
match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
182+
(Bool(true), Other) => suggest_bool_comparison(cx, e, right_side, applicability, true_message, true_hint),
183+
(Other, Bool(true)) => suggest_bool_comparison(cx, e, left_side, applicability, true_message, true_hint),
184+
(Bool(false), Other) => {
185+
suggest_bool_comparison(cx, e, right_side, applicability, false_message, false_hint)
186+
},
187+
(Other, Bool(false)) => suggest_bool_comparison(cx, e, left_side, applicability, false_message, false_hint),
188+
_ => (),
189+
}
190+
}
191+
}
192+
193+
fn suggest_bool_comparison<'a, 'tcx>(
194+
cx: &LateContext<'a, 'tcx>,
195+
e: &'tcx Expr,
196+
expr: &Expr,
197+
mut applicability: Applicability,
198+
message: &str,
199+
conv_hint: impl FnOnce(Sugg<'_>) -> Sugg<'_>,
200+
) {
201+
let hint = Sugg::hir_with_applicability(cx, expr, "..", &mut applicability);
202+
span_lint_and_sugg(
203+
cx,
204+
BOOL_COMPARISON,
205+
e.span,
206+
message,
207+
"try simplifying it as shown",
208+
conv_hint(hint).to_string(),
209+
applicability,
210+
);
211+
}
212+
211213
enum Expression {
212214
Bool(bool),
213215
RetBool(bool),

tests/ui/bool_comparison.rs

+4
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@ fn main() {
1818
if x == false { "yes" } else { "no" };
1919
if true == x { "yes" } else { "no" };
2020
if false == x { "yes" } else { "no" };
21+
if x != true { "yes" } else { "no" };
22+
if x != false { "yes" } else { "no" };
23+
if true != x { "yes" } else { "no" };
24+
if false != x { "yes" } else { "no" };
2125
}

tests/ui/bool_comparison.stderr

+25-1
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,29 @@ error: equality checks against false can be replaced by a negation
2424
20 | if false == x { "yes" } else { "no" };
2525
| ^^^^^^^^^^ help: try simplifying it as shown: `!x`
2626

27-
error: aborting due to 4 previous errors
27+
error: inequality checks against true can be replaced by a negation
28+
--> $DIR/bool_comparison.rs:21:8
29+
|
30+
21 | if x != true { "yes" } else { "no" };
31+
| ^^^^^^^^^ help: try simplifying it as shown: `!x`
32+
33+
error: inequality checks against false are unnecessary
34+
--> $DIR/bool_comparison.rs:22:8
35+
|
36+
22 | if x != false { "yes" } else { "no" };
37+
| ^^^^^^^^^^ help: try simplifying it as shown: `x`
38+
39+
error: inequality checks against true can be replaced by a negation
40+
--> $DIR/bool_comparison.rs:23:8
41+
|
42+
23 | if true != x { "yes" } else { "no" };
43+
| ^^^^^^^^^ help: try simplifying it as shown: `!x`
44+
45+
error: inequality checks against false are unnecessary
46+
--> $DIR/bool_comparison.rs:24:8
47+
|
48+
24 | if false != x { "yes" } else { "no" };
49+
| ^^^^^^^^^^ help: try simplifying it as shown: `x`
50+
51+
error: aborting due to 8 previous errors
2852

0 commit comments

Comments
 (0)