Initial lint without suggestion

This commit is contained in:
mgr-inz-rafal 2020-03-23 20:29:12 +01:00
parent 1ff81c1b6d
commit 12796cd688
4 changed files with 63 additions and 4 deletions

View file

@ -3,10 +3,11 @@
//! This lint is **warn** by default //! This lint is **warn** by default
use crate::utils::sugg::Sugg; 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_ast::ast::LitKind;
use rustc_errors::Applicability; 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_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Spanned; 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>( fn check_comparison<'a, 'tcx>(
cx: &LateContext<'a, 'tcx>, cx: &LateContext<'a, 'tcx>,
e: &'tcx Expr<'_>, e: &'tcx Expr<'_>,
@ -199,9 +215,16 @@ fn check_comparison<'a, 'tcx>(
) { ) {
use self::Expression::{Bool, Other}; 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)); 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 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; let mut applicability = Applicability::MachineApplicable;
match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) { match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
(Bool(true), Other) => left_true.map_or((), |(h, m)| { (Bool(true), Other) => left_true.map_or((), |(h, m)| {

View file

@ -111,3 +111,13 @@ fn issue3703() {
if Foo < false {} if Foo < false {}
if false < Foo {} if false < Foo {}
} }
fn issue4983() {
let a = true;
let b = false;
if a == !b {};
if !a == b {};
if a == b {};
if !a == !b {};
}

View file

@ -111,3 +111,13 @@ fn issue3703() {
if Foo < false {} if Foo < false {}
if false < Foo {} if false < Foo {}
} }
fn issue4983() {
let a = true;
let b = false;
if a == !b {};
if !a == b {};
if a == b {};
if !a == !b {};
}

View file

@ -84,5 +84,21 @@ error: order comparisons between booleans can be simplified
LL | if x > y { LL | if x > y {
| ^^^^^ help: try simplifying it as shown: `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