@@ -577,7 +577,7 @@ where
577577 src : Immediate < M :: Provenance > ,
578578 dest : & PlaceTy < ' tcx , M :: Provenance > ,
579579 ) -> InterpResult < ' tcx > {
580- assert ! ( dest. layout. is_sized( ) , "Cannot write unsized data" ) ;
580+ assert ! ( dest. layout. is_sized( ) , "Cannot write unsized immediate data" ) ;
581581 trace ! ( "write_immediate: {:?} <- {:?}: {}" , * dest, src, dest. layout. ty) ;
582582
583583 // See if we can avoid an allocation. This is the counterpart to `read_immediate_raw`,
@@ -591,9 +591,34 @@ where
591591 * self . force_allocation ( dest) ?
592592 } else {
593593 match M :: access_local_mut ( self , frame, local) ? {
594- Operand :: Immediate ( local ) => {
594+ Operand :: Immediate ( local_val ) => {
595595 // 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+ }
597622 return Ok ( ( ) ) ;
598623 }
599624 Operand :: Indirect ( mplace) => {
0 commit comments