]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/borrow_check/place_ext.rs
Don't run MIR passes on constructor shims
[rust.git] / src / librustc_mir / borrow_check / place_ext.rs
index cf9a6165d71a249159c6e28d500523f0cd5eb7ad..9306e88e9ae9c804704a2a015a31700566d86c22 100644 (file)
@@ -1,6 +1,6 @@
 use rustc::hir;
 use rustc::mir::ProjectionElem;
-use rustc::mir::{Mir, Place, PlaceBase, Mutability, Static, StaticKind};
+use rustc::mir::{Body, Place, PlaceBase, Mutability, Static, StaticKind};
 use rustc::ty::{self, TyCtxt};
 use crate::borrow_check::borrow_set::LocalsStateAtExit;
 
@@ -13,7 +13,7 @@
     fn ignore_borrow(
         &self,
         tcx: TyCtxt<'_, '_, 'tcx>,
-        mir: &Mir<'tcx>,
+        mir: &Body<'tcx>,
         locals_state_at_exit: &LocalsStateAtExit,
         ) -> bool;
 }
@@ -22,43 +22,39 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
     fn ignore_borrow(
         &self,
         tcx: TyCtxt<'_, '_, 'tcx>,
-        mir: &Mir<'tcx>,
+        mir: &Body<'tcx>,
         locals_state_at_exit: &LocalsStateAtExit,
     ) -> bool {
-        match self {
-            // If a local variable is immutable, then we only need to track borrows to guard
-            // against two kinds of errors:
-            // * The variable being dropped while still borrowed (e.g., because the fn returns
-            //   a reference to a local variable)
-            // * The variable being moved while still borrowed
-            //
-            // In particular, the variable cannot be mutated -- the "access checks" will fail --
-            // so we don't have to worry about mutation while borrowed.
-            Place::Base(PlaceBase::Local(index)) => {
-                match locals_state_at_exit {
-                    LocalsStateAtExit::AllAreInvalidated => false,
-                    LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => {
-                        let ignore = !has_storage_dead_or_moved.contains(*index) &&
-                            mir.local_decls[*index].mutability == Mutability::Not;
-                        debug!("ignore_borrow: local {:?} => {:?}", index, ignore);
-                        ignore
+        self.iterate(|place_base, place_projection| {
+            let ignore = match place_base {
+                // If a local variable is immutable, then we only need to track borrows to guard
+                // against two kinds of errors:
+                // * The variable being dropped while still borrowed (e.g., because the fn returns
+                //   a reference to a local variable)
+                // * The variable being moved while still borrowed
+                //
+                // In particular, the variable cannot be mutated -- the "access checks" will fail --
+                // so we don't have to worry about mutation while borrowed.
+                PlaceBase::Local(index) => {
+                    match locals_state_at_exit {
+                        LocalsStateAtExit::AllAreInvalidated => false,
+                        LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => {
+                            let ignore = !has_storage_dead_or_moved.contains(*index) &&
+                                mir.local_decls[*index].mutability == Mutability::Not;
+                            debug!("ignore_borrow: local {:?} => {:?}", index, ignore);
+                            ignore
+                        }
                     }
                 }
-            }
-            Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) =>
-                false,
-            Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => {
-                tcx.is_mutable_static(*def_id)
-            }
-            Place::Projection(proj) => match proj.elem {
-                ProjectionElem::Field(..)
-                | ProjectionElem::Downcast(..)
-                | ProjectionElem::Subslice { .. }
-                | ProjectionElem::ConstantIndex { .. }
-                | ProjectionElem::Index(_) => proj.base.ignore_borrow(
-                    tcx, mir, locals_state_at_exit),
+                PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. }) =>
+                    false,
+                PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. }) => {
+                    tcx.is_mutable_static(*def_id)
+                }
+            };
 
-                ProjectionElem::Deref => {
+            for proj in place_projection {
+                if proj.elem == ProjectionElem::Deref {
                     let ty = proj.base.ty(mir, tcx).ty;
                     match ty.sty {
                         // For both derefs of raw pointers and `&T`
@@ -71,11 +67,13 @@ fn ignore_borrow(
                         // original path into a new variable and
                         // borrowed *that* one, leaving the original
                         // path unborrowed.
-                        ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) => true,
-                        _ => proj.base.ignore_borrow(tcx, mir, locals_state_at_exit),
+                        ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) => return true,
+                        _ => {}
                     }
                 }
-            },
-        }
+            }
+
+            ignore
+        })
     }
 }