@@ -147,24 +147,24 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
147
147
join_block. unit ( )
148
148
}
149
149
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]
156
156
//
157
157
// If `opt_cond_expr` is `None`, then the graph is somewhat simplified:
158
158
//
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
168
168
169
169
let loop_block = this. cfg . start_new_block ( ) ;
170
170
let exit_block = this. cfg . start_new_block ( ) ;
@@ -178,7 +178,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
178
178
move |this| {
179
179
// conduct the test, if necessary
180
180
let body_block;
181
- let out_terminator;
182
181
if let Some ( cond_expr) = opt_cond_expr {
183
182
let loop_block_end;
184
183
let cond = unpack ! (
@@ -192,15 +191,14 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
192
191
// we have to do it; this overwrites any `break`-assigned value but it's
193
192
// always `()` anyway
194
193
this. cfg . push_assign_unit ( exit_block, source_info, destination) ;
195
-
196
- out_terminator = TerminatorKind :: Goto { target : loop_block } ;
197
194
} else {
198
- body_block = loop_block ;
195
+ body_block = this . cfg . start_new_block ( ) ;
199
196
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
+ } )
204
202
}
205
203
206
204
// 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> {
209
207
// Execute the body, branching back to the test.
210
208
let body_block_end = unpack ! ( this. into( & tmp, body_block, body) ) ;
211
209
this. cfg . terminate ( body_block_end, source_info,
212
- out_terminator ) ;
210
+ TerminatorKind :: Goto { target : loop_block } ) ;
213
211
}
214
212
) ;
215
213
exit_block. unit ( )
0 commit comments