11use std:: borrow:: Cow ;
2- use std:: mem;
32
43use either:: Either ;
54use rustc_ast:: ast:: InlineAsmOptions ;
@@ -15,8 +14,8 @@ use rustc_target::abi::{self, FieldIdx};
1514use rustc_target:: spec:: abi:: Abi ;
1615
1716use super :: {
18- AllocId , FnVal , ImmTy , InterpCx , InterpResult , LocalValue , MPlaceTy , Machine , MemoryKind , OpTy ,
19- Operand , PlaceTy , Provenance , Scalar , StackPopCleanup ,
17+ AllocId , FnVal , ImmTy , InterpCx , InterpResult , MPlaceTy , Machine , OpTy , PlaceTy , Projectable ,
18+ Provenance , Scalar , StackPopCleanup ,
2019} ;
2120use crate :: fluent_generated as fluent;
2221
@@ -394,28 +393,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
394393 // did in-place of by-copy argument passing, except for pointer equality tests.
395394 let caller_arg_copy = self . copy_fn_arg ( & caller_arg) ?;
396395 if !already_live {
397- // Special handling for unsized parameters: they are harder to make live.
398- if caller_arg_copy. layout . is_unsized ( ) {
399- // `check_argument_compat` ensures that both have the same type, so we know they will use the metadata the same way.
400- assert_eq ! ( caller_arg_copy. layout. ty, callee_ty) ;
401- // We have to properly pre-allocate the memory for the callee.
402- // So let's tear down some abstractions.
403- // This all has to be in memory, there are no immediate unsized values.
404- let src = caller_arg_copy. assert_mem_place ( ) ;
405- // The destination cannot be one of these "spread args".
406- let dest_local = callee_arg. as_local ( ) . expect ( "unsized arguments cannot be spread" ) ;
407- // Allocate enough memory to hold `src`.
408- let dest_place = self . allocate_dyn ( src. layout , MemoryKind :: Stack , src. meta ) ?;
409- // Update the local to be that new place. This is essentially a "dyn-sized StorageLive".
410- let old = mem:: replace (
411- & mut self . frame_mut ( ) . locals [ dest_local] . value ,
412- LocalValue :: Live ( Operand :: Indirect ( * dest_place) ) ,
413- ) ;
414- assert ! ( matches!( old, LocalValue :: Dead ) ) ;
415- } else {
416- // Just make the local live.
417- self . storage_live ( callee_arg. as_local ( ) . unwrap ( ) ) ?;
418- }
396+ let local = callee_arg. as_local ( ) . unwrap ( ) ;
397+ let meta = caller_arg_copy. meta ( ) ;
398+ // `check_argument_compat` ensures that if metadata is needed, both have the same type,
399+ // so we know they will use the metadata the same way.
400+ assert ! ( !meta. has_meta( ) || caller_arg_copy. layout. ty == callee_ty) ;
401+
402+ self . storage_live_dyn ( local, meta) ?;
419403 }
420404 // Now we can finally actually evaluate the callee place.
421405 let callee_arg = self . eval_place ( * callee_arg) ?;
0 commit comments