Skip if_not_else lint for '!= 0'-style checks
This commit is contained in:
parent
78e36d9f53
commit
5e17f9f972
@ -1,6 +1,7 @@
|
|||||||
//! lint on if branches that could be swapped so no `!` operation is necessary
|
//! lint on if branches that could be swapped so no `!` operation is necessary
|
||||||
//! on the condition
|
//! on the condition
|
||||||
|
|
||||||
|
use clippy_utils::consts::{constant_simple, Constant};
|
||||||
use clippy_utils::diagnostics::span_lint_and_help;
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
use clippy_utils::is_else_clause;
|
use clippy_utils::is_else_clause;
|
||||||
use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
|
use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
|
||||||
@ -47,6 +48,13 @@ declare_clippy_lint! {
|
|||||||
|
|
||||||
declare_lint_pass!(IfNotElse => [IF_NOT_ELSE]);
|
declare_lint_pass!(IfNotElse => [IF_NOT_ELSE]);
|
||||||
|
|
||||||
|
fn is_zero_const(expr: &Expr<'_>, cx: &LateContext<'_>) -> bool {
|
||||||
|
if let Some(value) = constant_simple(cx, cx.typeck_results(), expr) {
|
||||||
|
return Constant::Int(0) == value;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
impl LateLintPass<'_> for IfNotElse {
|
impl LateLintPass<'_> for IfNotElse {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) {
|
fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) {
|
||||||
// While loops will be desugared to ExprKind::If. This will cause the lint to fire.
|
// While loops will be desugared to ExprKind::If. This will cause the lint to fire.
|
||||||
@ -72,7 +80,9 @@ impl LateLintPass<'_> for IfNotElse {
|
|||||||
"remove the `!` and swap the blocks of the `if`/`else`",
|
"remove the `!` and swap the blocks of the `if`/`else`",
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
ExprKind::Binary(ref kind, _, _) if kind.node == BinOpKind::Ne => {
|
ExprKind::Binary(ref kind, _, lhs) if kind.node == BinOpKind::Ne && !is_zero_const(lhs, cx) => {
|
||||||
|
// Disable firing the lint on `… != 0`, as these are likely to be bit tests.
|
||||||
|
// For example, `if foo & 0x0F00 != 0 { … } else { … }` already is in the "proper" order.
|
||||||
span_lint_and_help(
|
span_lint_and_help(
|
||||||
cx,
|
cx,
|
||||||
IF_NOT_ELSE,
|
IF_NOT_ELSE,
|
||||||
|
11
tests/ui/if_not_else_bittest.rs
Normal file
11
tests/ui/if_not_else_bittest.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#![deny(clippy::if_not_else)]
|
||||||
|
|
||||||
|
fn show_permissions(flags: u32) {
|
||||||
|
if flags & 0x0F00 != 0 {
|
||||||
|
println!("Has the 0x0F00 permission.");
|
||||||
|
} else {
|
||||||
|
println!("The 0x0F00 permission is missing.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
x
Reference in New Issue
Block a user