@@ -7,7 +7,7 @@ use crate::MemFlags;
77use crate :: common:: { self , RealPredicate , IntPredicate } ;
88use crate :: traits:: * ;
99
10- use rustc:: ty:: { self , Ty , adjustment:: { PointerCast } , Instance } ;
10+ use rustc:: ty:: { self , Ty , TyCtxt , adjustment:: { PointerCast } , Instance } ;
1111use rustc:: ty:: cast:: { CastTy , IntTy } ;
1212use rustc:: ty:: layout:: { self , LayoutOf , HasTyCtxt } ;
1313use rustc:: mir;
@@ -349,8 +349,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
349349 }
350350 }
351351 ( CastTy :: Ptr ( _) , CastTy :: Ptr ( _) ) |
352- ( CastTy :: FnPtr , CastTy :: Ptr ( _) ) |
353- ( CastTy :: RPtr ( _) , CastTy :: Ptr ( _) ) =>
352+ ( CastTy :: FnPtr , CastTy :: Ptr ( _) ) =>
354353 bx. pointercast ( llval, ll_t_out) ,
355354 ( CastTy :: Ptr ( _) , CastTy :: Int ( _) ) |
356355 ( CastTy :: FnPtr , CastTy :: Int ( _) ) =>
@@ -375,24 +374,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
375374 }
376375
377376 mir:: Rvalue :: Ref ( _, bk, ref place) => {
378- let cg_place = self . codegen_place ( & mut bx, & place. as_ref ( ) ) ;
379-
380- let ty = cg_place. layout . ty ;
377+ let mk_ref = move |tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > | tcx. mk_ref (
378+ tcx. lifetimes . re_erased ,
379+ ty:: TypeAndMut { ty, mutbl : bk. to_mutbl_lossy ( ) }
380+ ) ;
381+ self . codegen_place_to_pointer ( bx, place, mk_ref)
382+ }
381383
382- // Note: places are indirect, so storing the `llval` into the
383- // destination effectively creates a reference.
384- let val = if !bx. cx ( ) . type_has_metadata ( ty) {
385- OperandValue :: Immediate ( cg_place. llval )
386- } else {
387- OperandValue :: Pair ( cg_place. llval , cg_place. llextra . unwrap ( ) )
388- } ;
389- ( bx, OperandRef {
390- val,
391- layout : self . cx . layout_of ( self . cx . tcx ( ) . mk_ref (
392- self . cx . tcx ( ) . lifetimes . re_erased ,
393- ty:: TypeAndMut { ty, mutbl : bk. to_mutbl_lossy ( ) }
394- ) ) ,
395- } )
384+ mir:: Rvalue :: AddressOf ( mutability, ref place) => {
385+ let mk_ptr = move |tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > | tcx. mk_ptr (
386+ ty:: TypeAndMut { ty, mutbl : mutability. into ( ) }
387+ ) ;
388+ self . codegen_place_to_pointer ( bx, place, mk_ptr)
396389 }
397390
398391 mir:: Rvalue :: Len ( ref place) => {
@@ -548,6 +541,30 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
548541 cg_value. len ( bx. cx ( ) )
549542 }
550543
544+ /// Codegen an `Rvalue::AddressOf` or `Rvalue::Ref`
545+ fn codegen_place_to_pointer (
546+ & mut self ,
547+ mut bx : Bx ,
548+ place : & mir:: Place < ' tcx > ,
549+ mk_ptr_ty : impl FnOnce ( TyCtxt < ' tcx > , Ty < ' tcx > ) -> Ty < ' tcx > ,
550+ ) -> ( Bx , OperandRef < ' tcx , Bx :: Value > ) {
551+ let cg_place = self . codegen_place ( & mut bx, & place. as_ref ( ) ) ;
552+
553+ let ty = cg_place. layout . ty ;
554+
555+ // Note: places are indirect, so storing the `llval` into the
556+ // destination effectively creates a reference.
557+ let val = if !bx. cx ( ) . type_has_metadata ( ty) {
558+ OperandValue :: Immediate ( cg_place. llval )
559+ } else {
560+ OperandValue :: Pair ( cg_place. llval , cg_place. llextra . unwrap ( ) )
561+ } ;
562+ ( bx, OperandRef {
563+ val,
564+ layout : self . cx . layout_of ( mk_ptr_ty ( self . cx . tcx ( ) , ty) ) ,
565+ } )
566+ }
567+
551568 pub fn codegen_scalar_binop (
552569 & mut self ,
553570 bx : & mut Bx ,
@@ -704,6 +721,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
704721 pub fn rvalue_creates_operand ( & self , rvalue : & mir:: Rvalue < ' tcx > , span : Span ) -> bool {
705722 match * rvalue {
706723 mir:: Rvalue :: Ref ( ..) |
724+ mir:: Rvalue :: AddressOf ( ..) |
707725 mir:: Rvalue :: Len ( ..) |
708726 mir:: Rvalue :: Cast ( ..) | // (*)
709727 mir:: Rvalue :: BinaryOp ( ..) |
0 commit comments