@@ -520,22 +520,22 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
520
520
trace ! ( "write_value: {:?} <- {:?}" , * dest, src_val) ;
521
521
// See if we can avoid an allocation. This is the counterpart to `try_read_value`,
522
522
// but not factored as a separate function.
523
- match dest. place {
523
+ let mplace = match dest. place {
524
524
Place :: Local { frame, local } => {
525
525
match * self . stack [ frame] . locals [ local] . access_mut ( ) ? {
526
526
Operand :: Immediate ( ref mut dest_val) => {
527
527
// Yay, we can just change the local directly.
528
528
* dest_val = src_val;
529
529
return Ok ( ( ) ) ;
530
530
} ,
531
- _ => { } ,
531
+ Operand :: Indirect ( mplace ) => mplace , // already in memory
532
532
}
533
533
} ,
534
- _ => { } ,
534
+ Place :: Ptr ( mplace ) => mplace , // already in memory
535
535
} ;
536
536
537
- // Slow path: write to memory
538
- let dest = self . force_allocation ( dest) ? ;
537
+ // This is already in memory, write there.
538
+ let dest = MPlaceTy { mplace , layout : dest. layout } ;
539
539
self . write_value_to_mplace ( src_val, dest)
540
540
}
541
541
@@ -565,7 +565,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
565
565
Value :: ScalarPair ( a_val, b_val) => {
566
566
let ( a, b) = match dest. layout . abi {
567
567
layout:: Abi :: ScalarPair ( ref a, ref b) => ( & a. value , & b. value ) ,
568
- _ => bug ! ( "write_value_to_ptr : invalid ScalarPair layout: {:#?}" , dest. layout)
568
+ _ => bug ! ( "write_value_to_mplace : invalid ScalarPair layout: {:#?}" , dest. layout)
569
569
} ;
570
570
let ( a_size, b_size) = ( a. size ( & self ) , b. size ( & self ) ) ;
571
571
let ( a_align, b_align) = ( a. align ( & self ) , b. align ( & self ) ) ;
@@ -591,8 +591,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
591
591
// Let us see if the layout is simple so we take a shortcut, avoid force_allocation.
592
592
let ( src_ptr, src_align) = match self . try_read_value ( src) ? {
593
593
Ok ( src_val) =>
594
- // Yay, we got a value that we can write directly.
595
- return self . write_value ( src_val, dest) ,
594
+ // Yay, we got a value that we can write directly. We write with the
595
+ // *source layout*, because that was used to load, and if they do not match
596
+ // this is a transmute we want to support.
597
+ return self . write_value ( src_val, PlaceTy { place : * dest, layout : src. layout } ) ,
596
598
Err ( mplace) => mplace. to_scalar_ptr_align ( ) ,
597
599
} ;
598
600
// Slow path, this does not fit into an immediate. Just memcpy.
0 commit comments