T: HasMoveData<'tcx> + BitDenotation<Idx = MovePathIndex>,
{
pub fn has_any_child_of(&self, mpi: T::Idx) -> Option<T::Idx> {
+ // We process `mpi` before the loop below, for two reasons:
+ // - it's a little different from the loop case (we don't traverse its
+ // siblings);
+ // - ~99% of the time the loop isn't reached, and this code is hot, so
+ // we don't want to allocate `todo` unnecessarily.
+ if self.contains(&mpi) {
+ return Some(mpi);
+ }
let move_data = self.operator().move_data();
+ let move_path = &move_data.move_paths[mpi];
+ let mut todo = if let Some(child) = move_path.first_child {
+ vec![child]
+ } else {
+ return None;
+ };
- let mut todo = vec![mpi];
- let mut push_siblings = false; // don't look at siblings of original `mpi`.
while let Some(mpi) = todo.pop() {
if self.contains(&mpi) {
return Some(mpi);
if let Some(child) = move_path.first_child {
todo.push(child);
}
- if push_siblings {
- if let Some(sibling) = move_path.next_sibling {
- todo.push(sibling);
- }
- } else {
- // after we've processed the original `mpi`, we should
- // always traverse the siblings of any of its
- // children.
- push_siblings = true;
+ // After we've processed the original `mpi`, we should always
+ // traverse the siblings of any of its children.
+ if let Some(sibling) = move_path.next_sibling {
+ todo.push(sibling);
}
}
return None;