diff --git a/clippy_lints/src/identity_op.rs b/clippy_lints/src/identity_op.rs index a409f4c7d65..21aa914155e 100644 --- a/clippy_lints/src/identity_op.rs +++ b/clippy_lints/src/identity_op.rs @@ -1,9 +1,9 @@ use consts::{constant_simple, Constant}; -use rustc::lint::*; use rustc::hir::*; +use rustc::lint::*; +use rustc_const_math::ConstInt; use syntax::codemap::Span; use utils::{in_macro, snippet, span_lint}; -use syntax::attr::IntType::{SignedInt, UnsignedInt}; /// **What it does:** Checks for identity operations, e.g. `x + 0`. /// @@ -58,15 +58,28 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityOp { } } +fn no_zeros(v: &ConstInt) -> bool { + match *v { + ConstInt::I8(i) => i.count_zeros() == 0, + ConstInt::I16(i) => i.count_zeros() == 0, + ConstInt::I32(i) => i.count_zeros() == 0, + ConstInt::I64(i) => i.count_zeros() == 0, + ConstInt::I128(i) => i.count_zeros() == 0, + ConstInt::U8(i) => i.count_zeros() == 0, + ConstInt::U16(i) => i.count_zeros() == 0, + ConstInt::U32(i) => i.count_zeros() == 0, + ConstInt::U64(i) => i.count_zeros() == 0, + ConstInt::U128(i) => i.count_zeros() == 0, + _ => false + } +} + #[allow(cast_possible_wrap)] fn check(cx: &LateContext, e: &Expr, m: i8, span: Span, arg: Span) { if let Some(Constant::Int(v)) = constant_simple(cx, e) { if match m { 0 => v.to_u128_unchecked() == 0, - -1 => match v.int_type() { - SignedInt(_) => (v.to_u128_unchecked() as i128 == -1), - UnsignedInt(_) => false, - }, + -1 => no_zeros(&v), 1 => v.to_u128_unchecked() == 1, _ => unreachable!(), } { diff --git a/tests/ui/identity_op.rs b/tests/ui/identity_op.rs index b474344977c..1ed9f974d43 100644 --- a/tests/ui/identity_op.rs +++ b/tests/ui/identity_op.rs @@ -27,4 +27,7 @@ fn main() { x & NEG_ONE; //no error, as we skip lookups (for now) -1 & x; + + let u : u8 = 0; + u & 255; } diff --git a/tests/ui/identity_op.stderr b/tests/ui/identity_op.stderr index 30367c989ec..c1ce8d2ec4c 100644 --- a/tests/ui/identity_op.stderr +++ b/tests/ui/identity_op.stderr @@ -42,3 +42,9 @@ error: the operation is ineffective. Consider reducing it to `x` 29 | -1 & x; | ^^^^^^ +error: the operation is ineffective. Consider reducing it to `u` + --> $DIR/identity_op.rs:32:5 + | +32 | u & 255; + | ^^^^^^^ +