@@ -156,10 +156,10 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
156
156
& mut self ,
157
157
borrow_index : BorrowIndex ,
158
158
borrow_region : RegionVid ,
159
- location : Location ,
159
+ first_location : Location ,
160
160
) {
161
161
// 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
163
163
// case we may have to later on process the first part of that BB if there
164
164
// is a path back to its start.
165
165
@@ -168,61 +168,58 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
168
168
// `visited` once they are added to `stack`, before they are actually
169
169
// processed, because this avoids the need to look them up again on
170
170
// completion.
171
- self . visited . insert ( location . block ) ;
171
+ self . visited . insert ( first_location . block ) ;
172
172
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 ( ) ;
175
176
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 } ) ;
177
178
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 } ;
184
184
// If region does not contain a point at the location, then add to list and skip
185
185
// 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;
195
192
}
196
193
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 ;
225
214
}
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
+ } ) ;
226
223
}
227
224
}
228
225
}
0 commit comments