@@ -542,6 +542,21 @@ impl<'tcx> Inliner<'tcx> {
542
542
destination
543
543
} ;
544
544
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
+
545
560
// Copy the arguments if needed.
546
561
let args: Vec < _ > = self . make_call_args ( args, & callsite, caller_body, & callee_body) ;
547
562
@@ -560,7 +575,7 @@ impl<'tcx> Inliner<'tcx> {
560
575
new_locals : Local :: new ( caller_body. local_decls . len ( ) ) ..,
561
576
new_scopes : SourceScope :: new ( caller_body. source_scopes . len ( ) ) ..,
562
577
new_blocks : BasicBlock :: new ( caller_body. basic_blocks . len ( ) ) ..,
563
- destination : dest ,
578
+ destination : destination_local ,
564
579
callsite_scope : caller_body. source_scopes [ callsite. source_info . scope ] . clone ( ) ,
565
580
callsite,
566
581
cleanup_block : cleanup,
@@ -591,6 +606,16 @@ impl<'tcx> Inliner<'tcx> {
591
606
// To avoid repeated O(n) insert, push any new statements to the end and rotate
592
607
// the slice once.
593
608
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
+ }
594
619
for local in callee_body. vars_and_temps_iter ( ) . rev ( ) {
595
620
if !callee_body. local_decls [ local] . internal
596
621
&& integrator. always_live_locals . contains ( local)
@@ -959,7 +984,7 @@ struct Integrator<'a, 'tcx> {
959
984
new_locals : RangeFrom < Local > ,
960
985
new_scopes : RangeFrom < SourceScope > ,
961
986
new_blocks : RangeFrom < BasicBlock > ,
962
- destination : Place < ' tcx > ,
987
+ destination : Local ,
963
988
callsite_scope : SourceScopeData < ' tcx > ,
964
989
callsite : & ' a CallSite < ' tcx > ,
965
990
cleanup_block : Option < BasicBlock > ,
@@ -972,7 +997,7 @@ struct Integrator<'a, 'tcx> {
972
997
impl Integrator < ' _ , ' _ > {
973
998
fn map_local ( & self , local : Local ) -> Local {
974
999
let new = if local == RETURN_PLACE {
975
- self . destination . local
1000
+ self . destination
976
1001
} else {
977
1002
let idx = local. index ( ) - 1 ;
978
1003
if idx < self . args . len ( ) {
@@ -1053,27 +1078,6 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
1053
1078
* span = span. fresh_expansion ( self . expn_data ) ;
1054
1079
}
1055
1080
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
-
1077
1081
fn visit_basic_block_data ( & mut self , block : BasicBlock , data : & mut BasicBlockData < ' tcx > ) {
1078
1082
self . in_cleanup_block = data. is_cleanup ;
1079
1083
self . super_basic_block_data ( block, data) ;
0 commit comments