1
Fork 0

Use an Iterator for MovePath traversal

This commit is contained in:
Dylan MacKenzie 2020-01-24 12:38:51 -08:00
parent a64cd59224
commit ce56f622b4
4 changed files with 47 additions and 16 deletions

View file

@ -1350,7 +1350,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// 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);

View file

@ -1582,9 +1582,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
) {
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 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}
}
child = child_move_path.next_sibling;
}
}
}

View 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

View 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 @@ impl<'tcx> fmt::Display for MovePath<'tcx> {
}
}
#[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>>,