@@ -278,42 +278,34 @@ where
278278 let meta = val. to_meta ( ) ?;
279279 let ptr = val. to_scalar_ptr ( ) ?;
280280 let mplace = MemPlace { ptr, align, meta } ;
281+ let mut mplace = MPlaceTy { mplace, layout } ;
281282 // Pointer tag tracking might want to adjust the tag.
282- let mplace = if M :: ENABLE_PTR_TRACKING_HOOKS {
283- let ( size, _) = self . size_and_align_of ( meta, layout) ?
284- // for extern types, just cover what we can
285- . unwrap_or_else ( || layout. size_and_align ( ) ) ;
283+ if M :: ENABLE_PTR_TRACKING_HOOKS {
286284 let mutbl = match val. layout . ty . sty {
287285 // `builtin_deref` considers boxes immutable, that's useless for our purposes
288286 ty:: Ref ( _, _, mutbl) => Some ( mutbl) ,
289287 ty:: Adt ( def, _) if def. is_box ( ) => Some ( hir:: MutMutable ) ,
290288 ty:: RawPtr ( _) => None ,
291289 _ => bug ! ( "Unexpected pointer type {}" , val. layout. ty. sty) ,
292290 } ;
293- M :: tag_dereference ( self , mplace, pointee_type, size, mutbl) ?
294- } else {
295- mplace
296- } ;
297- Ok ( MPlaceTy { mplace, layout } )
291+ mplace. mplace . ptr = M :: tag_dereference ( self , mplace, mutbl) ?;
292+ }
293+ // Done
294+ Ok ( mplace)
298295 }
299296
300297 /// Turn a mplace into a (thin or fat) pointer, as a reference, pointing to the same space.
301298 /// This is the inverse of `ref_to_mplace`.
302299 /// `mutbl` indicates whether we are create a shared or mutable ref, or a raw pointer (`None`).
303300 pub fn create_ref (
304301 & mut self ,
305- place : MPlaceTy < ' tcx , M :: PointerTag > ,
302+ mut place : MPlaceTy < ' tcx , M :: PointerTag > ,
306303 mutbl : Option < hir:: Mutability > ,
307304 ) -> EvalResult < ' tcx , Value < M :: PointerTag > > {
308305 // Pointer tag tracking might want to adjust the tag
309- let place = if M :: ENABLE_PTR_TRACKING_HOOKS {
310- let ( size, _) = self . size_and_align_of_mplace ( place) ?
311- // for extern types, just cover what we can
312- . unwrap_or_else ( || place. layout . size_and_align ( ) ) ;
313- M :: tag_reference ( self , * place, place. layout . ty , size, mutbl) ?
314- } else {
315- * place
316- } ;
306+ if M :: ENABLE_PTR_TRACKING_HOOKS {
307+ place. mplace . ptr = M :: tag_reference ( self , place, mutbl) ?
308+ }
317309 Ok ( match place. meta {
318310 None => Value :: Scalar ( place. ptr . into ( ) ) ,
319311 Some ( meta) => Value :: ScalarPair ( place. ptr . into ( ) , meta. into ( ) ) ,
@@ -489,6 +481,8 @@ where
489481
490482 /// Get the place of a field inside the place, and also the field's type.
491483 /// Just a convenience function, but used quite a bit.
484+ /// This is the only projection that might have a side-effect: We cannot project
485+ /// into the field of a local `ScalarPair`, we have to first allocate it.
492486 pub fn place_field (
493487 & mut self ,
494488 base : PlaceTy < ' tcx , M :: PointerTag > ,
@@ -501,7 +495,7 @@ where
501495 }
502496
503497 pub fn place_downcast (
504- & mut self ,
498+ & self ,
505499 base : PlaceTy < ' tcx , M :: PointerTag > ,
506500 variant : usize ,
507501 ) -> EvalResult < ' tcx , PlaceTy < ' tcx , M :: PointerTag > > {
@@ -510,7 +504,7 @@ where
510504 Place :: Ptr ( mplace) =>
511505 self . mplace_downcast ( MPlaceTy { mplace, layout : base. layout } , variant) ?. into ( ) ,
512506 Place :: Local { .. } => {
513- let layout = base. layout . for_variant ( & self , variant) ;
507+ let layout = base. layout . for_variant ( self , variant) ;
514508 PlaceTy { layout, ..base }
515509 }
516510 } )
@@ -643,7 +637,7 @@ where
643637
644638 if M :: enforce_validity ( self ) {
645639 // Data got changed, better make sure it matches the type!
646- self . validate_operand ( self . place_to_op ( dest) ?, & mut vec ! [ ] , None , /*const_mode*/ false ) ?;
640+ self . validate_operand ( self . place_to_op ( dest) ?, vec ! [ ] , None , /*const_mode*/ false ) ?;
647641 }
648642
649643 Ok ( ( ) )
@@ -765,7 +759,7 @@ where
765759
766760 if M :: enforce_validity ( self ) {
767761 // Data got changed, better make sure it matches the type!
768- self . validate_operand ( self . place_to_op ( dest) ?, & mut vec ! [ ] , None , /*const_mode*/ false ) ?;
762+ self . validate_operand ( self . place_to_op ( dest) ?, vec ! [ ] , None , /*const_mode*/ false ) ?;
769763 }
770764
771765 Ok ( ( ) )
@@ -843,7 +837,7 @@ where
843837
844838 if M :: enforce_validity ( self ) {
845839 // Data got changed, better make sure it matches the type!
846- self . validate_operand ( dest. into ( ) , & mut vec ! [ ] , None , /*const_mode*/ false ) ?;
840+ self . validate_operand ( dest. into ( ) , vec ! [ ] , None , /*const_mode*/ false ) ?;
847841 }
848842
849843 Ok ( ( ) )
0 commit comments