@@ -283,7 +283,7 @@ impl<'tcx> Scopes<'tcx> {
283283
284284 /// Returns the topmost active scope, which is known to be alive until
285285 /// the next scope expression.
286- pub ( super ) fn topmost ( & self ) -> region:: Scope {
286+ fn topmost ( & self ) -> region:: Scope {
287287 self . scopes . last ( ) . expect ( "topmost_scope: no scopes present" ) . region_scope
288288 }
289289
@@ -297,7 +297,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
297297 // ==========================
298298 // Start a breakable scope, which tracks where `continue`, `break` and
299299 // `return` should branch to.
300- pub fn in_breakable_scope < F > (
300+ crate fn in_breakable_scope < F > (
301301 & mut self ,
302302 loop_block : Option < BasicBlock > ,
303303 break_destination : Place < ' tcx > ,
@@ -547,7 +547,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
547547 ///
548548 /// This path terminates in GeneratorDrop. Returns the start of the path.
549549 /// None indicates there’s no cleanup to do at this point.
550- pub fn generator_drop_cleanup ( & mut self , yield_block : BasicBlock ) {
550+ crate fn generator_drop_cleanup ( & mut self , yield_block : BasicBlock ) {
551551 let drops = self . scopes . scopes . iter ( ) . flat_map ( |scope| & scope. drops ) ;
552552 let mut next_drop = ROOT_NODE ;
553553 for drop in drops {
@@ -832,7 +832,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
832832 ///
833833 /// This path terminates in Resume. The path isn't created until after all
834834 /// of the non-unwind paths in this item have been lowered.
835- pub fn diverge_from ( & mut self , start : BasicBlock ) {
835+ crate fn diverge_from ( & mut self , start : BasicBlock ) {
836836 let next_drop = self . diverge_cleanup ( ) ;
837837 self . scopes . unwind_drops . add_entry ( start, next_drop) ;
838838 }
@@ -887,7 +887,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
887887 ///
888888 /// This is only needed for `match` arm scopes, because they have one
889889 /// entrance per pattern, but only one exit.
890- pub ( crate ) fn clear_top_scope ( & mut self , region_scope : region:: Scope ) {
890+ crate fn clear_top_scope ( & mut self , region_scope : region:: Scope ) {
891891 let top_scope = self . scopes . scopes . last_mut ( ) . unwrap ( ) ;
892892
893893 assert_eq ! ( top_scope. region_scope, region_scope) ;
@@ -1018,38 +1018,38 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
10181018
10191019 crate fn build_drop_trees ( & mut self , should_abort : bool ) {
10201020 if self . is_generator {
1021- Self :: build_generator_drop_tree (
1021+ self . build_generator_drop_trees ( should_abort) ;
1022+ } else {
1023+ Self :: build_unwind_tree (
10221024 & mut self . cfg ,
1023- & mut self . scopes . generator_drops ,
1025+ & mut self . scopes . unwind_drops ,
10241026 self . fn_span ,
10251027 should_abort,
10261028 ) ;
10271029 }
1028- Self :: build_unwind_tree (
1029- & mut self . cfg ,
1030- & mut self . scopes . unwind_drops ,
1031- self . fn_span ,
1032- should_abort,
1033- ) ;
10341030 }
10351031
1036- fn build_generator_drop_tree (
1037- cfg : & mut CFG < ' tcx > ,
1038- drops : & mut DropTree ,
1039- fn_span : Span ,
1040- should_abort : bool ,
1041- ) {
1032+ fn build_generator_drop_trees ( & mut self , should_abort : bool ) {
1033+ // Build the drop tree for dropping the generator while it's suspended.
1034+ let drops = & mut self . scopes . generator_drops ;
1035+ let cfg = & mut self . cfg ;
1036+ let fn_span = self . fn_span ;
10421037 let mut blocks = IndexVec :: from_elem ( None , & drops. drops ) ;
10431038 build_drop_tree :: < GeneratorDrop > ( cfg, drops, & mut blocks) ;
1044- // TODO: unwind?
10451039 if let Some ( root_block) = blocks[ ROOT_NODE ] {
10461040 cfg. terminate (
10471041 root_block,
10481042 SourceInfo { scope : OUTERMOST_SOURCE_SCOPE , span : fn_span } ,
10491043 TerminatorKind :: GeneratorDrop ,
10501044 ) ;
10511045 }
1052- // Reuse the generator drop tree as the unwind tree.
1046+
1047+ // Build the drop tree for unwinding in the normal control flow paths.
1048+ let resume_block =
1049+ Self :: build_unwind_tree ( cfg, & mut self . scopes . unwind_drops , fn_span, should_abort) ;
1050+
1051+ // Build the drop tree for unwinding when dropping a suspended
1052+ // generator.
10531053 //
10541054 // This is a different tree to the standard unwind paths here to
10551055 // prevent drop elaboration from creating drop flags that would have
@@ -1060,15 +1060,26 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
10601060 drops. entry_points . push ( ( drop_data. 1 , blocks[ drop_idx] . unwrap ( ) ) ) ;
10611061 }
10621062 }
1063- Self :: build_unwind_tree ( cfg, drops, fn_span, should_abort) ;
1063+ let mut blocks = IndexVec :: from_elem ( None , & drops. drops ) ;
1064+ blocks[ ROOT_NODE ] = resume_block;
1065+ build_drop_tree :: < Unwind > ( cfg, drops, & mut blocks) ;
1066+ if let ( None , Some ( new_resume_block) ) = ( resume_block, blocks[ ROOT_NODE ] ) {
1067+ let terminator =
1068+ if should_abort { TerminatorKind :: Abort } else { TerminatorKind :: Resume } ;
1069+ cfg. terminate (
1070+ new_resume_block,
1071+ SourceInfo { scope : OUTERMOST_SOURCE_SCOPE , span : fn_span } ,
1072+ terminator,
1073+ ) ;
1074+ }
10641075 }
10651076
10661077 fn build_unwind_tree (
10671078 cfg : & mut CFG < ' tcx > ,
10681079 drops : & mut DropTree ,
10691080 fn_span : Span ,
10701081 should_abort : bool ,
1071- ) {
1082+ ) -> Option < BasicBlock > {
10721083 let mut blocks = IndexVec :: from_elem ( None , & drops. drops ) ;
10731084 build_drop_tree :: < Unwind > ( cfg, drops, & mut blocks) ;
10741085 if let Some ( resume_block) = blocks[ ROOT_NODE ] {
@@ -1079,6 +1090,9 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
10791090 SourceInfo { scope : OUTERMOST_SOURCE_SCOPE , span : fn_span } ,
10801091 terminator,
10811092 ) ;
1093+ Some ( resume_block)
1094+ } else {
1095+ None
10821096 }
10831097 }
10841098}
0 commit comments