Skip to content

Commit

Permalink
lint comparison to bool (e.g. y == true)
Browse files Browse the repository at this point in the history
Addresses #630
  • Loading branch information
Joshua Holmer committed Feb 9, 2016
1 parent 8c886f1 commit 56b3e7b
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/lib.rs
Expand Up @@ -105,6 +105,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
reg.register_late_lint_pass(box bit_mask::BitMask);
reg.register_late_lint_pass(box ptr_arg::PtrArg);
reg.register_late_lint_pass(box needless_bool::NeedlessBool);
reg.register_late_lint_pass(box needless_bool::BoolComparison);
reg.register_late_lint_pass(box approx_const::ApproxConstant);
reg.register_late_lint_pass(box misc::FloatCmp);
reg.register_early_lint_pass(box precedence::Precedence);
Expand Down Expand Up @@ -253,6 +254,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
mut_reference::UNNECESSARY_MUT_PASSED,
mutex_atomic::MUTEX_ATOMIC,
needless_bool::NEEDLESS_BOOL,
needless_bool::BOOL_COMPARISON,
needless_features::UNSTABLE_AS_MUT_SLICE,
needless_features::UNSTABLE_AS_SLICE,
needless_update::NEEDLESS_UPDATE,
Expand Down
66 changes: 66 additions & 0 deletions src/needless_bool.rs
Expand Up @@ -6,6 +6,7 @@ use rustc::lint::*;
use rustc_front::hir::*;

use syntax::ast::Lit_;
use syntax::codemap::Spanned;

use utils::{span_lint, snippet};

Expand All @@ -23,6 +24,20 @@ declare_lint! {
`if p { true } else { false }`"
}

/// **What it does:** This lint checks for expressions of the form `x == true` (or vice versa) and suggest using the variable directly.
///
/// **Why is this bad?** Unnecessary code.
///
/// **Known problems:** None.
///
/// **Example:** `if x == true { }` could be `if x { }`
declare_lint! {
pub BOOL_COMPARISON,
Warn,
"comparing a variable to a boolean, e.g. \
`if x == true`"
}

#[derive(Copy,Clone)]
pub struct NeedlessBool;

Expand Down Expand Up @@ -78,6 +93,57 @@ impl LateLintPass for NeedlessBool {
}
}

#[derive(Copy,Clone)]
pub struct BoolComparison;

impl LintPass for BoolComparison {
fn get_lints(&self) -> LintArray {
lint_array!(BOOL_COMPARISON)
}
}

impl LateLintPass for BoolComparison {
fn check_expr(&mut self, cx: &LateContext, e: &Expr) {
if let ExprBinary(Spanned{ node: BiEq, .. }, ref left_side, ref right_side) = e.node {
match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
(Some(true), None) => {
let side_snip = snippet(cx, right_side.span, "..");
let hint = format!("`{}`", side_snip);
span_lint(cx,
BOOL_COMPARISON,
e.span,
&format!("you can simplify this boolean comparison to {}", hint));
}
(None, Some(true)) => {
let side_snip = snippet(cx, left_side.span, "..");
let hint = format!("`{}`", side_snip);
span_lint(cx,
BOOL_COMPARISON,
e.span,
&format!("you can simplify this boolean comparison to {}", hint));
}
(Some(false), None) => {
let side_snip = snippet(cx, right_side.span, "..");
let hint = format!("`!{}`", side_snip);
span_lint(cx,
BOOL_COMPARISON,
e.span,
&format!("you can simplify this boolean comparison to {}", hint));
}
(None, Some(false)) => {
let side_snip = snippet(cx, left_side.span, "..");
let hint = format!("`!{}`", side_snip);
span_lint(cx,
BOOL_COMPARISON,
e.span,
&format!("you can simplify this boolean comparison to {}", hint));
}
_ => (),
}
}
}
}

fn fetch_bool_block(block: &Block) -> Option<bool> {
if block.stmts.is_empty() {
block.expr.as_ref().and_then(|e| fetch_bool_expr(e))
Expand Down
12 changes: 12 additions & 0 deletions tests/compile-fail/bool_comparison.rs
@@ -0,0 +1,12 @@
#![feature(plugin)]
#![plugin(clippy)]

#[allow(needless_bool)]
#[deny(bool_comparison)]
fn main() {
let x = true;
if x == true { true } else { false }; //~ERROR you can simplify this boolean comparison to `x`
if x == false { true } else { false }; //~ERROR you can simplify this boolean comparison to `!x`
if true == x { true } else { false }; //~ERROR you can simplify this boolean comparison to `x`
if false == x { true } else { false }; //~ERROR you can simplify this boolean comparison to `!x`
}

0 comments on commit 56b3e7b

Please sign in to comment.