]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/transform/check_consts/qualifs.rs
Remove PlaceBase enum and make Place base field be local: Local
[rust.git] / src / librustc_mir / transform / check_consts / qualifs.rs
index 223a5f8d605fcc518594a0fc0951c3d894e2bc2d..577736f9bd11df64a011adb3f6745890e086d3fc 100644 (file)
@@ -2,8 +2,7 @@
 
 use rustc::mir::*;
 use rustc::ty::{self, Ty};
-use rustc::hir::def_id::DefId;
-use syntax_pos::DUMMY_SP;
+use rustc_span::DUMMY_SP;
 
 use super::Item as ConstCx;
 
@@ -33,34 +32,30 @@ pub trait Qualif {
     /// of the type.
     fn in_any_value_of_ty(_cx: &ConstCx<'_, 'tcx>, _ty: Ty<'tcx>) -> bool;
 
-    fn in_static(cx: &ConstCx<'_, 'tcx>, def_id: DefId) -> bool {
-        // `mir_const_qualif` does return the qualifs in the final value of a `static`, so we could
-        // use value-based qualification here, but we shouldn't do this without a good reason.
-        Self::in_any_value_of_ty(cx, cx.tcx.type_of(def_id))
-    }
-
     fn in_projection_structurally(
         cx: &ConstCx<'_, 'tcx>,
         per_local: &impl Fn(Local) -> bool,
         place: PlaceRef<'_, 'tcx>,
     ) -> bool {
         if let [proj_base @ .., elem] = place.projection {
-            let base_qualif = Self::in_place(cx, per_local, PlaceRef {
-                base: place.base,
-                projection: proj_base,
-            });
-            let qualif = base_qualif && Self::in_any_value_of_ty(
+            let base_qualif = Self::in_place(
                 cx,
-                Place::ty_from(place.base, proj_base, *cx.body, cx.tcx)
-                    .projection_ty(cx.tcx, elem)
-                    .ty,
+                per_local,
+                PlaceRef { local: place.local, projection: proj_base },
             );
+            let qualif = base_qualif
+                && Self::in_any_value_of_ty(
+                    cx,
+                    Place::ty_from(place.local, proj_base, *cx.body, cx.tcx)
+                        .projection_ty(cx.tcx, elem)
+                        .ty,
+                );
             match elem {
-                ProjectionElem::Deref |
-                ProjectionElem::Subslice { .. } |
-                ProjectionElem::Field(..) |
-                ProjectionElem::ConstantIndex { .. } |
-                ProjectionElem::Downcast(..) => qualif,
+                ProjectionElem::Deref
+                | ProjectionElem::Subslice { .. }
+                | ProjectionElem::Field(..)
+                | ProjectionElem::ConstantIndex { .. }
+                ProjectionElem::Downcast(..) => qualif,
 
                 ProjectionElem::Index(local) => qualif || per_local(*local),
             }
@@ -83,18 +78,8 @@ fn in_place(
         place: PlaceRef<'_, 'tcx>,
     ) -> bool {
         match place {
-            PlaceRef {
-                base: PlaceBase::Local(local),
-                projection: [],
-            } => per_local(*local),
-            PlaceRef {
-                base: PlaceBase::Static(_),
-                projection: [],
-            } => bug!("qualifying already promoted MIR"),
-            PlaceRef {
-                base: _,
-                projection: [.., _],
-            } => Self::in_projection(cx, per_local, place),
+            PlaceRef { local, projection: [] } => per_local(*local),
+            PlaceRef { local: _, projection: [.., _] } => Self::in_projection(cx, per_local, place),
         }
     }
 
@@ -104,13 +89,22 @@ fn in_operand(
         operand: &Operand<'tcx>,
     ) -> bool {
         match *operand {
-            Operand::Copy(ref place) |
-            Operand::Move(ref place) => Self::in_place(cx, per_local, place.as_ref()),
+            Operand::Copy(ref place) | Operand::Move(ref place) => {
+                Self::in_place(cx, per_local, place.as_ref())
+            }
 
             Operand::Constant(ref constant) => {
-                if let Some(static_) = constant.check_static_ptr(cx.tcx) {
-                    Self::in_static(cx, static_)
-                } else if let ty::ConstKind::Unevaluated(def_id, _) = constant.literal.val {
+                if constant.check_static_ptr(cx.tcx).is_some() {
+                    // `mir_const_qualif` does return the qualifs in the final value of a `static`,
+                    // so we could use value-based qualification here, but we shouldn't do this
+                    // without a good reason.
+                    //
+                    // Note: this uses `constant.literal.ty` which is a reference or pointer to the
+                    // type of the actual `static` item.
+                    Self::in_any_value_of_ty(cx, constant.literal.ty)
+                } else if let ty::ConstKind::Unevaluated(def_id, _, promoted) = constant.literal.val
+                {
+                    assert!(promoted.is_none());
                     // Don't peek inside trait associated constants.
                     if cx.tcx.trait_of_item(def_id).is_some() {
                         Self::in_any_value_of_ty(cx, constant.literal.ty)
@@ -138,30 +132,30 @@ fn in_rvalue_structurally(
         match *rvalue {
             Rvalue::NullaryOp(..) => false,
 
-            Rvalue::Discriminant(ref place) |
-            Rvalue::Len(ref place) => Self::in_place(cx, per_local, place.as_ref()),
+            Rvalue::Discriminant(ref place) | Rvalue::Len(ref place) => {
+                Self::in_place(cx, per_local, place.as_ref())
+            }
 
-            Rvalue::Use(ref operand) |
-            Rvalue::Repeat(ref operand, _) |
-            Rvalue::UnaryOp(_, ref operand) |
-            Rvalue::Cast(_, ref operand, _) => Self::in_operand(cx, per_local, operand),
+            Rvalue::Use(ref operand)
+            | Rvalue::Repeat(ref operand, _)
+            | Rvalue::UnaryOp(_, ref operand)
+            Rvalue::Cast(_, ref operand, _) => Self::in_operand(cx, per_local, operand),
 
-            Rvalue::BinaryOp(_, ref lhs, ref rhs) |
-            Rvalue::CheckedBinaryOp(_, ref lhs, ref rhs) => {
+            Rvalue::BinaryOp(_, ref lhs, ref rhs)
+            Rvalue::CheckedBinaryOp(_, ref lhs, ref rhs) => {
                 Self::in_operand(cx, per_local, lhs) || Self::in_operand(cx, per_local, rhs)
             }
 
-            Rvalue::Ref(_, _, ref place) => {
+            Rvalue::Ref(_, _, ref place) | Rvalue::AddressOf(_, ref place) => {
                 // Special-case reborrows to be more like a copy of the reference.
-                if let &[ref proj_base @ .., elem] = place.projection.as_ref() {
-                    if ProjectionElem::Deref == elem {
-                        let base_ty = Place::ty_from(&place.base, proj_base, *cx.body, cx.tcx).ty;
-                        if let ty::Ref(..) = base_ty.kind {
-                            return Self::in_place(cx, per_local, PlaceRef {
-                                base: &place.base,
-                                projection: proj_base,
-                            });
-                        }
+                if let [proj_base @ .., ProjectionElem::Deref] = place.projection.as_ref() {
+                    let base_ty = Place::ty_from(&place.local, proj_base, *cx.body, cx.tcx).ty;
+                    if let ty::Ref(..) = base_ty.kind {
+                        return Self::in_place(
+                            cx,
+                            per_local,
+                            PlaceRef { local: &place.local, projection: proj_base },
+                        );
                     }
                 }