about summary refs log tree commit diff
diff options
context:
space:
mode:
authormgr-inz-rafal <rchabowski@gmail.com>2020-03-23 20:29:12 +0100
committermgr-inz-rafal <rchabowski@gmail.com>2020-03-23 20:29:12 +0100
commit12796cd6886989c449e62818fb8f0bb40b9ce41e (patch)
tree41aa4dc928d61c952e3cd704d08c32fd434d7e49
parent1ff81c1b6d7abdcc9ee47f4a8ab175082cad4421 (diff)
downloadrust-12796cd6886989c449e62818fb8f0bb40b9ce41e.tar.gz
rust-12796cd6886989c449e62818fb8f0bb40b9ce41e.zip
Initial lint without suggestion
-rw-r--r--clippy_lints/src/needless_bool.rs29
-rw-r--r--tests/ui/bool_comparison.fixed10
-rw-r--r--tests/ui/bool_comparison.rs10
-rw-r--r--tests/ui/bool_comparison.stderr18
4 files changed, 63 insertions, 4 deletions
diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs
index 19c22d2b791..8de2fe2f3ba 100644
--- a/clippy_lints/src/needless_bool.rs
+++ b/clippy_lints/src/needless_bool.rs
@@ -3,10 +3,11 @@
 //! This lint is **warn** by default
 
 use crate::utils::sugg::Sugg;
-use crate::utils::{higher, parent_node_is_if_expr, span_lint, span_lint_and_sugg};
+use crate::utils::{higher, parent_node_is_if_expr, span_lint, span_lint_and_help, span_lint_and_sugg};
+use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Block, Expr, ExprKind, StmtKind};
+use rustc_hir::{BinOpKind, Block, Expr, ExprKind, StmtKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::Spanned;
@@ -188,6 +189,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison {
     }
 }
 
+fn is_unary_not<'tcx>(e: &'tcx Expr<'_>) -> bool {
+    if_chain! {
+        if let ExprKind::Unary(unop, _) = e.kind;
+        if let UnOp::UnNot = unop;
+        then {
+            return true;
+        }
+    };
+    false
+}
+
+fn one_side_is_unary_not<'tcx>(left_side: &'tcx Expr<'_>, right_side: &'tcx Expr<'_>) -> bool {
+    is_unary_not(left_side) ^ is_unary_not(right_side)
+}
+
 fn check_comparison<'a, 'tcx>(
     cx: &LateContext<'a, 'tcx>,
     e: &'tcx Expr<'_>,
@@ -199,9 +215,16 @@ fn check_comparison<'a, 'tcx>(
 ) {
     use self::Expression::{Bool, Other};
 
-    if let ExprKind::Binary(_, ref left_side, ref right_side) = e.kind {
+    if let ExprKind::Binary(op, ref left_side, ref right_side) = e.kind {
         let (l_ty, r_ty) = (cx.tables.expr_ty(left_side), cx.tables.expr_ty(right_side));
         if l_ty.is_bool() && r_ty.is_bool() {
+            if_chain! {
+                if let BinOpKind::Eq = op.node;
+                if one_side_is_unary_not(&left_side, &right_side);
+                then {
+                    span_lint_and_help(cx, BOOL_COMPARISON, e.span, "Here comes", "the suggestion");
+                }
+            };
             let mut applicability = Applicability::MachineApplicable;
             match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
                 (Bool(true), Other) => left_true.map_or((), |(h, m)| {
diff --git a/tests/ui/bool_comparison.fixed b/tests/ui/bool_comparison.fixed
index 0bd73ec2c10..d217d03ead4 100644
--- a/tests/ui/bool_comparison.fixed
+++ b/tests/ui/bool_comparison.fixed
@@ -111,3 +111,13 @@ fn issue3703() {
     if Foo < false {}
     if false < Foo {}
 }
+
+fn issue4983() {
+    let a = true;
+    let b = false;
+
+    if a == !b {};
+    if !a == b {};
+    if a == b {};
+    if !a == !b {};
+}
diff --git a/tests/ui/bool_comparison.rs b/tests/ui/bool_comparison.rs
index 74f504edfd0..c13575eae71 100644
--- a/tests/ui/bool_comparison.rs
+++ b/tests/ui/bool_comparison.rs
@@ -111,3 +111,13 @@ fn issue3703() {
     if Foo < false {}
     if false < Foo {}
 }
+
+fn issue4983() {
+    let a = true;
+    let b = false;
+
+    if a == !b {};
+    if !a == b {};
+    if a == b {};
+    if !a == !b {};
+}
diff --git a/tests/ui/bool_comparison.stderr b/tests/ui/bool_comparison.stderr
index 2aa070a00f3..cec7b196a23 100644
--- a/tests/ui/bool_comparison.stderr
+++ b/tests/ui/bool_comparison.stderr
@@ -84,5 +84,21 @@ error: order comparisons between booleans can be simplified
 LL |     if x > y {
    |        ^^^^^ help: try simplifying it as shown: `x & !y`
 
-error: aborting due to 14 previous errors
+error: Here comes
+  --> $DIR/bool_comparison.rs:119:8
+   |
+LL |     if a == !b {};
+   |        ^^^^^^^
+   |
+   = help: the suggestion
+
+error: Here comes
+  --> $DIR/bool_comparison.rs:120:8
+   |
+LL |     if !a == b {};
+   |        ^^^^^^^
+   |
+   = help: the suggestion
+
+error: aborting due to 16 previous errors