@@ -11,7 +11,10 @@ use rustc::mir::interpret::{
1111 ConstValue , Pointer , Scalar ,
1212 EvalResult , EvalErrorKind ,
1313} ;
14- use super :: { EvalContext , Machine , MemPlace , MPlaceTy , MemoryKind } ;
14+ use super :: {
15+ EvalContext , Machine , AllocMap , Allocation , AllocationExtra ,
16+ MemPlace , MPlaceTy , PlaceTy , Place , MemoryKind ,
17+ } ;
1518pub use rustc:: mir:: interpret:: ScalarMaybeUndef ;
1619
1720/// A `Value` represents a single immediate self-contained Rust value.
@@ -112,15 +115,15 @@ impl<'tcx, Tag> Immediate<Tag> {
112115// as input for binary and cast operations.
113116#[ derive( Copy , Clone , Debug ) ]
114117pub struct ImmTy < ' tcx , Tag =( ) > {
115- immediate : Immediate < Tag > ,
118+ crate imm : Immediate < Tag > , // ideally we'd make this private, but const_prop needs this
116119 pub layout : TyLayout < ' tcx > ,
117120}
118121
119122impl < ' tcx , Tag > :: std:: ops:: Deref for ImmTy < ' tcx , Tag > {
120123 type Target = Immediate < Tag > ;
121124 #[ inline( always) ]
122125 fn deref ( & self ) -> & Immediate < Tag > {
123- & self . immediate
126+ & self . imm
124127 }
125128}
126129
@@ -180,7 +183,7 @@ impl<Tag> Operand<Tag> {
180183
181184#[ derive( Copy , Clone , Debug , Hash , PartialEq , Eq ) ]
182185pub struct OpTy < ' tcx , Tag =( ) > {
183- crate op : Operand < Tag > , // ideally we'd make this private, but const_prop needs this
186+ op : Operand < Tag > ,
184187 pub layout : TyLayout < ' tcx > ,
185188}
186189
@@ -206,7 +209,7 @@ impl<'tcx, Tag> From<ImmTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
206209 #[ inline( always) ]
207210 fn from ( val : ImmTy < ' tcx , Tag > ) -> Self {
208211 OpTy {
209- op : Operand :: Immediate ( val. immediate ) ,
212+ op : Operand :: Immediate ( val. imm ) ,
210213 layout : val. layout
211214 }
212215 }
@@ -324,8 +327,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
324327 & self ,
325328 op : OpTy < ' tcx , M :: PointerTag >
326329 ) -> EvalResult < ' tcx , ImmTy < ' tcx , M :: PointerTag > > {
327- if let Ok ( immediate ) = self . try_read_immediate ( op) ? {
328- Ok ( ImmTy { immediate , layout : op. layout } )
330+ if let Ok ( imm ) = self . try_read_immediate ( op) ? {
331+ Ok ( ImmTy { imm , layout : op. layout } )
329332 } else {
330333 bug ! ( "primitive read failed for type: {:?}" , op. layout. ty) ;
331334 }
@@ -469,6 +472,22 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
469472 Ok ( OpTy { op, layout } )
470473 }
471474
475+ /// Every place can be read from, so we can turm them into an operand
476+ #[ inline( always) ]
477+ pub fn place_to_op (
478+ & self ,
479+ place : PlaceTy < ' tcx , M :: PointerTag >
480+ ) -> EvalResult < ' tcx , OpTy < ' tcx , M :: PointerTag > > {
481+ let op = match * place {
482+ Place :: Ptr ( mplace) => {
483+ Operand :: Indirect ( mplace)
484+ }
485+ Place :: Local { frame, local } =>
486+ * self . stack [ frame] . locals [ local] . access ( ) ?
487+ } ;
488+ Ok ( OpTy { op, layout : place. layout } )
489+ }
490+
472491 // Evaluate a place with the goal of reading from it. This lets us sometimes
473492 // avoid allocations.
474493 fn eval_place_to_op (
@@ -531,10 +550,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
531550 . collect ( )
532551 }
533552
534- // Used when miri runs into a constant, and by CTFE.
535- // FIXME: CTFE should use allocations, then we can make this private (embed it into
536- // `eval_operand`, ideally).
537- pub ( crate ) fn const_value_to_op (
553+ // Used when Miri runs into a constant, and (indirectly through lazy_const_to_op) by CTFE.
554+ fn const_value_to_op (
538555 & self ,
539556 val : ty:: LazyConst < ' tcx > ,
540557 ) -> EvalResult < ' tcx , Operand < M :: PointerTag > > {
@@ -666,3 +683,21 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
666683 }
667684
668685}
686+
687+ impl < ' a , ' mir , ' tcx , M > EvalContext < ' a , ' mir , ' tcx , M >
688+ where
689+ M : Machine < ' a , ' mir , ' tcx , PointerTag =( ) > ,
690+ // FIXME: Working around https://github.com/rust-lang/rust/issues/24159
691+ M :: MemoryMap : AllocMap < AllocId , ( MemoryKind < M :: MemoryKinds > , Allocation < ( ) , M :: AllocExtra > ) > ,
692+ M :: AllocExtra : AllocationExtra < ( ) , M :: MemoryExtra > ,
693+ {
694+ // FIXME: CTFE should use allocations, then we can remove this.
695+ pub ( crate ) fn lazy_const_to_op (
696+ & self ,
697+ cnst : ty:: LazyConst < ' tcx > ,
698+ ty : ty:: Ty < ' tcx > ,
699+ ) -> EvalResult < ' tcx , OpTy < ' tcx > > {
700+ let op = self . const_value_to_op ( cnst) ?;
701+ Ok ( OpTy { op, layout : self . layout_of ( ty) ? } )
702+ }
703+ }
0 commit comments