@@ -235,6 +235,9 @@ trait DropTreeBuilder<'tcx> {
235
235
236
236
impl DropTree {
237
237
fn new ( ) -> Self {
238
+ // The root node of the tree doesn't represent a drop, but instead
239
+ // represents the block in the tree that should be jumped to once all
240
+ // of the required drops have been performed.
238
241
let fake_source_info = SourceInfo { span : DUMMY_SP , scope : OUTERMOST_SOURCE_SCOPE } ;
239
242
let fake_data =
240
243
DropData { source_info : fake_source_info, local : Local :: MAX , kind : DropKind :: Storage } ;
@@ -256,12 +259,17 @@ impl DropTree {
256
259
self . entry_points . push ( ( to, from) ) ;
257
260
}
258
261
262
+ /// Builds the MIR for a given drop tree.
263
+ ///
264
+ /// `blocks` should have the same length as `self.drops`, and may have its
265
+ /// first value set to some already existing block.
259
266
fn build_mir < ' tcx , T : DropTreeBuilder < ' tcx > > (
260
267
& mut self ,
261
268
cfg : & mut CFG < ' tcx > ,
262
269
blocks : & mut IndexVec < DropIdx , Option < BasicBlock > > ,
263
270
) {
264
271
debug ! ( "DropTree::lower_to_mir(drops = {:#?})" , self ) ;
272
+ debug_assert_eq ! ( blocks. len( ) , self . drops. len( ) ) ;
265
273
266
274
self . assign_blocks :: < T > ( cfg, blocks) ;
267
275
self . link_blocks ( cfg, blocks)
@@ -1105,7 +1113,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1105
1113
return self . cfg . start_new_block ( ) . unit ( ) ;
1106
1114
}
1107
1115
let mut first_arm = true ;
1108
- let cached_unwind_block = self . diverge_cleanup ( ) ;
1109
1116
let arm_end_blocks: Vec < _ > = arm_candidates
1110
1117
. into_iter ( )
1111
1118
. map ( |( arm, candidate) | {
@@ -1115,8 +1122,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1115
1122
destination_scope. map ( |scope| {
1116
1123
self . unschedule_drop ( scope, destination. as_local ( ) . unwrap ( ) ) ;
1117
1124
} ) ;
1118
- let top_scope = & mut self . scopes . scopes . last_mut ( ) . unwrap ( ) ;
1119
- top_scope. cached_unwind_block = Some ( cached_unwind_block) ;
1120
1125
}
1121
1126
1122
1127
let arm_source_info = self . source_info ( arm. span ) ;
@@ -1394,10 +1399,16 @@ impl<'tcx> DropTreeBuilder<'tcx> for GeneratorDrop {
1394
1399
cfg. start_new_block ( )
1395
1400
}
1396
1401
fn add_entry ( cfg : & mut CFG < ' tcx > , from : BasicBlock , to : BasicBlock ) {
1397
- let kind = & mut cfg. block_data_mut ( from) . terminator_mut ( ) . kind ;
1398
- if let TerminatorKind :: Yield { drop, .. } = kind {
1402
+ let term = cfg. block_data_mut ( from) . terminator_mut ( ) ;
1403
+ if let TerminatorKind :: Yield { ref mut drop, .. } = term . kind {
1399
1404
* drop = Some ( to) ;
1400
- } ;
1405
+ } else {
1406
+ span_bug ! (
1407
+ term. source_info. span,
1408
+ "cannot enter generator drop tree from {:?}" ,
1409
+ term. kind
1410
+ )
1411
+ }
1401
1412
}
1402
1413
}
1403
1414
@@ -1408,8 +1419,8 @@ impl<'tcx> DropTreeBuilder<'tcx> for Unwind {
1408
1419
cfg. start_new_cleanup_block ( )
1409
1420
}
1410
1421
fn add_entry ( cfg : & mut CFG < ' tcx > , from : BasicBlock , to : BasicBlock ) {
1411
- let term = & mut cfg. block_data_mut ( from) . terminator_mut ( ) . kind ;
1412
- match term {
1422
+ let term = & mut cfg. block_data_mut ( from) . terminator_mut ( ) ;
1423
+ match & mut term. kind {
1413
1424
TerminatorKind :: Drop { unwind, .. }
1414
1425
| TerminatorKind :: DropAndReplace { unwind, .. }
1415
1426
| TerminatorKind :: FalseUnwind { unwind, .. }
@@ -1425,7 +1436,9 @@ impl<'tcx> DropTreeBuilder<'tcx> for Unwind {
1425
1436
| TerminatorKind :: Unreachable
1426
1437
| TerminatorKind :: Yield { .. }
1427
1438
| TerminatorKind :: GeneratorDrop
1428
- | TerminatorKind :: FalseEdges { .. } => bug ! ( "cannot unwind from {:?}" , term) ,
1439
+ | TerminatorKind :: FalseEdges { .. } => {
1440
+ span_bug ! ( term. source_info. span, "cannot unwind from {:?}" , term. kind)
1441
+ }
1429
1442
}
1430
1443
}
1431
1444
}
0 commit comments