@@ -10,7 +10,7 @@ use rustc::mir::interpret::{
1010} ;
1111
1212use super :: {
13- Machine , EvalContext , MPlaceTy , OpTy ,
13+ Machine , EvalContext , MPlaceTy , PlaceTy , OpTy ,
1414} ;
1515
1616// A thing that we can project into, and that has a layout.
@@ -21,13 +21,16 @@ pub trait Value<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: Copy
2121 // Get this value's layout.
2222 fn layout ( & self ) -> TyLayout < ' tcx > ;
2323
24- // Get the underlying `MPlaceTy`, or panic if there is no such thing.
25- fn to_mem_place ( self ) -> MPlaceTy < ' tcx , M :: PointerTag > ;
24+ // Make this a `MPlaceTy`, or panic if that's not possible.
25+ fn force_allocation (
26+ self ,
27+ ectx : & mut EvalContext < ' a , ' mir , ' tcx , M > ,
28+ ) -> EvalResult < ' tcx , MPlaceTy < ' tcx , M :: PointerTag > > ;
2629
27- // Create this from an `MPlaceTy`
30+ // Create this from an `MPlaceTy`.
2831 fn from_mem_place ( MPlaceTy < ' tcx , M :: PointerTag > ) -> Self ;
2932
30- // Project to the n-th field
33+ // Project to the n-th field.
3134 fn project_field (
3235 self ,
3336 ectx : & mut EvalContext < ' a , ' mir , ' tcx , M > ,
@@ -45,8 +48,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
4548 }
4649
4750 #[ inline( always) ]
48- fn to_mem_place ( self ) -> MPlaceTy < ' tcx , M :: PointerTag > {
49- self . to_mem_place ( )
51+ fn force_allocation (
52+ self ,
53+ _ectx : & mut EvalContext < ' a , ' mir , ' tcx , M > ,
54+ ) -> EvalResult < ' tcx , MPlaceTy < ' tcx , M :: PointerTag > > {
55+ Ok ( self . to_mem_place ( ) )
5056 }
5157
5258 #[ inline( always) ]
@@ -63,6 +69,66 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
6369 ectx. operand_field ( self , field)
6470 }
6571}
72+ impl < ' a , ' mir , ' tcx , M : Machine < ' a , ' mir , ' tcx > > Value < ' a , ' mir , ' tcx , M >
73+ for MPlaceTy < ' tcx , M :: PointerTag >
74+ {
75+ #[ inline( always) ]
76+ fn layout ( & self ) -> TyLayout < ' tcx > {
77+ self . layout
78+ }
79+
80+ #[ inline( always) ]
81+ fn force_allocation (
82+ self ,
83+ _ectx : & mut EvalContext < ' a , ' mir , ' tcx , M > ,
84+ ) -> EvalResult < ' tcx , MPlaceTy < ' tcx , M :: PointerTag > > {
85+ Ok ( self )
86+ }
87+
88+ #[ inline( always) ]
89+ fn from_mem_place ( mplace : MPlaceTy < ' tcx , M :: PointerTag > ) -> Self {
90+ mplace
91+ }
92+
93+ #[ inline( always) ]
94+ fn project_field (
95+ self ,
96+ ectx : & mut EvalContext < ' a , ' mir , ' tcx , M > ,
97+ field : u64 ,
98+ ) -> EvalResult < ' tcx , Self > {
99+ ectx. mplace_field ( self , field)
100+ }
101+ }
102+ impl < ' a , ' mir , ' tcx , M : Machine < ' a , ' mir , ' tcx > > Value < ' a , ' mir , ' tcx , M >
103+ for PlaceTy < ' tcx , M :: PointerTag >
104+ {
105+ #[ inline( always) ]
106+ fn layout ( & self ) -> TyLayout < ' tcx > {
107+ self . layout
108+ }
109+
110+ #[ inline( always) ]
111+ fn force_allocation (
112+ self ,
113+ ectx : & mut EvalContext < ' a , ' mir , ' tcx , M > ,
114+ ) -> EvalResult < ' tcx , MPlaceTy < ' tcx , M :: PointerTag > > {
115+ ectx. force_allocation ( self )
116+ }
117+
118+ #[ inline( always) ]
119+ fn from_mem_place ( mplace : MPlaceTy < ' tcx , M :: PointerTag > ) -> Self {
120+ mplace. into ( )
121+ }
122+
123+ #[ inline( always) ]
124+ fn project_field (
125+ self ,
126+ ectx : & mut EvalContext < ' a , ' mir , ' tcx , M > ,
127+ field : u64 ,
128+ ) -> EvalResult < ' tcx , Self > {
129+ ectx. place_field ( self , field)
130+ }
131+ }
66132
67133// How to traverse a value and what to do when we are at the leaves.
68134pub trait ValueVisitor < ' a , ' mir , ' tcx , M : Machine < ' a , ' mir , ' tcx > > : fmt:: Debug {
@@ -135,7 +201,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
135201 // If it is a trait object, switch to the actual type that was used to create it.
136202 match v. layout ( ) . ty . sty {
137203 ty:: Dynamic ( ..) => {
138- let dest = v. value ( ) . to_mem_place ( ) ; // immediate trait objects are not a thing
204+ // immediate trait objects are not a thing
205+ let dest = v. value ( ) . force_allocation ( self ) ?;
139206 let inner = self . unpack_dyn_trait ( dest) ?. 1 ;
140207 // recurse with the inner type
141208 return v. with_field ( Value :: from_mem_place ( inner) , 0 , |v| self . visit_value ( v) ) ;
@@ -201,7 +268,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
201268 MPlaceTy :: dangling ( v. layout ( ) , & self )
202269 } else {
203270 // non-ZST array/slice/str cannot be immediate
204- v. value ( ) . to_mem_place ( )
271+ v. value ( ) . force_allocation ( self ) ?
205272 } ;
206273 // Now iterate over it.
207274 for ( i, field) in self . mplace_array_fields ( mplace) ?. enumerate ( ) {
0 commit comments