Use an Iterator
for MovePath
traversal
This commit is contained in:
parent
a64cd59224
commit
ce56f622b4
4 changed files with 47 additions and 16 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue