@@ -577,7 +577,7 @@ where
577
577
src : Immediate < M :: Provenance > ,
578
578
dest : & PlaceTy < ' tcx , M :: Provenance > ,
579
579
) -> InterpResult < ' tcx > {
580
- assert ! ( dest. layout. is_sized( ) , "Cannot write unsized data" ) ;
580
+ assert ! ( dest. layout. is_sized( ) , "Cannot write unsized immediate data" ) ;
581
581
trace ! ( "write_immediate: {:?} <- {:?}: {}" , * dest, src, dest. layout. ty) ;
582
582
583
583
// See if we can avoid an allocation. This is the counterpart to `read_immediate_raw`,
@@ -591,9 +591,34 @@ where
591
591
* self . force_allocation ( dest) ?
592
592
} else {
593
593
match M :: access_local_mut ( self , frame, local) ? {
594
- Operand :: Immediate ( local ) => {
594
+ Operand :: Immediate ( local_val ) => {
595
595
// Local can be updated in-place.
596
- * local = src;
596
+ * local_val = src;
597
+ // Double-check that the value we are storing and the local fit to each other.
598
+ // (*After* doing the update for borrow checker reasons.)
599
+ if cfg ! ( debug_assertions) {
600
+ let local_layout =
601
+ self . layout_of_local ( & self . stack ( ) [ frame] , local, None ) ?;
602
+ match ( src, local_layout. abi ) {
603
+ ( Immediate :: Scalar ( scalar) , Abi :: Scalar ( s) ) => {
604
+ assert_eq ! ( scalar. size( ) , s. size( self ) )
605
+ }
606
+ (
607
+ Immediate :: ScalarPair ( a_val, b_val) ,
608
+ Abi :: ScalarPair ( a, b) ,
609
+ ) => {
610
+ assert_eq ! ( a_val. size( ) , a. size( self ) ) ;
611
+ assert_eq ! ( b_val. size( ) , b. size( self ) ) ;
612
+ }
613
+ ( Immediate :: Uninit , _) => { }
614
+ ( src, abi) => {
615
+ bug ! (
616
+ "value {src:?} cannot be written into local with type {} (ABI {abi:?})" ,
617
+ local_layout. ty
618
+ )
619
+ }
620
+ } ;
621
+ }
597
622
return Ok ( ( ) ) ;
598
623
}
599
624
Operand :: Indirect ( mplace) => {
0 commit comments