@@ -327,6 +327,11 @@ struct Builder<'a, 'tcx> {
327327
328328 var_debug_info : Vec < VarDebugInfo < ' tcx > > ,
329329
330+ /// Cached block with the `RESUME` terminator; this is created
331+ /// when first set of cleanups are built.
332+ cached_resume_block : Option < BasicBlock > ,
333+ /// Cached block with the `RETURN` terminator.
334+ cached_return_block : Option < BasicBlock > ,
330335 /// Cached block with the `UNREACHABLE` terminator.
331336 cached_unreachable_block : Option < BasicBlock > ,
332337}
@@ -585,34 +590,50 @@ where
585590 region:: Scope { id : body. value . hir_id . local_id , data : region:: ScopeData :: CallSite } ;
586591 let arg_scope =
587592 region:: Scope { id : body. value . hir_id . local_id , data : region:: ScopeData :: Arguments } ;
593+ let mut block = START_BLOCK ;
588594 let source_info = builder. source_info ( span) ;
589595 let call_site_s = ( call_site_scope, source_info) ;
590- unpack ! ( builder. in_scope( call_site_s, LintLevel :: Inherited , |builder| {
591- let arg_scope_s = ( arg_scope, source_info) ;
592- // Attribute epilogue to function's closing brace
593- let fn_end = span. shrink_to_hi( ) ;
594- let return_block =
595- unpack!( builder. in_breakable_scope( None , Place :: return_place( ) , fn_end, |builder| {
596- Some ( builder. in_scope( arg_scope_s, LintLevel :: Inherited , |builder| {
597- builder. args_and_body(
598- START_BLOCK ,
599- fn_def_id. to_def_id( ) ,
600- & arguments,
601- arg_scope,
602- & body. value,
603- )
604- } ) )
605- } ) ) ;
606- let source_info = builder. source_info( fn_end) ;
607- builder. cfg. terminate( return_block, source_info, TerminatorKind :: Return ) ;
608- let should_abort = should_abort_on_panic( tcx, fn_def_id, abi) ;
609- builder. build_drop_trees( should_abort) ;
610- // Attribute any unreachable codepaths to the function's closing brace
611- if let Some ( unreachable_block) = builder. cached_unreachable_block {
612- builder. cfg. terminate( unreachable_block, source_info, TerminatorKind :: Unreachable ) ;
613- }
614- return_block. unit( )
615- } ) ) ;
596+ unpack ! (
597+ block = builder. in_scope( call_site_s, LintLevel :: Inherited , |builder| {
598+ if should_abort_on_panic( tcx, fn_def_id, abi) {
599+ builder. schedule_abort( ) ;
600+ }
601+
602+ let arg_scope_s = ( arg_scope, source_info) ;
603+ // `return_block` is called when we evaluate a `return` expression, so
604+ // we just use `START_BLOCK` here.
605+ unpack!(
606+ block = builder. in_breakable_scope(
607+ None ,
608+ START_BLOCK ,
609+ Place :: return_place( ) ,
610+ |builder| {
611+ builder. in_scope( arg_scope_s, LintLevel :: Inherited , |builder| {
612+ builder. args_and_body(
613+ block,
614+ fn_def_id. to_def_id( ) ,
615+ & arguments,
616+ arg_scope,
617+ & body. value,
618+ )
619+ } )
620+ } ,
621+ )
622+ ) ;
623+ // Attribute epilogue to function's closing brace
624+ let fn_end = span. shrink_to_hi( ) ;
625+ let source_info = builder. source_info( fn_end) ;
626+ let return_block = builder. return_block( ) ;
627+ builder. cfg. goto( block, source_info, return_block) ;
628+ builder. cfg. terminate( return_block, source_info, TerminatorKind :: Return ) ;
629+ // Attribute any unreachable codepaths to the function's closing brace
630+ if let Some ( unreachable_block) = builder. cached_unreachable_block {
631+ builder. cfg. terminate( unreachable_block, source_info, TerminatorKind :: Unreachable ) ;
632+ }
633+ return_block. unit( )
634+ } )
635+ ) ;
636+ assert_eq ! ( block, builder. return_block( ) ) ;
616637
617638 let spread_arg = if abi == Abi :: RustCall {
618639 // RustCall pseudo-ABI untuples the last argument.
@@ -646,7 +667,8 @@ fn construct_const<'a, 'tcx>(
646667 let source_info = builder. source_info ( span) ;
647668 builder. cfg . terminate ( block, source_info, TerminatorKind :: Return ) ;
648669
649- builder. build_drop_trees ( false ) ;
670+ // Constants can't `return` so a return block should not be created.
671+ assert_eq ! ( builder. cached_return_block, None ) ;
650672
651673 // Constants may be match expressions in which case an unreachable block may
652674 // be created, so terminate it properly.
@@ -713,7 +735,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
713735 fn_span : span,
714736 arg_count,
715737 generator_kind,
716- scopes : scope :: Scopes :: new ( ) ,
738+ scopes : Default :: default ( ) ,
717739 block_context : BlockContext :: new ( ) ,
718740 source_scopes : IndexVec :: new ( ) ,
719741 source_scope : OUTERMOST_SOURCE_SCOPE ,
@@ -726,6 +748,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
726748 var_indices : Default :: default ( ) ,
727749 unit_temp : None ,
728750 var_debug_info : vec ! [ ] ,
751+ cached_resume_block : None ,
752+ cached_return_block : None ,
729753 cached_unreachable_block : None ,
730754 } ;
731755
@@ -957,6 +981,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
957981 }
958982 }
959983 }
984+
985+ fn return_block ( & mut self ) -> BasicBlock {
986+ match self . cached_return_block {
987+ Some ( rb) => rb,
988+ None => {
989+ let rb = self . cfg . start_new_block ( ) ;
990+ self . cached_return_block = Some ( rb) ;
991+ rb
992+ }
993+ }
994+ }
960995}
961996
962997///////////////////////////////////////////////////////////////////////////
0 commit comments