diff --git a/src/matches.rs b/src/matches.rs index da770c6f4..a7cfefd7a 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -1,6 +1,7 @@ use rustc::lint::*; use rustc_front::hir::*; use rustc::middle::ty; +use syntax::ast::Lit_::LitBool; use utils::{snippet, span_lint, span_help_and_lint, in_external_macro, expr_block}; @@ -66,10 +67,58 @@ impl LateLintPass for MatchPass { // check preconditions for MATCH_BOOL // type of expression == bool if cx.tcx.expr_ty(ex).sty == ty::TyBool { - - span_lint(cx, MATCH_BOOL, expr.span, + if arms.len() == 2 && arms[0].pats.len() == 1 { // no guards + let exprs = if let PatLit(ref arm_bool) = arms[0].pats[0].node { + if let ExprLit(ref lit) = arm_bool.node { + if let LitBool(val) = lit.node { + if val { + Some((&*arms[0].body, &*arms[1].body)) + } else { + Some((&*arms[1].body, &*arms[0].body)) + } + } else { None } + } else { None } + } else { None }; + if let Some((ref true_expr, ref false_expr)) = exprs { + if !is_unit_expr(true_expr) { + if !is_unit_expr(false_expr) { + span_help_and_lint(cx, MATCH_BOOL, expr.span, + "you seem to be trying to match on a boolean expression. \ + Consider using an if..else block:", + &format!("try\nif {} {} else {}", + snippet(cx, ex.span, "b"), + expr_block(cx, true_expr, None, ".."), + expr_block(cx, false_expr, None, ".."))); + } else { + span_help_and_lint(cx, MATCH_BOOL, expr.span, + "you seem to be trying to match on a boolean expression. \ + Consider using an if..else block:", + &format!("try\nif {} {}", + snippet(cx, ex.span, "b"), + expr_block(cx, true_expr, None, ".."))); + } + } else if !is_unit_expr(false_expr) { + span_help_and_lint(cx, MATCH_BOOL, expr.span, + "you seem to be trying to match on a boolean expression. \ + Consider using an if..else block:", + &format!("try\nif !{} {}", + snippet(cx, ex.span, "b"), + expr_block(cx, false_expr, None, ".."))); + } else { + span_lint(cx, MATCH_BOOL, expr.span, "you seem to be trying to match on a boolean expression. \ Consider using an if..else block"); + } + } else { + span_lint(cx, MATCH_BOOL, expr.span, + "you seem to be trying to match on a boolean expression. \ + Consider using an if..else block"); + } + } else { + span_lint(cx, MATCH_BOOL, expr.span, + "you seem to be trying to match on a boolean expression. \ + Consider using an if..else block"); + } } } } diff --git a/tests/compile-fail/matches.rs b/tests/compile-fail/matches.rs index 1cdf813bc..f0cc650f7 100755 --- a/tests/compile-fail/matches.rs +++ b/tests/compile-fail/matches.rs @@ -48,8 +48,25 @@ fn match_bool() { let option = 1; match option == 1 { //~ ERROR you seem to be trying to match on a boolean expression + true => 1, + false => 0, + }; + + match test { //~ ERROR you seem to be trying to match on a boolean expression true => (), - false => (), + false => { println!("Noooo!"); }, + }; + + match test { //~ ERROR you seem to be trying to match on a boolean expression + //~^ERROR you seem to be trying to use match + //TODO: Remove duplicate warning + false => { println!("Noooo!"); }, + _ => (), + }; + + match test { //~ ERROR you seem to be trying to match on a boolean expression + false => { println!("Noooo!"); }, + true => { println!("Yes!"); }, }; // Not linted