]> git.lizzy.rs Git - rust.git/commitdiff
Move unroll_place to Place::unroll
authorSantiago Pastorino <spastorino@gmail.com>
Tue, 26 Feb 2019 22:41:38 +0000 (23:41 +0100)
committerSantiago Pastorino <spastorino@gmail.com>
Wed, 17 Apr 2019 17:44:17 +0000 (19:44 +0200)
src/librustc/mir/mod.rs
src/librustc_mir/borrow_check/places_conflict.rs

index 3f376fb052a27adfe8994a0c33336afa373993b4..6289b78af9b9b57afe991a4a0462e7bb3fc01108 100644 (file)
@@ -2058,6 +2058,81 @@ pub fn base_local(&self) -> Option<Local> {
             Place::Base(PlaceBase::Static(..)) => None,
         }
     }
+
+    /// Recursively "unroll" a place into a `PlaceComponents` list,
+    /// invoking `op` with a `PlaceComponentsIter`.
+    pub fn unroll<R>(
+        &self,
+        next: Option<&PlaceComponents<'_, 'tcx>>,
+        op: impl FnOnce(PlaceComponentsIter<'_, 'tcx>) -> R,
+    ) -> R {
+        match self {
+            Place::Projection(interior) => interior.base.unroll(
+                Some(&PlaceComponents {
+                    component: self,
+                    next,
+                }),
+                op,
+            ),
+
+            Place::Base(PlaceBase::Local(_)) | Place::Base(PlaceBase::Static(_)) => {
+                let list = PlaceComponents {
+                    component: self,
+                    next,
+                };
+                op(list.iter())
+            }
+        }
+    }
+}
+
+/// A linked list of places running up the stack; begins with the
+/// innermost place and extends to projections (e.g., `a.b` would have
+/// the place `a` with a "next" pointer to `a.b`). Created by
+/// `Place::unroll`.
+///
+/// N.B., this particular impl strategy is not the most obvious. It was
+/// chosen because it makes a measurable difference to NLL
+/// performance, as this code (`borrow_conflicts_with_place`) is somewhat hot.
+pub struct PlaceComponents<'p, 'tcx: 'p> {
+    pub component: &'p Place<'tcx>,
+    pub next: Option<&'p PlaceComponents<'p, 'tcx>>,
+}
+
+impl<'p, 'tcx> PlaceComponents<'p, 'tcx> {
+    /// Converts a list of `Place` components into an iterator; this
+    /// iterator yields up a never-ending stream of `Option<&Place>`.
+    /// These begin with the "innermost" place and then with each
+    /// projection therefrom. So given a place like `a.b.c` it would
+    /// yield up:
+    ///
+    /// ```notrust
+    /// Some(`a`), Some(`a.b`), Some(`a.b.c`), None, None, ...
+    /// ```
+    fn iter(&self) -> PlaceComponentsIter<'_, 'tcx> {
+        PlaceComponentsIter { value: Some(self) }
+    }
+}
+
+/// Iterator over components; see `PlaceComponents::iter` for more
+/// information.
+///
+/// N.B., this is not a *true* Rust iterator -- the code above just
+/// manually invokes `next`. This is because we (sometimes) want to
+/// keep executing even after `None` has been returned.
+pub struct PlaceComponentsIter<'p, 'tcx: 'p> {
+    pub value: Option<&'p PlaceComponents<'p, 'tcx>>,
+}
+
+impl<'p, 'tcx> PlaceComponentsIter<'p, 'tcx> {
+    pub fn next(&mut self) -> Option<&'p Place<'tcx>> {
+        if let Some(&PlaceComponents { component, next }) = self.value {
+            self.value = next;
+            Some(component)
+        } else {
+            None
+        }
+    }
 }
 
 impl<'tcx> Debug for Place<'tcx> {
index fbe8b8485dda5b9d886ee7b1d8a3834d4c4ab11e..4f1fbea983290c414417edcade448bba3dd7164c 100644 (file)
@@ -2,7 +2,9 @@
 use crate::borrow_check::Overlap;
 use crate::borrow_check::{Deep, Shallow, AccessDepth};
 use rustc::hir;
-use rustc::mir::{BorrowKind, Mir, Place, PlaceBase, Projection, ProjectionElem, StaticKind};
+use rustc::mir::{
+    BorrowKind, Mir, Place, PlaceBase, Projection, ProjectionElem, PlaceComponentsIter, StaticKind
+};
 use rustc::ty::{self, TyCtxt};
 use std::cmp::max;
 
@@ -65,8 +67,8 @@ pub(super) fn borrow_conflicts_with_place<'gcx, 'tcx>(
         }
     }
 
-    unroll_place(borrow_place, None, |borrow_components| {
-        unroll_place(access_place, None, |access_components| {
+    borrow_place.unroll(None, |borrow_components| {
+        access_place.unroll(None, |access_components| {
             place_components_conflict(
                 tcx,
                 mir,
@@ -272,82 +274,6 @@ fn place_components_conflict<'gcx, 'tcx>(
     }
 }
 
-/// A linked list of places running up the stack; begins with the
-/// innermost place and extends to projections (e.g., `a.b` would have
-/// the place `a` with a "next" pointer to `a.b`). Created by
-/// `unroll_place`.
-///
-/// N.B., this particular impl strategy is not the most obvious. It was
-/// chosen because it makes a measurable difference to NLL
-/// performance, as this code (`borrow_conflicts_with_place`) is somewhat hot.
-struct PlaceComponents<'p, 'tcx: 'p> {
-    component: &'p Place<'tcx>,
-    next: Option<&'p PlaceComponents<'p, 'tcx>>,
-}
-
-impl<'p, 'tcx> PlaceComponents<'p, 'tcx> {
-    /// Converts a list of `Place` components into an iterator; this
-    /// iterator yields up a never-ending stream of `Option<&Place>`.
-    /// These begin with the "innermost" place and then with each
-    /// projection therefrom. So given a place like `a.b.c` it would
-    /// yield up:
-    ///
-    /// ```notrust
-    /// Some(`a`), Some(`a.b`), Some(`a.b.c`), None, None, ...
-    /// ```
-    fn iter(&self) -> PlaceComponentsIter<'_, 'tcx> {
-        PlaceComponentsIter { value: Some(self) }
-    }
-}
-
-/// Iterator over components; see `PlaceComponents::iter` for more
-/// information.
-///
-/// N.B., this is not a *true* Rust iterator -- the code above just
-/// manually invokes `next`. This is because we (sometimes) want to
-/// keep executing even after `None` has been returned.
-struct PlaceComponentsIter<'p, 'tcx: 'p> {
-    value: Option<&'p PlaceComponents<'p, 'tcx>>,
-}
-
-impl<'p, 'tcx> PlaceComponentsIter<'p, 'tcx> {
-    fn next(&mut self) -> Option<&'p Place<'tcx>> {
-        if let Some(&PlaceComponents { component, next }) = self.value {
-            self.value = next;
-            Some(component)
-        } else {
-            None
-        }
-    }
-}
-
-/// Recursively "unroll" a place into a `PlaceComponents` list,
-/// invoking `op` with a `PlaceComponentsIter`.
-fn unroll_place<'tcx, R>(
-    place: &Place<'tcx>,
-    next: Option<&PlaceComponents<'_, 'tcx>>,
-    op: impl FnOnce(PlaceComponentsIter<'_, 'tcx>) -> R,
-) -> R {
-    match place {
-        Place::Projection(interior) => unroll_place(
-            &interior.base,
-            Some(&PlaceComponents {
-                component: place,
-                next,
-            }),
-            op,
-        ),
-
-        Place::Base(PlaceBase::Local(_)) | Place::Base(PlaceBase::Static(_)) => {
-            let list = PlaceComponents {
-                component: place,
-                next,
-            };
-            op(list.iter())
-        }
-    }
-}
-
 // Given that the bases of `elem1` and `elem2` are always either equal
 // or disjoint (and have the same type!), return the overlap situation
 // between `elem1` and `elem2`.