Skip to content

Commit

Permalink
Provide appropriate suggestion
Browse files Browse the repository at this point in the history
  • Loading branch information
mgr-inz-rafal committed Mar 23, 2020
1 parent 12796cd commit 3d3af07
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 24 deletions.
45 changes: 31 additions & 14 deletions clippy_lints/src/needless_bool.rs
Expand Up @@ -3,7 +3,7 @@
//! 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_help, span_lint_and_sugg};
use crate::utils::{higher, parent_node_is_if_expr, span_lint, span_lint_and_help, span_lint_and_sugg, snippet_with_applicability};
use if_chain::if_chain;
use rustc_ast::ast::LitKind;
use rustc_errors::Applicability;
Expand Down Expand Up @@ -189,19 +189,23 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison {
}
}

fn is_unary_not<'tcx>(e: &'tcx Expr<'_>) -> bool {
fn is_unary_not<'tcx>(e: &'tcx Expr<'_>) -> (bool, rustc_span::Span) {
if_chain! {
if let ExprKind::Unary(unop, _) = e.kind;
if let ExprKind::Unary(unop, operand) = e.kind;
if let UnOp::UnNot = unop;
then {
return true;
return (true, operand.span);
}
};
false
(false, e.span)
}

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 one_side_is_unary_not<'tcx>(left_side: &'tcx Expr<'_>, right_side: &'tcx Expr<'_>) -> (bool, rustc_span::Span, rustc_span::Span) {
let left = is_unary_not(left_side);
let right = is_unary_not(right_side);

let retval = left.0 ^ right.0;
(retval, left.1, right.1)
}

fn check_comparison<'a, 'tcx>(
Expand All @@ -218,14 +222,27 @@ fn check_comparison<'a, 'tcx>(
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;

if let BinOpKind::Eq = op.node
{
let xxx = one_side_is_unary_not(&left_side, &right_side);
if xxx.0
{
span_lint_and_sugg(
cx,
BOOL_COMPARISON,
e.span,
"This comparison might be written more concisely",
"try simplifying it as shown",
format!("{} != {}",
snippet_with_applicability(cx, xxx.1, "..", &mut applicability),
snippet_with_applicability(cx, xxx.2, "..", &mut applicability)),
applicability,
)
}
}

match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
(Bool(true), Other) => left_true.map_or((), |(h, m)| {
suggest_bool_comparison(cx, e, right_side, applicability, m, h)
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/bool_comparison.fixed
Expand Up @@ -116,8 +116,8 @@ fn issue4983() {
let a = true;
let b = false;

if a == !b {};
if !a == b {};
if a != b {};
if a != b {};
if a == b {};
if !a == !b {};
}
5 changes: 5 additions & 0 deletions tests/ui/bool_comparison.rs
Expand Up @@ -120,4 +120,9 @@ fn issue4983() {
if !a == b {};
if a == b {};
if !a == !b {};

if b == !a {};
if !b == a {};
if b == a {};
if !b == !a {};
}
12 changes: 4 additions & 8 deletions tests/ui/bool_comparison.stderr
Expand Up @@ -84,21 +84,17 @@ error: order comparisons between booleans can be simplified
LL | if x > y {
| ^^^^^ help: try simplifying it as shown: `x & !y`

error: Here comes
error: This comparison might be written more concisely
--> $DIR/bool_comparison.rs:119:8
|
LL | if a == !b {};
| ^^^^^^^
|
= help: the suggestion
| ^^^^^^^ help: try simplifying it as shown: `a != b`

error: Here comes
error: This comparison might be written more concisely
--> $DIR/bool_comparison.rs:120:8
|
LL | if !a == b {};
| ^^^^^^^
|
= help: the suggestion
| ^^^^^^^ help: try simplifying it as shown: `a != b`

error: aborting due to 16 previous errors

0 comments on commit 3d3af07

Please sign in to comment.