@@ -642,27 +642,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
642642 fn leave_top_scope ( & mut self , block : BasicBlock ) -> BasicBlock {
643643 // If we are emitting a `drop` statement, we need to have the cached
644644 // 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 ( ) ) ;
646646 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 } ;
648648
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" ) ;
666650 unpack ! ( build_scope_drops(
667651 & mut self . cfg,
668652 & mut self . scopes. unwind_drops,
@@ -1097,16 +1081,18 @@ fn build_scope_drops<'tcx>(
10971081
10981082 match drop_data. kind {
10991083 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 ;
11001087 // If the operand has been moved, and we are not on an unwind
11011088 // path, then don't generate the drop. (We only take this into
11021089 // account for non-unwind paths so as not to disturb the
11031090 // caching mechanism.)
11041091 if scope. moved_locals . iter ( ) . any ( |& o| o == local) {
1105- unwind_to = unwind_drops. drops [ unwind_to] . 1 ;
11061092 continue ;
11071093 }
11081094
1109- unwind_drops. entry_points . push ( ( unwind_to , block ) ) ;
1095+ unwind_drops. add_entry ( block , unwind_to ) ;
11101096
11111097 let next = cfg. start_new_block ( ) ;
11121098 cfg. terminate (
@@ -1118,6 +1104,8 @@ fn build_scope_drops<'tcx>(
11181104 }
11191105 DropKind :: Storage => {
11201106 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) ;
11211109 unwind_to = unwind_drops. drops [ unwind_to] . 1 ;
11221110 }
11231111 // Only temps and vars need their storage dead.
@@ -1214,6 +1202,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
12141202 // optimization is, but it is here.
12151203 for ( drop_idx, drop_data) in drops. drops . iter_enumerated ( ) {
12161204 if let DropKind :: Value = drop_data. 0 . kind {
1205+ debug_assert ! ( drop_data. 1 < drops. drops. next_index( ) ) ;
12171206 drops. entry_points . push ( ( drop_data. 1 , blocks[ drop_idx] . unwrap ( ) ) ) ;
12181207 }
12191208 }
0 commit comments