]> git.lizzy.rs Git - rust.git/commitdiff
Use an `Iterator` for `MovePath` traversal
authorDylan MacKenzie <ecstaticmorse@gmail.com>
Fri, 24 Jan 2020 20:38:51 +0000 (12:38 -0800)
committerDylan MacKenzie <ecstaticmorse@gmail.com>
Fri, 14 Feb 2020 02:42:12 +0000 (18:42 -0800)
src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
src/librustc_mir/borrow_check/mod.rs
src/librustc_mir/borrow_check/nll.rs
src/librustc_mir/dataflow/move_paths/mod.rs

index c7c7db9ad80953de8b12f85c2780a44f24578052..4f83a660f5c3fbc8d94f9137e704d6aadc56ede7 100644 (file)
@@ -1350,7 +1350,7 @@ fn get_moved_indexes(&mut self, location: Location, mpi: MovePathIndex) -> Vec<M
                 // there.
                 let mut mpis = vec![mpi];
                 let move_paths = &self.move_data.move_paths;
-                mpis.extend(move_paths[mpi].parents(move_paths));
+                mpis.extend(move_paths[mpi].parents(move_paths).map(|(mpi, _)| mpi));
 
                 for moi in &self.move_data.loc_map[location] {
                     debug!("report_use_of_moved_or_uninitialized: moi={:?}", moi);
index 88173137bd2e4637c57104c1c65234f8243ab91d..03871984e40d6f4f2f5607048563193c5c8ed792 100644 (file)
@@ -1582,9 +1582,9 @@ fn check_if_subslice_element_is_moved(
     ) {
         if let Some(mpi) = self.move_path_for_place(place_span.0) {
             let move_paths = &self.move_data.move_paths;
-            let mut child = move_paths[mpi].first_child;
-            while let Some(child_mpi) = child {
-                let child_move_path = &move_paths[child_mpi];
+
+            let root_path = &move_paths[mpi];
+            for (child_mpi, child_move_path) in root_path.children(move_paths) {
                 let last_proj = child_move_path.place.projection.last().unwrap();
                 if let ProjectionElem::ConstantIndex { offset, from_end, .. } = last_proj {
                     debug_assert!(!from_end, "Array constant indexing shouldn't be `from_end`.");
@@ -1606,7 +1606,6 @@ fn check_if_subslice_element_is_moved(
                         }
                     }
                 }
-                child = child_move_path.next_sibling;
             }
         }
     }
index a71dfc9a7780fe754f3d7d94e3233bac2da01e5b..1fcd5aefb3ea18c0dd264b2afba976c5b65afa8b 100644 (file)
@@ -90,7 +90,7 @@ fn populate_polonius_move_facts(
     for (child, move_path) in move_data.move_paths.iter_enumerated() {
         all_facts
             .child
-            .extend(move_path.parents(&move_data.move_paths).iter().map(|&parent| (child, parent)));
+            .extend(move_path.parents(&move_data.move_paths).map(|(parent, _)| (child, parent)));
     }
 
     // initialized_at
index 614a276164334203584bb1a64edf8aa3547f2f3c..6f6ba7dc27128adda533997dec7ab5f10173b76b 100644 (file)
@@ -58,19 +58,32 @@ pub struct MovePath<'tcx> {
 }
 
 impl<'tcx> MovePath<'tcx> {
-    pub fn parents(
+    /// Returns an iterator over the parents of `self`.
+    pub fn parents<'a>(
         &self,
-        move_paths: &IndexVec<MovePathIndex, MovePath<'_>>,
-    ) -> Vec<MovePathIndex> {
-        let mut parents = Vec::new();
-
-        let mut curr_parent = self.parent;
-        while let Some(parent_mpi) = curr_parent {
-            parents.push(parent_mpi);
-            curr_parent = move_paths[parent_mpi].parent;
+        move_paths: &'a IndexVec<MovePathIndex, MovePath<'tcx>>,
+    ) -> impl 'a + Iterator<Item = (MovePathIndex, &'a MovePath<'tcx>)> {
+        let first = self.parent.map(|mpi| (mpi, &move_paths[mpi]));
+        MovePathLinearIter {
+            next: first,
+            fetch_next: move |_, parent: &MovePath<'_>| {
+                parent.parent.map(|mpi| (mpi, &move_paths[mpi]))
+            },
         }
+    }
 
-        parents
+    /// Returns an iterator over the immediate children of `self`.
+    pub fn children<'a>(
+        &self,
+        move_paths: &'a IndexVec<MovePathIndex, MovePath<'tcx>>,
+    ) -> impl 'a + Iterator<Item = (MovePathIndex, &'a MovePath<'tcx>)> {
+        let first = self.first_child.map(|mpi| (mpi, &move_paths[mpi]));
+        MovePathLinearIter {
+            next: first,
+            fetch_next: move |_, child: &MovePath<'_>| {
+                child.next_sibling.map(|mpi| (mpi, &move_paths[mpi]))
+            },
+        }
     }
 
     /// Finds the closest descendant of `self` for which `f` returns `true` using a breadth-first
@@ -131,6 +144,25 @@ fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
+#[allow(unused)]
+struct MovePathLinearIter<'a, 'tcx, F> {
+    next: Option<(MovePathIndex, &'a MovePath<'tcx>)>,
+    fetch_next: F,
+}
+
+impl<'a, 'tcx, F> Iterator for MovePathLinearIter<'a, 'tcx, F>
+where
+    F: FnMut(MovePathIndex, &'a MovePath<'tcx>) -> Option<(MovePathIndex, &'a MovePath<'tcx>)>,
+{
+    type Item = (MovePathIndex, &'a MovePath<'tcx>);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let ret = self.next.take()?;
+        self.next = (self.fetch_next)(ret.0, ret.1);
+        Some(ret)
+    }
+}
+
 #[derive(Debug)]
 pub struct MoveData<'tcx> {
     pub move_paths: IndexVec<MovePathIndex, MovePath<'tcx>>,