@@ -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;
@@ -342,8 +342,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
342342 }
343343 }
344344 ( CastTy :: Ptr ( _) , CastTy :: Ptr ( _) ) |
345- ( CastTy :: FnPtr , CastTy :: Ptr ( _) ) |
346- ( CastTy :: RPtr ( _) , CastTy :: Ptr ( _) ) =>
345+ ( CastTy :: FnPtr , CastTy :: Ptr ( _) ) =>
347346 bx. pointercast ( llval, ll_t_out) ,
348347 ( CastTy :: Ptr ( _) , CastTy :: Int ( _) ) |
349348 ( CastTy :: FnPtr , CastTy :: Int ( _) ) =>
@@ -370,24 +369,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
370369 }
371370
372371 mir:: Rvalue :: Ref ( _, bk, ref place) => {
373- let cg_place = self . codegen_place ( & mut bx, & place. as_ref ( ) ) ;
374-
375- let ty = cg_place. layout . ty ;
372+ let mk_ref = move |tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > | tcx. mk_ref (
373+ tcx. lifetimes . re_erased ,
374+ ty:: TypeAndMut { ty, mutbl : bk. to_mutbl_lossy ( ) }
375+ ) ;
376+ self . codegen_place_to_pointer ( bx, place, mk_ref)
377+ }
376378
377- // Note: places are indirect, so storing the `llval` into the
378- // destination effectively creates a reference.
379- let val = if !bx. cx ( ) . type_has_metadata ( ty) {
380- OperandValue :: Immediate ( cg_place. llval )
381- } else {
382- OperandValue :: Pair ( cg_place. llval , cg_place. llextra . unwrap ( ) )
383- } ;
384- ( bx, OperandRef {
385- val,
386- layout : self . cx . layout_of ( self . cx . tcx ( ) . mk_ref (
387- self . cx . tcx ( ) . lifetimes . re_erased ,
388- ty:: TypeAndMut { ty, mutbl : bk. to_mutbl_lossy ( ) }
389- ) ) ,
390- } )
379+ mir:: Rvalue :: AddressOf ( mutability, ref place) => {
380+ let mk_ptr = move |tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > | tcx. mk_ptr (
381+ ty:: TypeAndMut { ty, mutbl : mutability. into ( ) }
382+ ) ;
383+ self . codegen_place_to_pointer ( bx, place, mk_ptr)
391384 }
392385
393386 mir:: Rvalue :: Len ( ref place) => {
@@ -543,6 +536,30 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
543536 cg_value. len ( bx. cx ( ) )
544537 }
545538
539+ /// Codegen an `Rvalue::AddressOf` or `Rvalue::Ref`
540+ fn codegen_place_to_pointer (
541+ & mut self ,
542+ mut bx : Bx ,
543+ place : & mir:: Place < ' tcx > ,
544+ mk_ptr_ty : impl FnOnce ( TyCtxt < ' tcx > , Ty < ' tcx > ) -> Ty < ' tcx > ,
545+ ) -> ( Bx , OperandRef < ' tcx , Bx :: Value > ) {
546+ let cg_place = self . codegen_place ( & mut bx, & place. as_ref ( ) ) ;
547+
548+ let ty = cg_place. layout . ty ;
549+
550+ // Note: places are indirect, so storing the `llval` into the
551+ // destination effectively creates a reference.
552+ let val = if !bx. cx ( ) . type_has_metadata ( ty) {
553+ OperandValue :: Immediate ( cg_place. llval )
554+ } else {
555+ OperandValue :: Pair ( cg_place. llval , cg_place. llextra . unwrap ( ) )
556+ } ;
557+ ( bx, OperandRef {
558+ val,
559+ layout : self . cx . layout_of ( mk_ptr_ty ( self . cx . tcx ( ) , ty) ) ,
560+ } )
561+ }
562+
546563 pub fn codegen_scalar_binop (
547564 & mut self ,
548565 bx : & mut Bx ,
@@ -699,6 +716,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
699716 pub fn rvalue_creates_operand ( & self , rvalue : & mir:: Rvalue < ' tcx > , span : Span ) -> bool {
700717 match * rvalue {
701718 mir:: Rvalue :: Ref ( ..) |
719+ mir:: Rvalue :: AddressOf ( ..) |
702720 mir:: Rvalue :: Len ( ..) |
703721 mir:: Rvalue :: Cast ( ..) | // (*)
704722 mir:: Rvalue :: BinaryOp ( ..) |
0 commit comments