@@ -147,24 +147,24 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
147147 join_block. unit ( )
148148 }
149149 ExprKind :: Loop { condition : opt_cond_expr, body } => {
150- // [block] --> [loop_block] ~~ > [loop_block_end] -1-> [exit_block]
151- // ^ |
152- // | 0
153- // | |
154- // | v
155- // [body_block_end] <~~~ [body_block]
150+ // [block] --> [loop_block] -/eval. cond./- > [loop_block_end] -1-> [exit_block]
151+ // ^ |
152+ // | 0
153+ // | |
154+ // | v
155+ // [body_block_end] <-/eval. body/-- [body_block]
156156 //
157157 // If `opt_cond_expr` is `None`, then the graph is somewhat simplified:
158158 //
159- // [block] --> [loop_block] ~~> [loop_block_end]
160- // | ^ |
161- // false link | |
162- // | +-------------------+
163- // v
164- // [cleanup_block]
165- //
166- // The false link is required in case something results in
167- // unwinding through the body.
159+ // [block]
160+ // |
161+ // [loop_block] -> [body_block] -/eval. body/-> [body_block_end]
162+ // | ^ |
163+ // false link | |
164+ // | +-----------------------------------------+
165+ // +-> [diverge_cleanup]
166+ // The false link is required to make sure borrowck considers unwinds through the
167+ // body, even when the exact code in the body cannot unwind
168168
169169 let loop_block = this. cfg . start_new_block ( ) ;
170170 let exit_block = this. cfg . start_new_block ( ) ;
@@ -178,7 +178,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
178178 move |this| {
179179 // conduct the test, if necessary
180180 let body_block;
181- let out_terminator;
182181 if let Some ( cond_expr) = opt_cond_expr {
183182 let loop_block_end;
184183 let cond = unpack ! (
@@ -192,15 +191,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
192191 // we have to do it; this overwrites any `break`-assigned value but it's
193192 // always `()` anyway
194193 this. cfg . push_assign_unit ( exit_block, source_info, destination) ;
195-
196- out_terminator = TerminatorKind :: Goto { target : loop_block } ;
197194 } else {
198- body_block = loop_block ;
195+ body_block = this . cfg . start_new_block ( ) ;
199196 let diverge_cleanup = this. diverge_cleanup ( ) ;
200- out_terminator = TerminatorKind :: FalseUnwind {
201- real_target : loop_block,
202- unwind : Some ( diverge_cleanup)
203- }
197+ this. cfg . terminate ( loop_block, source_info,
198+ TerminatorKind :: FalseUnwind {
199+ real_target : body_block,
200+ unwind : Some ( diverge_cleanup)
201+ } )
204202 }
205203
206204 // The “return” value of the loop body must always be an unit. We therefore
@@ -209,7 +207,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
209207 // Execute the body, branching back to the test.
210208 let body_block_end = unpack ! ( this. into( & tmp, body_block, body) ) ;
211209 this. cfg . terminate ( body_block_end, source_info,
212- out_terminator ) ;
210+ TerminatorKind :: Goto { target : loop_block } ) ;
213211 }
214212 ) ;
215213 exit_block. unit ( )
0 commit comments