@@ -204,10 +204,22 @@ where
204204 T : HasMoveData < ' tcx > + BitDenotation < Idx = MovePathIndex > ,
205205{
206206 pub fn has_any_child_of ( & self , mpi : T :: Idx ) -> Option < T :: Idx > {
207+ // We process `mpi` before the loop below, for two reasons:
208+ // - it's a little different from the loop case (we don't traverse its
209+ // siblings);
210+ // - ~99% of the time the loop isn't reached, and this code is hot, so
211+ // we don't want to allocate `todo` unnecessarily.
212+ if self . contains ( & mpi) {
213+ return Some ( mpi) ;
214+ }
207215 let move_data = self . operator ( ) . move_data ( ) ;
216+ let move_path = & move_data. move_paths [ mpi] ;
217+ let mut todo = if let Some ( child) = move_path. first_child {
218+ vec ! [ child]
219+ } else {
220+ return None ;
221+ } ;
208222
209- let mut todo = vec ! [ mpi] ;
210- let mut push_siblings = false ; // don't look at siblings of original `mpi`.
211223 while let Some ( mpi) = todo. pop ( ) {
212224 if self . contains ( & mpi) {
213225 return Some ( mpi) ;
@@ -216,15 +228,10 @@ where
216228 if let Some ( child) = move_path. first_child {
217229 todo. push ( child) ;
218230 }
219- if push_siblings {
220- if let Some ( sibling) = move_path. next_sibling {
221- todo. push ( sibling) ;
222- }
223- } else {
224- // after we've processed the original `mpi`, we should
225- // always traverse the siblings of any of its
226- // children.
227- push_siblings = true ;
231+ // After we've processed the original `mpi`, we should always
232+ // traverse the siblings of any of its children.
233+ if let Some ( sibling) = move_path. next_sibling {
234+ todo. push ( sibling) ;
228235 }
229236 }
230237 return None ;
0 commit comments