@@ -542,6 +542,21 @@ impl<'tcx> Inliner<'tcx> {
542542 destination
543543 } ;
544544
545+ // Always create a local to hold the destination, as `RETURN_PLACE` may appear
546+ // where a full `Place` is not allowed.
547+ let ( remap_destination, destination_local) = if let Some ( d) = dest. as_local ( ) {
548+ ( false , d)
549+ } else {
550+ (
551+ true ,
552+ self . new_call_temp (
553+ caller_body,
554+ & callsite,
555+ destination. ty ( caller_body, self . tcx ) . ty ,
556+ ) ,
557+ )
558+ } ;
559+
545560 // Copy the arguments if needed.
546561 let args: Vec < _ > = self . make_call_args ( args, & callsite, caller_body, & callee_body) ;
547562
@@ -560,7 +575,7 @@ impl<'tcx> Inliner<'tcx> {
560575 new_locals : Local :: new ( caller_body. local_decls . len ( ) ) ..,
561576 new_scopes : SourceScope :: new ( caller_body. source_scopes . len ( ) ) ..,
562577 new_blocks : BasicBlock :: new ( caller_body. basic_blocks . len ( ) ) ..,
563- destination : dest ,
578+ destination : destination_local ,
564579 callsite_scope : caller_body. source_scopes [ callsite. source_info . scope ] . clone ( ) ,
565580 callsite,
566581 cleanup_block : cleanup,
@@ -591,6 +606,16 @@ impl<'tcx> Inliner<'tcx> {
591606 // To avoid repeated O(n) insert, push any new statements to the end and rotate
592607 // the slice once.
593608 let mut n = 0 ;
609+ if remap_destination {
610+ caller_body[ block] . statements . push ( Statement {
611+ source_info : callsite. source_info ,
612+ kind : StatementKind :: Assign ( Box :: new ( (
613+ dest,
614+ Rvalue :: Use ( Operand :: Move ( destination_local. into ( ) ) ) ,
615+ ) ) ) ,
616+ } ) ;
617+ n += 1 ;
618+ }
594619 for local in callee_body. vars_and_temps_iter ( ) . rev ( ) {
595620 if !callee_body. local_decls [ local] . internal
596621 && integrator. always_live_locals . contains ( local)
@@ -959,7 +984,7 @@ struct Integrator<'a, 'tcx> {
959984 new_locals : RangeFrom < Local > ,
960985 new_scopes : RangeFrom < SourceScope > ,
961986 new_blocks : RangeFrom < BasicBlock > ,
962- destination : Place < ' tcx > ,
987+ destination : Local ,
963988 callsite_scope : SourceScopeData < ' tcx > ,
964989 callsite : & ' a CallSite < ' tcx > ,
965990 cleanup_block : Option < BasicBlock > ,
@@ -972,7 +997,7 @@ struct Integrator<'a, 'tcx> {
972997impl Integrator < ' _ , ' _ > {
973998 fn map_local ( & self , local : Local ) -> Local {
974999 let new = if local == RETURN_PLACE {
975- self . destination . local
1000+ self . destination
9761001 } else {
9771002 let idx = local. index ( ) - 1 ;
9781003 if idx < self . args . len ( ) {
@@ -1053,27 +1078,6 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
10531078 * span = span. fresh_expansion ( self . expn_data ) ;
10541079 }
10551080
1056- fn visit_place ( & mut self , place : & mut Place < ' tcx > , context : PlaceContext , location : Location ) {
1057- for elem in place. projection {
1058- // FIXME: Make sure that return place is not used in an indexing projection, since it
1059- // won't be rebased as it is supposed to be.
1060- assert_ne ! ( ProjectionElem :: Index ( RETURN_PLACE ) , elem) ;
1061- }
1062-
1063- // If this is the `RETURN_PLACE`, we need to rebase any projections onto it.
1064- let dest_proj_len = self . destination . projection . len ( ) ;
1065- if place. local == RETURN_PLACE && dest_proj_len > 0 {
1066- let mut projs = Vec :: with_capacity ( dest_proj_len + place. projection . len ( ) ) ;
1067- projs. extend ( self . destination . projection ) ;
1068- projs. extend ( place. projection ) ;
1069-
1070- place. projection = self . tcx . intern_place_elems ( & * projs) ;
1071- }
1072- // Handles integrating any locals that occur in the base
1073- // or projections
1074- self . super_place ( place, context, location)
1075- }
1076-
10771081 fn visit_basic_block_data ( & mut self , block : BasicBlock , data : & mut BasicBlockData < ' tcx > ) {
10781082 self . in_cleanup_block = data. is_cleanup ;
10791083 self . super_basic_block_data ( block, data) ;
0 commit comments