1515use std:: convert:: TryFrom ;
1616use std:: hash:: Hash ;
1717
18+ use rustc:: hir;
1819use rustc:: mir;
1920use rustc:: ty:: { self , Ty } ;
2021use rustc:: ty:: layout:: { self , Size , Align , LayoutOf , TyLayout , HasDataLayout } ;
@@ -270,26 +271,31 @@ where
270271 & self ,
271272 val : ValTy < ' tcx , M :: PointerTag > ,
272273 ) -> EvalResult < ' tcx , MPlaceTy < ' tcx , M :: PointerTag > > {
274+ let pointee_type = val. layout . ty . builtin_deref ( true ) . unwrap ( ) . ty ;
275+ let layout = self . layout_of ( pointee_type) ?;
276+
277+ let align = layout. align ;
278+ let meta = val. to_meta ( ) ?;
279+
273280 let ptr = match val. to_scalar_ptr ( ) ? {
274281 Scalar :: Ptr ( ptr) if M :: ENABLE_PTR_TRACKING_HOOKS => {
275282 // Machine might want to track the `*` operator
276- let tag = M :: tag_dereference ( self , ptr, val. layout . ty ) ?;
283+ let ( size, _) = self . size_and_align_of ( meta, layout) ?
284+ . expect ( "ref_to_mplace cannot determine size" ) ;
285+ let mutbl = match val. layout . ty . sty {
286+ // `builtin_deref` considers boxes immutable, that's useless for our purposes
287+ ty:: Ref ( _, _, mutbl) => Some ( mutbl) ,
288+ ty:: Adt ( def, _) if def. is_box ( ) => Some ( hir:: MutMutable ) ,
289+ ty:: RawPtr ( _) => None ,
290+ _ => bug ! ( "Unexpected pointer type {}" , val. layout. ty. sty) ,
291+ } ;
292+ let tag = M :: tag_dereference ( self , ptr, pointee_type, size, mutbl) ?;
277293 Scalar :: Ptr ( Pointer :: new_with_tag ( ptr. alloc_id , ptr. offset , tag) )
278294 }
279295 other => other,
280296 } ;
281297
282- let pointee_type = val. layout . ty . builtin_deref ( true ) . unwrap ( ) . ty ;
283- let layout = self . layout_of ( pointee_type) ?;
284- let align = layout. align ;
285-
286- let mplace = match * val {
287- Value :: Scalar ( _) =>
288- MemPlace { ptr, align, meta : None } ,
289- Value :: ScalarPair ( _, meta) =>
290- MemPlace { ptr, align, meta : Some ( meta. not_undef ( ) ?) } ,
291- } ;
292- Ok ( MPlaceTy { mplace, layout } )
298+ Ok ( MPlaceTy { mplace : MemPlace { ptr, align, meta } , layout } )
293299 }
294300
295301 /// Turn a mplace into a (thin or fat) pointer, as a reference, pointing to the same space.
@@ -304,7 +310,12 @@ where
304310 // Machine might want to track the `&` operator
305311 let ( size, _) = self . size_and_align_of_mplace ( place) ?
306312 . expect ( "create_ref cannot determine size" ) ;
307- let tag = M :: tag_reference ( self , ptr, place. layout . ty , size, borrow_kind) ?;
313+ let mutbl = match borrow_kind {
314+ Some ( mir:: BorrowKind :: Mut { .. } ) => Some ( hir:: MutMutable ) ,
315+ Some ( _) => Some ( hir:: MutImmutable ) ,
316+ None => None ,
317+ } ;
318+ let tag = M :: tag_reference ( self , ptr, place. layout . ty , size, mutbl) ?;
308319 Scalar :: Ptr ( Pointer :: new_with_tag ( ptr. alloc_id , ptr. offset , tag) )
309320 } ,
310321 other => other,
0 commit comments