diff --git a/clippy_lints/src/consts.rs b/clippy_lints/src/consts.rs index 062c9bd2d9e..c5e33b288a9 100644 --- a/clippy_lints/src/consts.rs +++ b/clippy_lints/src/consts.rs @@ -40,6 +40,8 @@ pub enum Constant { Tuple(Vec), /// A raw pointer. RawPtr(u128), + /// A reference + Ref(Box), /// A literal with syntax error. Err(Symbol), } @@ -66,6 +68,7 @@ impl PartialEq for Constant { (&Self::Bool(l), &Self::Bool(r)) => l == r, (&Self::Vec(ref l), &Self::Vec(ref r)) | (&Self::Tuple(ref l), &Self::Tuple(ref r)) => l == r, (&Self::Repeat(ref lv, ref ls), &Self::Repeat(ref rv, ref rs)) => ls == rs && lv == rv, + (&Self::Ref(ref lb), &Self::Ref(ref rb)) => *lb == *rb, // TODO: are there inter-type equalities? _ => false, } @@ -110,6 +113,9 @@ impl Hash for Constant { Self::RawPtr(u) => { u.hash(state); }, + Self::Ref(ref r) => { + r.hash(state); + }, Self::Err(ref s) => { s.hash(state); }, @@ -144,6 +150,7 @@ impl Constant { x => x, } }, + (&Self::Ref(ref lb), &Self::Ref(ref rb)) => Self::partial_cmp(tcx, cmp_type, lb, rb), // TODO: are there any useful inter-type orderings? _ => None, } @@ -239,7 +246,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { ExprKind::Unary(op, ref operand) => self.expr(operand).and_then(|o| match op { UnOp::UnNot => self.constant_not(&o, self.typeck_results.expr_ty(e)), UnOp::UnNeg => self.constant_negate(&o, self.typeck_results.expr_ty(e)), - UnOp::UnDeref => Some(o), + UnOp::UnDeref => Some(if let Constant::Ref(r) = o { *r } else { o }), }), ExprKind::Binary(op, ref left, ref right) => self.binop(op, left, right), ExprKind::Call(ref callee, ref args) => { @@ -269,6 +276,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { } }, ExprKind::Index(ref arr, ref index) => self.index(arr, index), + ExprKind::AddrOf(_, _, ref inner) => self.expr(inner).map(|r| Constant::Ref(Box::new(r))), // TODO: add other expressions. _ => None, } diff --git a/tests/ui/float_cmp.rs b/tests/ui/float_cmp.rs index 9fa0e5f5c07..586784b73e6 100644 --- a/tests/ui/float_cmp.rs +++ b/tests/ui/float_cmp.rs @@ -2,6 +2,7 @@ #![allow( unused, clippy::no_effect, + clippy::op_ref, clippy::unnecessary_operation, clippy::cast_lossless, clippy::many_single_char_names @@ -116,4 +117,8 @@ fn main() { 1.23f64.signum() != x64.signum(); 1.23f64.signum() != -(x64.signum()); 1.23f64.signum() != 3.21f64.signum(); + + // the comparison should also look through references + &0.0 == &ZERO; + &&&&0.0 == &&&&ZERO; } diff --git a/tests/ui/float_cmp.stderr b/tests/ui/float_cmp.stderr index f7c380fc915..bb4051c4662 100644 --- a/tests/ui/float_cmp.stderr +++ b/tests/ui/float_cmp.stderr @@ -1,5 +1,5 @@ error: strict comparison of `f32` or `f64` - --> $DIR/float_cmp.rs:65:5 + --> $DIR/float_cmp.rs:66:5 | LL | ONE as f64 != 2.0; | ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE as f64 - 2.0).abs() > error_margin` @@ -8,7 +8,7 @@ LL | ONE as f64 != 2.0; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` - --> $DIR/float_cmp.rs:70:5 + --> $DIR/float_cmp.rs:71:5 | LL | x == 1.0; | ^^^^^^^^ help: consider comparing them within some margin of error: `(x - 1.0).abs() < error_margin` @@ -16,7 +16,7 @@ LL | x == 1.0; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` - --> $DIR/float_cmp.rs:73:5 + --> $DIR/float_cmp.rs:74:5 | LL | twice(x) != twice(ONE as f64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(twice(x) - twice(ONE as f64)).abs() > error_margin` @@ -24,7 +24,7 @@ LL | twice(x) != twice(ONE as f64); = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` - --> $DIR/float_cmp.rs:93:5 + --> $DIR/float_cmp.rs:94:5 | LL | NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(NON_ZERO_ARRAY[i] - NON_ZERO_ARRAY[j]).abs() < error_margin` @@ -32,7 +32,7 @@ LL | NON_ZERO_ARRAY[i] == NON_ZERO_ARRAY[j]; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` arrays - --> $DIR/float_cmp.rs:98:5 + --> $DIR/float_cmp.rs:99:5 | LL | a1 == a2; | ^^^^^^^^ @@ -40,7 +40,7 @@ LL | a1 == a2; = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` error: strict comparison of `f32` or `f64` - --> $DIR/float_cmp.rs:99:5 + --> $DIR/float_cmp.rs:100:5 | LL | a1[0] == a2[0]; | ^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(a1[0] - a2[0]).abs() < error_margin`