@@ -11,7 +11,10 @@ use rustc::mir::interpret::{
11
11
ConstValue , Pointer , Scalar ,
12
12
EvalResult , EvalErrorKind ,
13
13
} ;
14
- use super :: { EvalContext , Machine , MemPlace , MPlaceTy , MemoryKind } ;
14
+ use super :: {
15
+ EvalContext , Machine , AllocMap , Allocation , AllocationExtra ,
16
+ MemPlace , MPlaceTy , PlaceTy , Place , MemoryKind ,
17
+ } ;
15
18
pub use rustc:: mir:: interpret:: ScalarMaybeUndef ;
16
19
17
20
/// A `Value` represents a single immediate self-contained Rust value.
@@ -112,15 +115,15 @@ impl<'tcx, Tag> Immediate<Tag> {
112
115
// as input for binary and cast operations.
113
116
#[ derive( Copy , Clone , Debug ) ]
114
117
pub struct ImmTy < ' tcx , Tag =( ) > {
115
- immediate : Immediate < Tag > ,
118
+ crate imm : Immediate < Tag > , // ideally we'd make this private, but const_prop needs this
116
119
pub layout : TyLayout < ' tcx > ,
117
120
}
118
121
119
122
impl < ' tcx , Tag > :: std:: ops:: Deref for ImmTy < ' tcx , Tag > {
120
123
type Target = Immediate < Tag > ;
121
124
#[ inline( always) ]
122
125
fn deref ( & self ) -> & Immediate < Tag > {
123
- & self . immediate
126
+ & self . imm
124
127
}
125
128
}
126
129
@@ -180,7 +183,7 @@ impl<Tag> Operand<Tag> {
180
183
181
184
#[ derive( Copy , Clone , Debug , Hash , PartialEq , Eq ) ]
182
185
pub struct OpTy < ' tcx , Tag =( ) > {
183
- crate op : Operand < Tag > , // ideally we'd make this private, but const_prop needs this
186
+ op : Operand < Tag > ,
184
187
pub layout : TyLayout < ' tcx > ,
185
188
}
186
189
@@ -206,7 +209,7 @@ impl<'tcx, Tag> From<ImmTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
206
209
#[ inline( always) ]
207
210
fn from ( val : ImmTy < ' tcx , Tag > ) -> Self {
208
211
OpTy {
209
- op : Operand :: Immediate ( val. immediate ) ,
212
+ op : Operand :: Immediate ( val. imm ) ,
210
213
layout : val. layout
211
214
}
212
215
}
@@ -324,8 +327,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
324
327
& self ,
325
328
op : OpTy < ' tcx , M :: PointerTag >
326
329
) -> 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 } )
329
332
} else {
330
333
bug ! ( "primitive read failed for type: {:?}" , op. layout. ty) ;
331
334
}
@@ -469,6 +472,22 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
469
472
Ok ( OpTy { op, layout } )
470
473
}
471
474
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
+
472
491
// Evaluate a place with the goal of reading from it. This lets us sometimes
473
492
// avoid allocations.
474
493
fn eval_place_to_op (
@@ -531,10 +550,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
531
550
. collect ( )
532
551
}
533
552
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 (
538
555
& self ,
539
556
val : ty:: LazyConst < ' tcx > ,
540
557
) -> EvalResult < ' tcx , Operand < M :: PointerTag > > {
@@ -666,3 +683,21 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
666
683
}
667
684
668
685
}
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