]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/consts.rs
Merge commit '4911ab124c481430672a3833b37075e6435ec34d' into clippyup
[rust.git] / clippy_lints / src / consts.rs
index 062c9bd2d9e6c9eb83770ec5c342a4d48bd1da46..0035ded9356cf53ba787f20a386ac9bee6162126 100644 (file)
@@ -7,8 +7,9 @@
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{BinOp, BinOpKind, Block, Expr, ExprKind, HirId, QPath, UnOp};
 use rustc_lint::LateContext;
+use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::ty::subst::{Subst, SubstsRef};
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::Symbol;
 use std::cmp::Ordering::{self, Equal};
@@ -40,6 +41,8 @@ pub enum Constant {
     Tuple(Vec<Constant>),
     /// A raw pointer.
     RawPtr(u128),
+    /// A reference
+    Ref(Box<Constant>),
     /// A literal with syntax error.
     Err(Symbol),
 }
@@ -66,6 +69,7 @@ fn eq(&self, other: &Self) -> bool {
             (&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 +114,9 @@ fn hash<H>(&self, state: &mut H)
             Self::RawPtr(u) => {
                 u.hash(state);
             },
+            Self::Ref(ref r) => {
+                r.hash(state);
+            },
             Self::Err(ref s) => {
                 s.hash(state);
             },
@@ -144,6 +151,7 @@ pub fn partial_cmp(tcx: TyCtxt<'_>, cmp_type: Ty<'_>, left: &Self, right: &Self)
                     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 +247,7 @@ pub fn expr(&mut self, e: &Expr<'_>) -> Option<Constant> {
             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 +277,7 @@ pub fn expr(&mut self, e: &Expr<'_>) -> Option<Constant> {
                 }
             },
             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,
         }
@@ -492,21 +501,21 @@ fn binop(&mut self, op: BinOp, left: &Expr<'_>, right: &Expr<'_>) -> Option<Cons
 }
 
 pub fn miri_to_const(result: &ty::Const<'_>) -> Option<Constant> {
-    use rustc_middle::mir::interpret::{ConstValue, Scalar};
+    use rustc_middle::mir::interpret::ConstValue;
     match result.val {
-        ty::ConstKind::Value(ConstValue::Scalar(Scalar::Raw { data: d, .. })) => {
+        ty::ConstKind::Value(ConstValue::Scalar(Scalar::Int(int))) => {
             match result.ty.kind() {
-                ty::Bool => Some(Constant::Bool(d == 1)),
-                ty::Uint(_) | ty::Int(_) => Some(Constant::Int(d)),
+                ty::Bool => Some(Constant::Bool(int == ScalarInt::TRUE)),
+                ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.assert_bits(int.size()))),
                 ty::Float(FloatTy::F32) => Some(Constant::F32(f32::from_bits(
-                    d.try_into().expect("invalid f32 bit representation"),
+                    int.try_into().expect("invalid f32 bit representation"),
                 ))),
                 ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits(
-                    d.try_into().expect("invalid f64 bit representation"),
+                    int.try_into().expect("invalid f64 bit representation"),
                 ))),
                 ty::RawPtr(type_and_mut) => {
                     if let ty::Uint(_) = type_and_mut.ty.kind() {
-                        return Some(Constant::RawPtr(d));
+                        return Some(Constant::RawPtr(int.assert_bits(int.size())));
                     }
                     None
                 },