Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit ce56f62

Browse files
Use an Iterator for MovePath traversal
1 parent a64cd59 commit ce56f62

File tree

4 files changed

+47
-16
lines changed

4 files changed

+47
-16
lines changed

src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1350,7 +1350,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
13501350
// there.
13511351
let mut mpis = vec![mpi];
13521352
let move_paths = &self.move_data.move_paths;
1353-
mpis.extend(move_paths[mpi].parents(move_paths));
1353+
mpis.extend(move_paths[mpi].parents(move_paths).map(|(mpi, _)| mpi));
13541354

13551355
for moi in &self.move_data.loc_map[location] {
13561356
debug!("report_use_of_moved_or_uninitialized: moi={:?}", moi);

src/librustc_mir/borrow_check/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,9 +1582,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
15821582
) {
15831583
if let Some(mpi) = self.move_path_for_place(place_span.0) {
15841584
let move_paths = &self.move_data.move_paths;
1585-
let mut child = move_paths[mpi].first_child;
1586-
while let Some(child_mpi) = child {
1587-
let child_move_path = &move_paths[child_mpi];
1585+
1586+
let root_path = &move_paths[mpi];
1587+
for (child_mpi, child_move_path) in root_path.children(move_paths) {
15881588
let last_proj = child_move_path.place.projection.last().unwrap();
15891589
if let ProjectionElem::ConstantIndex { offset, from_end, .. } = last_proj {
15901590
debug_assert!(!from_end, "Array constant indexing shouldn't be `from_end`.");
@@ -1606,7 +1606,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
16061606
}
16071607
}
16081608
}
1609-
child = child_move_path.next_sibling;
16101609
}
16111610
}
16121611
}

src/librustc_mir/borrow_check/nll.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ fn populate_polonius_move_facts(
9090
for (child, move_path) in move_data.move_paths.iter_enumerated() {
9191
all_facts
9292
.child
93-
.extend(move_path.parents(&move_data.move_paths).iter().map(|&parent| (child, parent)));
93+
.extend(move_path.parents(&move_data.move_paths).map(|(parent, _)| (child, parent)));
9494
}
9595

9696
// initialized_at

src/librustc_mir/dataflow/move_paths/mod.rs

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,32 @@ pub struct MovePath<'tcx> {
5858
}
5959

6060
impl<'tcx> MovePath<'tcx> {
61-
pub fn parents(
61+
/// Returns an iterator over the parents of `self`.
62+
pub fn parents<'a>(
6263
&self,
63-
move_paths: &IndexVec<MovePathIndex, MovePath<'_>>,
64-
) -> Vec<MovePathIndex> {
65-
let mut parents = Vec::new();
66-
67-
let mut curr_parent = self.parent;
68-
while let Some(parent_mpi) = curr_parent {
69-
parents.push(parent_mpi);
70-
curr_parent = move_paths[parent_mpi].parent;
64+
move_paths: &'a IndexVec<MovePathIndex, MovePath<'tcx>>,
65+
) -> impl 'a + Iterator<Item = (MovePathIndex, &'a MovePath<'tcx>)> {
66+
let first = self.parent.map(|mpi| (mpi, &move_paths[mpi]));
67+
MovePathLinearIter {
68+
next: first,
69+
fetch_next: move |_, parent: &MovePath<'_>| {
70+
parent.parent.map(|mpi| (mpi, &move_paths[mpi]))
71+
},
7172
}
73+
}
7274

73-
parents
75+
/// Returns an iterator over the immediate children of `self`.
76+
pub fn children<'a>(
77+
&self,
78+
move_paths: &'a IndexVec<MovePathIndex, MovePath<'tcx>>,
79+
) -> impl 'a + Iterator<Item = (MovePathIndex, &'a MovePath<'tcx>)> {
80+
let first = self.first_child.map(|mpi| (mpi, &move_paths[mpi]));
81+
MovePathLinearIter {
82+
next: first,
83+
fetch_next: move |_, child: &MovePath<'_>| {
84+
child.next_sibling.map(|mpi| (mpi, &move_paths[mpi]))
85+
},
86+
}
7487
}
7588

7689
/// Finds the closest descendant of `self` for which `f` returns `true` using a breadth-first
@@ -131,6 +144,25 @@ impl<'tcx> fmt::Display for MovePath<'tcx> {
131144
}
132145
}
133146

147+
#[allow(unused)]
148+
struct MovePathLinearIter<'a, 'tcx, F> {
149+
next: Option<(MovePathIndex, &'a MovePath<'tcx>)>,
150+
fetch_next: F,
151+
}
152+
153+
impl<'a, 'tcx, F> Iterator for MovePathLinearIter<'a, 'tcx, F>
154+
where
155+
F: FnMut(MovePathIndex, &'a MovePath<'tcx>) -> Option<(MovePathIndex, &'a MovePath<'tcx>)>,
156+
{
157+
type Item = (MovePathIndex, &'a MovePath<'tcx>);
158+
159+
fn next(&mut self) -> Option<Self::Item> {
160+
let ret = self.next.take()?;
161+
self.next = (self.fetch_next)(ret.0, ret.1);
162+
Some(ret)
163+
}
164+
}
165+
134166
#[derive(Debug)]
135167
pub struct MoveData<'tcx> {
136168
pub move_paths: IndexVec<MovePathIndex, MovePath<'tcx>>,

0 commit comments

Comments
 (0)