about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-05-25 04:57:36 +0200
committerGitHub <noreply@github.com>2019-05-25 04:57:36 +0200
commite30300d6e8673bcc509741fa885f3874c0df0e21 (patch)
treec65d5b8d8cd00426f9f42448b35690d47644d7d2
parentaf015527aa037ae858871ae30cf6897bdb8236e5 (diff)
parent10fe26962c644d6b1a381ecea93d6fe516bd861f (diff)
downloadrust-e30300d6e8673bcc509741fa885f3874c0df0e21.tar.gz
rust-e30300d6e8673bcc509741fa885f3874c0df0e21.zip
Rollup merge of #61099 - spastorino:ignore-borrow-iterate, r=oli-obk
Make ignore_borrow iterate instead of recurse

r? @oli-obk
-rw-r--r--src/librustc_mir/borrow_check/place_ext.rs68
1 files changed, 33 insertions, 35 deletions
diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs
index cf9a6165d71..9ad0e936e1b 100644
--- a/src/librustc_mir/borrow_check/place_ext.rs
+++ b/src/librustc_mir/borrow_check/place_ext.rs
@@ -25,40 +25,36 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
         mir: &Mir<'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 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
                         // 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
+        })
     }
 }