@@ -623,35 +623,30 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
623623 let frame = M :: init_frame_extra ( self , pre_frame) ?;
624624 self . stack_mut ( ) . push ( frame) ;
625625
626- // don't allocate at all for trivial constants
627- if body. local_decls . len ( ) > 1 {
628- // Locals are initially uninitialized.
629- let dummy = LocalState { value : LocalValue :: Uninitialized , layout : Cell :: new ( None ) } ;
630- let mut locals = IndexVec :: from_elem ( dummy, & body. local_decls ) ;
631- // Return place is handled specially by the `eval_place` functions, and the
632- // entry in `locals` should never be used. Make it dead, to be sure.
633- locals[ mir:: RETURN_PLACE ] . value = LocalValue :: Dead ;
634- // Now mark those locals as dead that we do not want to initialize
635- match self . tcx . def_kind ( instance. def_id ( ) ) {
636- // statics and constants don't have `Storage*` statements, no need to look for them
637- //
638- // FIXME: The above is likely untrue. See
639- // <https://github.com/rust-lang/rust/pull/70004#issuecomment-602022110>. Is it
640- // okay to ignore `StorageDead`/`StorageLive` annotations during CTFE?
641- Some ( DefKind :: Static | DefKind :: Const | DefKind :: AssocConst ) => { }
642- _ => {
643- // Mark locals that use `Storage*` annotations as dead on function entry.
644- let always_live = AlwaysLiveLocals :: new ( self . body ( ) ) ;
645- for local in locals. indices ( ) {
646- if !always_live. contains ( local) {
647- locals[ local] . value = LocalValue :: Dead ;
648- }
626+ // Locals are initially uninitialized.
627+ let dummy = LocalState { value : LocalValue :: Uninitialized , layout : Cell :: new ( None ) } ;
628+ let mut locals = IndexVec :: from_elem ( dummy, & body. local_decls ) ;
629+
630+ // Now mark those locals as dead that we do not want to initialize
631+ match self . tcx . def_kind ( instance. def_id ( ) ) {
632+ // statics and constants don't have `Storage*` statements, no need to look for them
633+ //
634+ // FIXME: The above is likely untrue. See
635+ // <https://github.com/rust-lang/rust/pull/70004#issuecomment-602022110>. Is it
636+ // okay to ignore `StorageDead`/`StorageLive` annotations during CTFE?
637+ Some ( DefKind :: Static | DefKind :: Const | DefKind :: AssocConst ) => { }
638+ _ => {
639+ // Mark locals that use `Storage*` annotations as dead on function entry.
640+ let always_live = AlwaysLiveLocals :: new ( self . body ( ) ) ;
641+ for local in locals. indices ( ) {
642+ if !always_live. contains ( local) {
643+ locals[ local] . value = LocalValue :: Dead ;
649644 }
650645 }
651646 }
652- // done
653- self . frame_mut ( ) . locals = locals;
654647 }
648+ // done
649+ self . frame_mut ( ) . locals = locals;
655650
656651 M :: after_stack_push ( self ) ?;
657652 info ! ( "ENTERING({}) {}" , self . frame_idx( ) , self . frame( ) . instance) ;
@@ -729,6 +724,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
729724 let frame =
730725 self . stack_mut ( ) . pop ( ) . expect ( "tried to pop a stack frame, but there were none" ) ;
731726
727+ if let Some ( return_place) = frame. return_place {
728+ // Copy the return value to the caller's stack frame.
729+ let op = self . access_local ( & frame, mir:: RETURN_PLACE , None ) ?;
730+ self . copy_op ( op, return_place) ?;
731+ }
732+
732733 // Now where do we jump next?
733734
734735 // Usually we want to clean up (deallocate locals), but in a few rare cases we don't.
0 commit comments