@@ -220,15 +220,24 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
220220 // Note that `break` and `continue` statements
221221 // may cause additional edges.
222222
223- // Is the condition considered part of the loop?
224223 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)
227230 self . loop_scopes . push ( LoopScope {
228231 loop_id : expr. id ,
229232 continue_index : loopback,
230233 break_index : expr_exit
231234 } ) ;
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+
232241 let body_exit = self . block ( & body, cond_exit) ; // 4
233242 self . add_contained_edge ( body_exit, loopback) ; // 5
234243 self . loop_scopes . pop ( ) ;
@@ -294,17 +303,17 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
294303 self . add_unreachable_node ( )
295304 }
296305
297- hir:: ExprBreak ( label , ref opt_expr) => {
306+ hir:: ExprBreak ( destination , ref opt_expr) => {
298307 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 ) ;
300309 let b = self . add_ast_node ( expr. id , & [ v] ) ;
301310 self . add_exiting_edge ( expr, b,
302311 loop_scope, loop_scope. break_index ) ;
303312 self . add_unreachable_node ( )
304313 }
305314
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 ) ;
308317 let a = self . add_ast_node ( expr. id , & [ pred] ) ;
309318 self . add_exiting_edge ( expr, a,
310319 loop_scope, loop_scope. continue_index ) ;
@@ -579,17 +588,18 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
579588
580589 fn find_scope ( & self ,
581590 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 ) => {
586595 for l in & self . loop_scopes {
587- if l. loop_id == label . loop_id {
596+ if l. loop_id == loop_id {
588597 return * l;
589598 }
590599 }
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) ;
592601 }
602+ Err ( err) => span_bug ! ( expr. span, "loop scope error: {}" , err)
593603 }
594604 }
595605}
0 commit comments