@@ -10,7 +10,7 @@ use rustc::mir::interpret::{
10
10
} ;
11
11
12
12
use super :: {
13
- Machine , EvalContext , MPlaceTy , OpTy ,
13
+ Machine , EvalContext , MPlaceTy , PlaceTy , OpTy ,
14
14
} ;
15
15
16
16
// 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
21
21
// Get this value's layout.
22
22
fn layout ( & self ) -> TyLayout < ' tcx > ;
23
23
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 > > ;
26
29
27
- // Create this from an `MPlaceTy`
30
+ // Create this from an `MPlaceTy`.
28
31
fn from_mem_place ( MPlaceTy < ' tcx , M :: PointerTag > ) -> Self ;
29
32
30
- // Project to the n-th field
33
+ // Project to the n-th field.
31
34
fn project_field (
32
35
self ,
33
36
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>
45
48
}
46
49
47
50
#[ 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 ( ) )
50
56
}
51
57
52
58
#[ inline( always) ]
@@ -63,6 +69,66 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
63
69
ectx. operand_field ( self , field)
64
70
}
65
71
}
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
+ }
66
132
67
133
// How to traverse a value and what to do when we are at the leaves.
68
134
pub 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>
135
201
// If it is a trait object, switch to the actual type that was used to create it.
136
202
match v. layout ( ) . ty . sty {
137
203
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 ) ?;
139
206
let inner = self . unpack_dyn_trait ( dest) ?. 1 ;
140
207
// recurse with the inner type
141
208
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>
201
268
MPlaceTy :: dangling ( v. layout ( ) , self )
202
269
} else {
203
270
// non-ZST array/slice/str cannot be immediate
204
- v. value ( ) . to_mem_place ( )
271
+ v. value ( ) . force_allocation ( self ) ?
205
272
} ;
206
273
// Now iterate over it.
207
274
for ( i, field) in self . mplace_array_fields ( mplace) ?. enumerate ( ) {
0 commit comments