1 //! Checks for needless boolean results of if-else expressions
3 //! This lint is **warn** by default
5 use rustc::plugin::Registry;
7 use rustc::middle::const_eval::lookup_const_by_id;
8 use rustc::middle::def::*;
10 use syntax::ast_util::{is_comparison_binop, binop_to_string};
12 use syntax::codemap::Span;
13 use utils::{de_p, span_lint};
18 "Warn on needless use of if x { true } else { false } (or vice versa)"
22 pub struct NeedlessBool;
24 impl LintPass for NeedlessBool {
25 fn get_lints(&self) -> LintArray {
26 lint_array!(NEEDLESS_BOOL)
29 fn check_expr(&mut self, cx: &Context, e: &Expr) {
30 if let ExprIf(_, ref then_block, Option::Some(ref else_expr)) = e.node {
31 match (fetch_bool_block(then_block), fetch_bool_expr(else_expr)) {
32 (Option::Some(true), Option::Some(true)) => {
33 span_lint(cx, NEEDLESS_BOOL, e.span,
34 "your if-then-else expression will always return true"); },
35 (Option::Some(true), Option::Some(false)) => {
36 span_lint(cx, NEEDLESS_BOOL, e.span,
37 "you can reduce your if-statement to its predicate"); },
38 (Option::Some(false), Option::Some(true)) => {
39 span_lint(cx, NEEDLESS_BOOL, e.span,
40 "you can reduce your if-statement to '!' + your predicate"); },
41 (Option::Some(false), Option::Some(false)) => {
42 span_lint(cx, NEEDLESS_BOOL, e.span,
43 "your if-then-else expression will always return false"); },
50 fn fetch_bool_block(block: &Block) -> Option<bool> {
51 if block.stmts.is_empty() {
52 block.expr.as_ref().map(de_p).and_then(fetch_bool_expr)
53 } else { Option::None }
56 fn fetch_bool_expr(expr: &Expr) -> Option<bool> {
58 &ExprBlock(ref block) => fetch_bool_block(block),
59 &ExprLit(ref lit_ptr) => if let &LitBool(value) = &lit_ptr.node {
60 Option::Some(value) } else { Option::None },