@@ -349,8 +349,8 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
349349 // - placeholders or free regions themselves,
350350 // - or also transitively outlive a free region.
351351 //
352- // That is to say, if there are member constraints here, the loan escapes the
353- // function and cannot go out of scope. We can early return.
352+ // That is to say, if there are member constraints here, the loan escapes the function
353+ // and cannot go out of scope. We can early return.
354354 //
355355 // 2. Via regions that are live at all points: placeholders and free regions.
356356 //
@@ -364,36 +364,32 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
364364 return ;
365365 }
366366
367- // 3. Via outlives successors, which we want to record and traverse: we add them
368- // to the worklist stack
367+ // 3. Via outlives successors, which we want to record and traverse: we add them to the
368+ // worklist stack
369369 for & succ_scc in sccs. successors ( scc) {
370370 if self . reachability . insert ( succ_scc) {
371371 self . reachability_stack . push ( succ_scc) ;
372372 }
373373 }
374374 }
375375
376- // We visit one BB at a time. The complication is that we may start in the
377- // middle of the first BB visited (the one containing `location`), in which
378- // case we may have to later on process the first part of that BB if there
379- // is a path back to its start.
376+ // We visit one BB at a time. The complication is that we may start in the middle of the
377+ // first BB visited (the one containing `issued_location`), in which case we may have to
378+ // later on process the first part of that BB if there is a path back to its start.
380379
381- // For visited BBs, we record the index of the first statement processed.
382- // (In fully processed BBs this index is 0.) Note also that we add BBs to
383- // `visited` once they are added to `stack`, before they are actually
384- // processed, because this avoids the need to look them up again on
385- // completion.
380+ // For visited BBs, we record the index of the first statement processed. (In fully
381+ // processed BBs this index is 0.) Note also that we add BBs to `visited` once they are
382+ // added to `stack`, before they are actually processed, because this avoids the need to
383+ // look them up again on completion.
386384 self . visited . insert ( issued_location. block ) ;
387385
386+ let first_block = issued_location. block ;
388387 let mut first_lo = issued_location. statement_index ;
389388 let first_hi = self . body [ issued_location. block ] . statements . len ( ) ;
390389
391390 self . visit_stack . push ( StackEntry { bb : issued_location. block , lo : first_lo, hi : first_hi } ) ;
392391
393- while let Some ( StackEntry { bb, lo, hi } ) = self . visit_stack . pop ( ) {
394- // If we process the first part of the first basic block (i.e. we encounter that block
395- // for the second time), we no longer have to visit its successors again.
396- let mut finished_early = bb == issued_location. block && hi != first_hi;
392+ ' preorder: while let Some ( StackEntry { bb, lo, hi } ) = self . visit_stack . pop ( ) {
397393 for i in lo..=hi {
398394 let location = Location { block : bb, statement_index : i } ;
399395
@@ -419,44 +415,42 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
419415 }
420416 }
421417
422- // If no live region is reachable from the issuing region, then the loan is
423- // killed at this point, and goes out of scope.
418+ // If no live region is reachable from the issuing region, then the loan is killed
419+ // at this point, and goes out of scope. We also can skip visiting successor
420+ // locations.
424421 if !issuing_region_can_reach_live_regions {
425422 debug ! ( "loan {:?} gets killed at {:?}" , loan_idx, location) ;
426423 self . loans_out_of_scope_at_location . entry ( location) . or_default ( ) . push ( loan_idx) ;
427- finished_early = true ;
428- break ;
424+ continue ' preorder;
429425 }
430426 }
431427
432- if !finished_early {
433- // Add successor BBs to the work list, if necessary.
434- let bb_data = & self . body [ bb] ;
435- debug_assert ! ( hi == bb_data. statements. len( ) ) ;
436- for succ_bb in bb_data. terminator ( ) . successors ( ) {
437- if !self . visited . insert ( succ_bb) {
438- if succ_bb == issued_location. block && first_lo > 0 {
439- // `succ_bb` has been seen before. If it wasn't fully processed, add its
440- // first part to `visit_stack` for processing.
441- self . visit_stack . push ( StackEntry {
442- bb : succ_bb,
443- lo : 0 ,
444- hi : first_lo - 1 ,
445- } ) ;
446-
447- // And update this entry with 0, to represent the whole BB being
448- // processed.
449- first_lo = 0 ;
450- }
451- } else {
452- // `succ_bb` hasn't been seen before. Add it to `visit_stack` for
453- // processing.
454- self . visit_stack . push ( StackEntry {
455- bb : succ_bb,
456- lo : 0 ,
457- hi : self . body [ succ_bb] . statements . len ( ) ,
458- } ) ;
428+ // If we process the first part of the first basic block (i.e. we encounter that block
429+ // for the second time), we no longer have to visit its successors again.
430+ if bb == first_block && hi != first_hi {
431+ continue ;
432+ }
433+
434+ // Add successor BBs to the work list, if necessary.
435+ let bb_data = & self . body [ bb] ;
436+ debug_assert ! ( hi == bb_data. statements. len( ) ) ;
437+ for succ_bb in bb_data. terminator ( ) . successors ( ) {
438+ if !self . visited . insert ( succ_bb) {
439+ if succ_bb == first_block && first_lo > 0 {
440+ // `succ_bb` has been seen before. If it wasn't fully processed, add its
441+ // first part to the stack for processing.
442+ self . visit_stack . push ( StackEntry { bb : succ_bb, lo : 0 , hi : first_lo - 1 } ) ;
443+
444+ // And update this entry with 0, to represent the whole BB being processed.
445+ first_lo = 0 ;
459446 }
447+ } else {
448+ // `succ_bb` hasn't been seen before. Add it to the stack for processing.
449+ self . visit_stack . push ( StackEntry {
450+ bb : succ_bb,
451+ lo : 0 ,
452+ hi : self . body [ succ_bb] . statements . len ( ) ,
453+ } ) ;
460454 }
461455 }
462456 }
0 commit comments