@@ -220,15 +220,24 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
220
220
// Note that `break` and `continue` statements
221
221
// may cause additional edges.
222
222
223
- // Is the condition considered part of the loop?
224
223
let loopback = self . add_dummy_node ( & [ pred] ) ; // 1
225
- let cond_exit = self . expr ( & cond, loopback) ; // 2
226
- let expr_exit = self . add_ast_node ( expr. id , & [ cond_exit] ) ; // 3
224
+
225
+ // Create expr_exit without pred (cond_exit)
226
+ let expr_exit = self . add_ast_node ( expr. id , & [ ] ) ; // 3
227
+
228
+ // The LoopScope needs to be on the loop_scopes stack while evaluating the
229
+ // condition and the body of the loop (both can break out of the loop)
227
230
self . loop_scopes . push ( LoopScope {
228
231
loop_id : expr. id ,
229
232
continue_index : loopback,
230
233
break_index : expr_exit
231
234
} ) ;
235
+
236
+ let cond_exit = self . expr ( & cond, loopback) ; // 2
237
+
238
+ // Add pred (cond_exit) to expr_exit
239
+ self . add_contained_edge ( cond_exit, expr_exit) ;
240
+
232
241
let body_exit = self . block ( & body, cond_exit) ; // 4
233
242
self . add_contained_edge ( body_exit, loopback) ; // 5
234
243
self . loop_scopes . pop ( ) ;
@@ -294,17 +303,17 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
294
303
self . add_unreachable_node ( )
295
304
}
296
305
297
- hir:: ExprBreak ( label , ref opt_expr) => {
306
+ hir:: ExprBreak ( destination , ref opt_expr) => {
298
307
let v = self . opt_expr ( opt_expr, pred) ;
299
- let loop_scope = self . find_scope ( expr, label ) ;
308
+ let loop_scope = self . find_scope ( expr, destination ) ;
300
309
let b = self . add_ast_node ( expr. id , & [ v] ) ;
301
310
self . add_exiting_edge ( expr, b,
302
311
loop_scope, loop_scope. break_index ) ;
303
312
self . add_unreachable_node ( )
304
313
}
305
314
306
- hir:: ExprAgain ( label ) => {
307
- let loop_scope = self . find_scope ( expr, label ) ;
315
+ hir:: ExprAgain ( destination ) => {
316
+ let loop_scope = self . find_scope ( expr, destination ) ;
308
317
let a = self . add_ast_node ( expr. id , & [ pred] ) ;
309
318
self . add_exiting_edge ( expr, a,
310
319
loop_scope, loop_scope. continue_index ) ;
@@ -579,17 +588,18 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
579
588
580
589
fn find_scope ( & self ,
581
590
expr : & hir:: Expr ,
582
- label : Option < hir:: Label > ) -> LoopScope {
583
- match label {
584
- None => * self . loop_scopes . last ( ) . unwrap ( ) ,
585
- Some ( label ) => {
591
+ destination : hir:: Destination ) -> LoopScope {
592
+
593
+ match destination . loop_id . into ( ) {
594
+ Ok ( loop_id ) => {
586
595
for l in & self . loop_scopes {
587
- if l. loop_id == label . loop_id {
596
+ if l. loop_id == loop_id {
588
597
return * l;
589
598
}
590
599
}
591
- span_bug ! ( expr. span, "no loop scope for id {}" , label . loop_id) ;
600
+ span_bug ! ( expr. span, "no loop scope for id {}" , loop_id) ;
592
601
}
602
+ Err ( err) => span_bug ! ( expr. span, "loop scope error: {}" , err)
593
603
}
594
604
}
595
605
}
0 commit comments