Skip to content

Commit 1013026

Browse files
committed
Merge branch 'pr-645'
2 parents 93461af + 7e06737 commit 1013026

File tree

4 files changed

+102
-2
lines changed

4 files changed

+102
-2
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ A collection of lints to catch common mistakes and improve your Rust code.
66
[Jump to usage instructions](#usage)
77

88
##Lints
9-
There are 117 lints included in this crate:
9+
There are 118 lints included in this crate:
1010

1111
name | default | meaning
1212
---------------------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -15,6 +15,7 @@ name
1515
[bad_bit_mask](https://github.com/Manishearth/rust-clippy/wiki#bad_bit_mask) | warn | expressions of the form `_ & mask == select` that will only ever return `true` or `false` (because in the example `select` containing bits that `mask` doesn't have)
1616
[block_in_if_condition_expr](https://github.com/Manishearth/rust-clippy/wiki#block_in_if_condition_expr) | warn | braces can be eliminated in conditions that are expressions, e.g `if { true } ...`
1717
[block_in_if_condition_stmt](https://github.com/Manishearth/rust-clippy/wiki#block_in_if_condition_stmt) | warn | avoid complex blocks in conditions, instead move the block higher and bind it with 'let'; e.g: `if { let x = true; x } ...`
18+
[bool_comparison](https://github.com/Manishearth/rust-clippy/wiki#bool_comparison) | warn | comparing a variable to a boolean, e.g. `if x == true`
1819
[box_vec](https://github.com/Manishearth/rust-clippy/wiki#box_vec) | warn | usage of `Box<Vec<T>>`, vector elements are already on the heap
1920
[boxed_local](https://github.com/Manishearth/rust-clippy/wiki#boxed_local) | warn | using Box<T> where unnecessary
2021
[cast_possible_truncation](https://github.com/Manishearth/rust-clippy/wiki#cast_possible_truncation) | allow | casts that may cause truncation of the value, e.g `x as u8` where `x: u32`, or `x as i32` where `x: f32`

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
105105
reg.register_late_lint_pass(box bit_mask::BitMask);
106106
reg.register_late_lint_pass(box ptr_arg::PtrArg);
107107
reg.register_late_lint_pass(box needless_bool::NeedlessBool);
108+
reg.register_late_lint_pass(box needless_bool::BoolComparison);
108109
reg.register_late_lint_pass(box approx_const::ApproxConstant);
109110
reg.register_late_lint_pass(box misc::FloatCmp);
110111
reg.register_early_lint_pass(box precedence::Precedence);
@@ -252,6 +253,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
252253
misc_early::UNNEEDED_FIELD_PATTERN,
253254
mut_reference::UNNECESSARY_MUT_PASSED,
254255
mutex_atomic::MUTEX_ATOMIC,
256+
needless_bool::BOOL_COMPARISON,
255257
needless_bool::NEEDLESS_BOOL,
256258
needless_features::UNSTABLE_AS_MUT_SLICE,
257259
needless_features::UNSTABLE_AS_SLICE,

src/needless_bool.rs

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ use rustc::lint::*;
66
use rustc_front::hir::*;
77

88
use syntax::ast::Lit_;
9+
use syntax::codemap::Spanned;
910

10-
use utils::{span_lint, snippet};
11+
use utils::{span_lint, span_lint_and_then, snippet};
1112

1213
/// **What it does:** This lint checks for expressions of the form `if c { true } else { false }` (or vice versa) and suggest using the condition directly.
1314
///
@@ -23,6 +24,20 @@ declare_lint! {
2324
`if p { true } else { false }`"
2425
}
2526

27+
/// **What it does:** This lint checks for expressions of the form `x == true` (or vice versa) and suggest using the variable directly.
28+
///
29+
/// **Why is this bad?** Unnecessary code.
30+
///
31+
/// **Known problems:** None.
32+
///
33+
/// **Example:** `if x == true { }` could be `if x { }`
34+
declare_lint! {
35+
pub BOOL_COMPARISON,
36+
Warn,
37+
"comparing a variable to a boolean, e.g. \
38+
`if x == true`"
39+
}
40+
2641
#[derive(Copy,Clone)]
2742
pub struct NeedlessBool;
2843

@@ -78,6 +93,65 @@ impl LateLintPass for NeedlessBool {
7893
}
7994
}
8095

96+
#[derive(Copy,Clone)]
97+
pub struct BoolComparison;
98+
99+
impl LintPass for BoolComparison {
100+
fn get_lints(&self) -> LintArray {
101+
lint_array!(BOOL_COMPARISON)
102+
}
103+
}
104+
105+
impl LateLintPass for BoolComparison {
106+
fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
107+
if let ExprBinary(Spanned{ node: BiEq, .. }, ref left_side, ref right_side) = e.node {
108+
match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
109+
(Some(true), None) => {
110+
let hint = snippet(cx, right_side.span, "..").into_owned();
111+
span_lint_and_then(cx,
112+
BOOL_COMPARISON,
113+
e.span,
114+
"equality checks against true are unnecesary",
115+
|db| {
116+
db.span_suggestion(e.span, "try simplifying it as shown:", hint);
117+
});
118+
}
119+
(None, Some(true)) => {
120+
let hint = snippet(cx, left_side.span, "..").into_owned();
121+
span_lint_and_then(cx,
122+
BOOL_COMPARISON,
123+
e.span,
124+
"equality checks against true are unnecesary",
125+
|db| {
126+
db.span_suggestion(e.span, "try simplifying it as shown:", hint);
127+
});
128+
}
129+
(Some(false), None) => {
130+
let hint = format!("!{}", snippet(cx, right_side.span, ".."));
131+
span_lint_and_then(cx,
132+
BOOL_COMPARISON,
133+
e.span,
134+
"equality checks against false can be replaced by a negation",
135+
|db| {
136+
db.span_suggestion(e.span, "try simplifying it as shown:", hint);
137+
});
138+
}
139+
(None, Some(false)) => {
140+
let hint = format!("!{}", snippet(cx, left_side.span, ".."));
141+
span_lint_and_then(cx,
142+
BOOL_COMPARISON,
143+
e.span,
144+
"equality checks against false can be replaced by a negation",
145+
|db| {
146+
db.span_suggestion(e.span, "try simplifying it as shown:", hint);
147+
});
148+
}
149+
_ => (),
150+
}
151+
}
152+
}
153+
}
154+
81155
fn fetch_bool_block(block: &Block) -> Option<bool> {
82156
if block.stmts.is_empty() {
83157
block.expr.as_ref().and_then(|e| fetch_bool_expr(e))

tests/compile-fail/bool_comparison.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#![feature(plugin)]
2+
#![plugin(clippy)]
3+
4+
#[deny(bool_comparison)]
5+
fn main() {
6+
let x = true;
7+
if x == true { "yes" } else { "no" };
8+
//~^ ERROR equality checks against true are unnecesary
9+
//~| HELP try simplifying it as shown:
10+
//~| SUGGESTION if x { "yes" } else { "no" };
11+
if x == false { "yes" } else { "no" };
12+
//~^ ERROR equality checks against false can be replaced by a negation
13+
//~| HELP try simplifying it as shown:
14+
//~| SUGGESTION if !x { "yes" } else { "no" };
15+
if true == x { "yes" } else { "no" };
16+
//~^ ERROR equality checks against true are unnecesary
17+
//~| HELP try simplifying it as shown:
18+
//~| SUGGESTION if x { "yes" } else { "no" };
19+
if false == x { "yes" } else { "no" };
20+
//~^ ERROR equality checks against false can be replaced by a negation
21+
//~| HELP try simplifying it as shown:
22+
//~| SUGGESTION if !x { "yes" } else { "no" };
23+
}

0 commit comments

Comments
 (0)