@@ -156,10 +156,10 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
156156 & mut self ,
157157 borrow_index : BorrowIndex ,
158158 borrow_region : RegionVid ,
159- location : Location ,
159+ first_location : Location ,
160160 ) {
161161 // We visit one BB at a time. The complication is that we may start in the
162- // middle of the first BB visited (the one containing `location `), in which
162+ // middle of the first BB visited (the one containing `first_location `), in which
163163 // case we may have to later on process the first part of that BB if there
164164 // is a path back to its start.
165165
@@ -168,61 +168,58 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
168168 // `visited` once they are added to `stack`, before they are actually
169169 // processed, because this avoids the need to look them up again on
170170 // completion.
171- self . visited . insert ( location . block ) ;
171+ self . visited . insert ( first_location . block ) ;
172172
173- let mut first_lo = location. statement_index ;
174- let first_hi = self . body [ location. block ] . statements . len ( ) ;
173+ let first_block = first_location. block ;
174+ let mut first_lo = first_location. statement_index ;
175+ let first_hi = self . body [ first_block] . statements . len ( ) ;
175176
176- self . visit_stack . push ( StackEntry { bb : location . block , lo : first_lo, hi : first_hi } ) ;
177+ self . visit_stack . push ( StackEntry { bb : first_block , lo : first_lo, hi : first_hi } ) ;
177178
178- while let Some ( StackEntry { bb, lo, hi } ) = self . visit_stack . pop ( ) {
179- // If we process the first part of the first basic block (i.e. we encounter that block
180- // for the second time), we no longer have to visit its successors again.
181- let mut finished_early = bb == location. block && hi != first_hi;
182- for i in lo..=hi {
183- let location = Location { block : bb, statement_index : i } ;
179+ ' preorder: while let Some ( StackEntry { bb, lo, hi } ) = self . visit_stack . pop ( ) {
180+ if let Some ( kill_stmt) =
181+ self . regioncx . first_non_contained_inclusive ( borrow_region, bb, lo, hi)
182+ {
183+ let kill_location = Location { block : bb, statement_index : kill_stmt } ;
184184 // If region does not contain a point at the location, then add to list and skip
185185 // successor locations.
186- if !self . regioncx . region_contains ( borrow_region, location) {
187- debug ! ( "borrow {:?} gets killed at {:?}" , borrow_index, location) ;
188- self . borrows_out_of_scope_at_location
189- . entry ( location)
190- . or_default ( )
191- . push ( borrow_index) ;
192- finished_early = true ;
193- break ;
194- }
186+ debug ! ( "borrow {:?} gets killed at {:?}" , borrow_index, kill_location) ;
187+ self . borrows_out_of_scope_at_location
188+ . entry ( kill_location)
189+ . or_default ( )
190+ . push ( borrow_index) ;
191+ continue ' preorder;
195192 }
196193
197- if !finished_early {
198- // Add successor BBs to the work list, if necessary.
199- let bb_data = & self . body [ bb] ;
200- debug_assert ! ( hi == bb_data. statements. len( ) ) ;
201- for succ_bb in bb_data. terminator ( ) . successors ( ) {
202- if !self . visited . insert ( succ_bb) {
203- if succ_bb == location. block && first_lo > 0 {
204- // `succ_bb` has been seen before. If it wasn't
205- // fully processed, add its first part to `stack`
206- // for processing.
207- self . visit_stack . push ( StackEntry {
208- bb : succ_bb,
209- lo : 0 ,
210- hi : first_lo - 1 ,
211- } ) ;
212-
213- // And update this entry with 0, to represent the
214- // whole BB being processed.
215- first_lo = 0 ;
216- }
217- } else {
218- // succ_bb hasn't been seen before. Add it to
219- // `stack` for processing.
220- self . visit_stack . push ( StackEntry {
221- bb : succ_bb,
222- lo : 0 ,
223- hi : self . body [ succ_bb] . statements . len ( ) ,
224- } ) ;
194+ // If we process the first part of the first basic block (i.e. we encounter that block
195+ // for the second time), we no longer have to visit its successors again.
196+ if bb == first_block && hi != first_hi {
197+ continue ;
198+ }
199+
200+ // Add successor BBs to the work list, if necessary.
201+ let bb_data = & self . body [ bb] ;
202+ debug_assert ! ( hi == bb_data. statements. len( ) ) ;
203+ for succ_bb in bb_data. terminator ( ) . successors ( ) {
204+ if !self . visited . insert ( succ_bb) {
205+ if succ_bb == first_block && first_lo > 0 {
206+ // `succ_bb` has been seen before. If it wasn't
207+ // fully processed, add its first part to `stack`
208+ // for processing.
209+ self . visit_stack . push ( StackEntry { bb : succ_bb, lo : 0 , hi : first_lo - 1 } ) ;
210+
211+ // And update this entry with 0, to represent the
212+ // whole BB being processed.
213+ first_lo = 0 ;
225214 }
215+ } else {
216+ // succ_bb hasn't been seen before. Add it to
217+ // `stack` for processing.
218+ self . visit_stack . push ( StackEntry {
219+ bb : succ_bb,
220+ lo : 0 ,
221+ hi : self . body [ succ_bb] . statements . len ( ) ,
222+ } ) ;
226223 }
227224 }
228225 }
0 commit comments