@@ -7,7 +7,7 @@ use crate::MemFlags;
7
7
use crate :: common:: { self , RealPredicate , IntPredicate } ;
8
8
use crate :: traits:: * ;
9
9
10
- use rustc:: ty:: { self , Ty , adjustment:: { PointerCast } , Instance } ;
10
+ use rustc:: ty:: { self , Ty , TyCtxt , adjustment:: { PointerCast } , Instance } ;
11
11
use rustc:: ty:: cast:: { CastTy , IntTy } ;
12
12
use rustc:: ty:: layout:: { self , LayoutOf , HasTyCtxt } ;
13
13
use rustc:: mir;
@@ -342,8 +342,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
342
342
}
343
343
}
344
344
( CastTy :: Ptr ( _) , CastTy :: Ptr ( _) ) |
345
- ( CastTy :: FnPtr , CastTy :: Ptr ( _) ) |
346
- ( CastTy :: RPtr ( _) , CastTy :: Ptr ( _) ) =>
345
+ ( CastTy :: FnPtr , CastTy :: Ptr ( _) ) =>
347
346
bx. pointercast ( llval, ll_t_out) ,
348
347
( CastTy :: Ptr ( _) , CastTy :: Int ( _) ) |
349
348
( CastTy :: FnPtr , CastTy :: Int ( _) ) =>
@@ -370,24 +369,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
370
369
}
371
370
372
371
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
+ }
376
378
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)
391
384
}
392
385
393
386
mir:: Rvalue :: Len ( ref place) => {
@@ -543,6 +536,30 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
543
536
cg_value. len ( bx. cx ( ) )
544
537
}
545
538
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
+
546
563
pub fn codegen_scalar_binop (
547
564
& mut self ,
548
565
bx : & mut Bx ,
@@ -699,6 +716,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
699
716
pub fn rvalue_creates_operand ( & self , rvalue : & mir:: Rvalue < ' tcx > , span : Span ) -> bool {
700
717
match * rvalue {
701
718
mir:: Rvalue :: Ref ( ..) |
719
+ mir:: Rvalue :: AddressOf ( ..) |
702
720
mir:: Rvalue :: Len ( ..) |
703
721
mir:: Rvalue :: Cast ( ..) | // (*)
704
722
mir:: Rvalue :: BinaryOp ( ..) |
0 commit comments