@@ -327,6 +327,11 @@ struct Builder<'a, 'tcx> {
327
327
328
328
var_debug_info : Vec < VarDebugInfo < ' tcx > > ,
329
329
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 > ,
330
335
/// Cached block with the `UNREACHABLE` terminator.
331
336
cached_unreachable_block : Option < BasicBlock > ,
332
337
}
@@ -585,34 +590,50 @@ where
585
590
region:: Scope { id : body. value . hir_id . local_id , data : region:: ScopeData :: CallSite } ;
586
591
let arg_scope =
587
592
region:: Scope { id : body. value . hir_id . local_id , data : region:: ScopeData :: Arguments } ;
593
+ let mut block = START_BLOCK ;
588
594
let source_info = builder. source_info ( span) ;
589
595
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( ) ) ;
616
637
617
638
let spread_arg = if abi == Abi :: RustCall {
618
639
// RustCall pseudo-ABI untuples the last argument.
@@ -646,7 +667,8 @@ fn construct_const<'a, 'tcx>(
646
667
let source_info = builder. source_info ( span) ;
647
668
builder. cfg . terminate ( block, source_info, TerminatorKind :: Return ) ;
648
669
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 ) ;
650
672
651
673
// Constants may be match expressions in which case an unreachable block may
652
674
// be created, so terminate it properly.
@@ -713,7 +735,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
713
735
fn_span : span,
714
736
arg_count,
715
737
generator_kind,
716
- scopes : scope :: Scopes :: new ( ) ,
738
+ scopes : Default :: default ( ) ,
717
739
block_context : BlockContext :: new ( ) ,
718
740
source_scopes : IndexVec :: new ( ) ,
719
741
source_scope : OUTERMOST_SOURCE_SCOPE ,
@@ -726,6 +748,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
726
748
var_indices : Default :: default ( ) ,
727
749
unit_temp : None ,
728
750
var_debug_info : vec ! [ ] ,
751
+ cached_resume_block : None ,
752
+ cached_return_block : None ,
729
753
cached_unreachable_block : None ,
730
754
} ;
731
755
@@ -957,6 +981,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
957
981
}
958
982
}
959
983
}
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
+ }
960
995
}
961
996
962
997
///////////////////////////////////////////////////////////////////////////
0 commit comments