@@ -642,27 +642,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
642
642
fn leave_top_scope ( & mut self , block : BasicBlock ) -> BasicBlock {
643
643
// If we are emitting a `drop` statement, we need to have the cached
644
644
// diverge cleanup pads ready in case that drop panics.
645
- let scope = self . scopes . scopes . last ( ) . expect ( "exit_top_scope called with no scopes" ) ;
645
+ let needs_cleanup = self . scopes . scopes . last ( ) . map_or ( false , |scope| scope . needs_cleanup ( ) ) ;
646
646
let is_generator = self . generator_kind . is_some ( ) ;
647
- let needs_cleanup = scope . needs_cleanup ( ) ;
647
+ let unwind_to = if needs_cleanup { self . diverge_cleanup ( ) } else { DropIdx :: MAX } ;
648
648
649
- let unwind_to = if needs_cleanup {
650
- let mut drops = self
651
- . scopes
652
- . scopes
653
- . iter ( )
654
- . flat_map ( |scope| & scope. drops )
655
- . filter ( |drop| is_generator || drop. kind == DropKind :: Value ) ;
656
- let mut next_drop = ROOT_NODE ;
657
- let mut drop_info = drops. next ( ) . unwrap ( ) ;
658
- for previous_drop_info in drops {
659
- next_drop = self . scopes . unwind_drops . add_drop ( * drop_info, next_drop) ;
660
- drop_info = previous_drop_info;
661
- }
662
- next_drop
663
- } else {
664
- DropIdx :: MAX
665
- } ;
649
+ let scope = self . scopes . scopes . last ( ) . expect ( "exit_top_scope called with no scopes" ) ;
666
650
unpack ! ( build_scope_drops(
667
651
& mut self . cfg,
668
652
& mut self . scopes. unwind_drops,
@@ -1097,16 +1081,18 @@ fn build_scope_drops<'tcx>(
1097
1081
1098
1082
match drop_data. kind {
1099
1083
DropKind :: Value => {
1084
+ debug_assert_eq ! ( unwind_drops. drops[ unwind_to] . 0 . local, drop_data. local) ;
1085
+ debug_assert_eq ! ( unwind_drops. drops[ unwind_to] . 0 . kind, drop_data. kind) ;
1086
+ unwind_to = unwind_drops. drops [ unwind_to] . 1 ;
1100
1087
// If the operand has been moved, and we are not on an unwind
1101
1088
// path, then don't generate the drop. (We only take this into
1102
1089
// account for non-unwind paths so as not to disturb the
1103
1090
// caching mechanism.)
1104
1091
if scope. moved_locals . iter ( ) . any ( |& o| o == local) {
1105
- unwind_to = unwind_drops. drops [ unwind_to] . 1 ;
1106
1092
continue ;
1107
1093
}
1108
1094
1109
- unwind_drops. entry_points . push ( ( unwind_to , block ) ) ;
1095
+ unwind_drops. add_entry ( block , unwind_to ) ;
1110
1096
1111
1097
let next = cfg. start_new_block ( ) ;
1112
1098
cfg. terminate (
@@ -1118,6 +1104,8 @@ fn build_scope_drops<'tcx>(
1118
1104
}
1119
1105
DropKind :: Storage => {
1120
1106
if storage_dead_on_unwind {
1107
+ debug_assert_eq ! ( unwind_drops. drops[ unwind_to] . 0 . local, drop_data. local) ;
1108
+ debug_assert_eq ! ( unwind_drops. drops[ unwind_to] . 0 . kind, drop_data. kind) ;
1121
1109
unwind_to = unwind_drops. drops [ unwind_to] . 1 ;
1122
1110
}
1123
1111
// Only temps and vars need their storage dead.
@@ -1214,6 +1202,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
1214
1202
// optimization is, but it is here.
1215
1203
for ( drop_idx, drop_data) in drops. drops . iter_enumerated ( ) {
1216
1204
if let DropKind :: Value = drop_data. 0 . kind {
1205
+ debug_assert ! ( drop_data. 1 < drops. drops. next_index( ) ) ;
1217
1206
drops. entry_points . push ( ( drop_data. 1 , blocks[ drop_idx] . unwrap ( ) ) ) ;
1218
1207
}
1219
1208
}
0 commit comments