@@ -651,24 +651,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
651651 fn leave_top_scope ( & mut self , block : BasicBlock ) -> BasicBlock {
652652 // If we are emitting a `drop` statement, we need to have the cached
653653 // diverge cleanup pads ready in case that drop panics.
654- let scope = self . scopes . scopes . last ( ) . expect ( "exit_top_scope called with no scopes" ) ;
654+ let needs_cleanup = self . scopes . scopes . last ( ) . map_or ( false , |scope| scope . needs_cleanup ( ) ) ;
655655 let is_generator = self . is_generator ;
656- let needs_cleanup = scope. needs_cleanup ( ) ;
657-
658656 let unwind_to = if needs_cleanup {
659- let mut drops = self . scopes . scopes . iter ( )
660- . flat_map ( |scope| & scope. drops )
661- . filter ( |drop| is_generator || drop. kind == DropKind :: Value ) ;
662- let mut next_drop = ROOT_NODE ;
663- let mut drop_info = drops. next ( ) . unwrap ( ) ;
664- for previous_drop_info in drops {
665- next_drop = self . scopes . unwind_drops . add_drop ( * drop_info, next_drop) ;
666- drop_info = previous_drop_info;
667- }
668- next_drop
657+ self . diverge_cleanup ( )
669658 } else {
670659 DropIdx :: MAX
671660 } ;
661+
662+ let scope = self . scopes . scopes . last ( ) . expect ( "exit_top_scope called with no scopes" ) ;
672663 unpack ! ( build_scope_drops(
673664 & mut self . cfg,
674665 & mut self . scopes. unwind_drops,
@@ -1098,16 +1089,18 @@ fn build_scope_drops<'tcx>(
10981089
10991090 match drop_data. kind {
11001091 DropKind :: Value => {
1092+ debug_assert_eq ! ( unwind_drops. drops[ unwind_to] . 0 . local, drop_data. local) ;
1093+ debug_assert_eq ! ( unwind_drops. drops[ unwind_to] . 0 . kind, drop_data. kind) ;
1094+ unwind_to = unwind_drops. drops [ unwind_to] . 1 ;
11011095 // If the operand has been moved, and we are not on an unwind
11021096 // path, then don't generate the drop. (We only take this into
11031097 // account for non-unwind paths so as not to disturb the
11041098 // caching mechanism.)
11051099 if scope. moved_locals . iter ( ) . any ( |& o| o == local) {
1106- unwind_to = unwind_drops. drops [ unwind_to] . 1 ;
11071100 continue ;
11081101 }
11091102
1110- unwind_drops. entry_points . push ( ( unwind_to , block ) ) ;
1103+ unwind_drops. add_entry ( block , unwind_to ) ;
11111104
11121105 let next = cfg. start_new_block ( ) ;
11131106 cfg. terminate ( block, source_info, TerminatorKind :: Drop {
@@ -1119,6 +1112,8 @@ fn build_scope_drops<'tcx>(
11191112 }
11201113 DropKind :: Storage => {
11211114 if storage_dead_on_unwind {
1115+ debug_assert_eq ! ( unwind_drops. drops[ unwind_to] . 0 . local, drop_data. local) ;
1116+ debug_assert_eq ! ( unwind_drops. drops[ unwind_to] . 0 . kind, drop_data. kind) ;
11221117 unwind_to = unwind_drops. drops [ unwind_to] . 1 ;
11231118 }
11241119 // Only temps and vars need their storage dead.
@@ -1224,6 +1219,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
12241219 // optimization is, but it is here.
12251220 for ( drop_idx, drop_data) in drops. drops . iter_enumerated ( ) {
12261221 if let DropKind :: Value = drop_data. 0 . kind {
1222+ debug_assert ! ( drop_data. 1 < drops. drops. next_index( ) ) ;
12271223 drops. entry_points . push ( ( drop_data. 1 , blocks[ drop_idx] . unwrap ( ) ) ) ;
12281224 }
12291225 }
0 commit comments