Skip to content

Commit 702096d

Browse files
Implement a find_descendant method for MovePath
1 parent c64dfd7 commit 702096d

File tree

2 files changed

+47
-41
lines changed

2 files changed

+47
-41
lines changed

src/librustc_mir/dataflow/at_location.rs

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
use rustc::mir::{BasicBlock, Location};
55
use rustc_index::bit_set::{BitIter, BitSet, HybridBitSet};
66

7-
use crate::dataflow::move_paths::{HasMoveData, MovePathIndex};
87
use crate::dataflow::{BitDenotation, DataflowResults, GenKillSet};
98

109
use std::borrow::Borrow;
@@ -168,43 +167,3 @@ where
168167
self.stmt_trans.apply(&mut self.curr_state)
169168
}
170169
}
171-
172-
impl<'tcx, T, DR> FlowAtLocation<'tcx, T, DR>
173-
where
174-
T: HasMoveData<'tcx> + BitDenotation<'tcx, Idx = MovePathIndex>,
175-
DR: Borrow<DataflowResults<'tcx, T>>,
176-
{
177-
pub fn has_any_child_of(&self, mpi: T::Idx) -> Option<T::Idx> {
178-
// We process `mpi` before the loop below, for two reasons:
179-
// - it's a little different from the loop case (we don't traverse its
180-
// siblings);
181-
// - ~99% of the time the loop isn't reached, and this code is hot, so
182-
// we don't want to allocate `todo` unnecessarily.
183-
if self.contains(mpi) {
184-
return Some(mpi);
185-
}
186-
let move_data = self.operator().move_data();
187-
let move_path = &move_data.move_paths[mpi];
188-
let mut todo = if let Some(child) = move_path.first_child {
189-
vec![child]
190-
} else {
191-
return None;
192-
};
193-
194-
while let Some(mpi) = todo.pop() {
195-
if self.contains(mpi) {
196-
return Some(mpi);
197-
}
198-
let move_path = &move_data.move_paths[mpi];
199-
if let Some(child) = move_path.first_child {
200-
todo.push(child);
201-
}
202-
// After we've processed the original `mpi`, we should always
203-
// traverse the siblings of any of its children.
204-
if let Some(sibling) = move_path.next_sibling {
205-
todo.push(sibling);
206-
}
207-
}
208-
return None;
209-
}
210-
}

src/librustc_mir/dataflow/move_paths/mod.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,41 @@ impl<'tcx> MovePath<'tcx> {
7272

7373
parents
7474
}
75+
76+
/// Finds the closest descendant of `self` for which `f` returns `true` using a breadth-first
77+
/// search.
78+
///
79+
/// `f` will **not** be called on `self`.
80+
pub fn find_descendant(
81+
&self,
82+
move_paths: &IndexVec<MovePathIndex, MovePath<'_>>,
83+
f: impl Fn(MovePathIndex) -> bool,
84+
) -> Option<MovePathIndex> {
85+
let mut todo = if let Some(child) = self.first_child {
86+
vec![child]
87+
} else {
88+
return None;
89+
};
90+
91+
while let Some(mpi) = todo.pop() {
92+
if f(mpi) {
93+
return Some(mpi);
94+
}
95+
96+
let move_path = &move_paths[mpi];
97+
if let Some(child) = move_path.first_child {
98+
todo.push(child);
99+
}
100+
101+
// After we've processed the original `mpi`, we should always
102+
// traverse the siblings of any of its children.
103+
if let Some(sibling) = move_path.next_sibling {
104+
todo.push(sibling);
105+
}
106+
}
107+
108+
None
109+
}
75110
}
76111

77112
impl<'tcx> fmt::Debug for MovePath<'tcx> {
@@ -333,4 +368,16 @@ impl<'tcx> MoveData<'tcx> {
333368
}
334369
}
335370
}
371+
372+
pub fn find_in_move_path_or_its_descendants(
373+
&self,
374+
root: MovePathIndex,
375+
pred: impl Fn(MovePathIndex) -> bool,
376+
) -> Option<MovePathIndex> {
377+
if pred(root) {
378+
return Some(root);
379+
}
380+
381+
self.move_paths[root].find_descendant(&self.move_paths, pred)
382+
}
336383
}

0 commit comments

Comments
 (0)