@@ -204,10 +204,22 @@ where
204
204
T : HasMoveData < ' tcx > + BitDenotation < Idx = MovePathIndex > ,
205
205
{
206
206
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
+ }
207
215
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
+ } ;
208
222
209
- let mut todo = vec ! [ mpi] ;
210
- let mut push_siblings = false ; // don't look at siblings of original `mpi`.
211
223
while let Some ( mpi) = todo. pop ( ) {
212
224
if self . contains ( & mpi) {
213
225
return Some ( mpi) ;
@@ -216,15 +228,10 @@ where
216
228
if let Some ( child) = move_path. first_child {
217
229
todo. push ( child) ;
218
230
}
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) ;
228
235
}
229
236
}
230
237
return None ;
0 commit comments