@@ -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;
@@ -349,8 +349,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
349
349
}
350
350
}
351
351
( CastTy :: Ptr ( _) , CastTy :: Ptr ( _) ) |
352
- ( CastTy :: FnPtr , CastTy :: Ptr ( _) ) |
353
- ( CastTy :: RPtr ( _) , CastTy :: Ptr ( _) ) =>
352
+ ( CastTy :: FnPtr , CastTy :: Ptr ( _) ) =>
354
353
bx. pointercast ( llval, ll_t_out) ,
355
354
( CastTy :: Ptr ( _) , CastTy :: Int ( _) ) |
356
355
( CastTy :: FnPtr , CastTy :: Int ( _) ) =>
@@ -375,24 +374,18 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
375
374
}
376
375
377
376
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
+ }
381
383
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)
396
389
}
397
390
398
391
mir:: Rvalue :: Len ( ref place) => {
@@ -548,6 +541,30 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
548
541
cg_value. len ( bx. cx ( ) )
549
542
}
550
543
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
+
551
568
pub fn codegen_scalar_binop (
552
569
& mut self ,
553
570
bx : & mut Bx ,
@@ -704,6 +721,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
704
721
pub fn rvalue_creates_operand ( & self , rvalue : & mir:: Rvalue < ' tcx > , span : Span ) -> bool {
705
722
match * rvalue {
706
723
mir:: Rvalue :: Ref ( ..) |
724
+ mir:: Rvalue :: AddressOf ( ..) |
707
725
mir:: Rvalue :: Len ( ..) |
708
726
mir:: Rvalue :: Cast ( ..) | // (*)
709
727
mir:: Rvalue :: BinaryOp ( ..) |
0 commit comments