@@ -30,6 +30,13 @@ pub trait Value<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: Copy
30
30
// Create this from an `MPlaceTy`.
31
31
fn from_mem_place ( MPlaceTy < ' tcx , M :: PointerTag > ) -> Self ;
32
32
33
+ // Read the current enum discriminant, and downcast to that. Also return the
34
+ // variant index.
35
+ fn project_downcast (
36
+ self ,
37
+ ectx : & EvalContext < ' a , ' mir , ' tcx , M >
38
+ ) -> EvalResult < ' tcx , ( Self , usize ) > ;
39
+
33
40
// Project to the n-th field.
34
41
fn project_field (
35
42
self ,
@@ -60,6 +67,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
60
67
mplace. into ( )
61
68
}
62
69
70
+ #[ inline( always) ]
71
+ fn project_downcast (
72
+ self ,
73
+ ectx : & EvalContext < ' a , ' mir , ' tcx , M >
74
+ ) -> EvalResult < ' tcx , ( Self , usize ) > {
75
+ let idx = ectx. read_discriminant ( self ) ?. 1 ;
76
+ Ok ( ( ectx. operand_downcast ( self , idx) ?, idx) )
77
+ }
78
+
63
79
#[ inline( always) ]
64
80
fn project_field (
65
81
self ,
@@ -90,6 +106,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
90
106
mplace
91
107
}
92
108
109
+ #[ inline( always) ]
110
+ fn project_downcast (
111
+ self ,
112
+ ectx : & EvalContext < ' a , ' mir , ' tcx , M >
113
+ ) -> EvalResult < ' tcx , ( Self , usize ) > {
114
+ let idx = ectx. read_discriminant ( self . into ( ) ) ?. 1 ;
115
+ Ok ( ( ectx. mplace_downcast ( self , idx) ?, idx) )
116
+ }
117
+
93
118
#[ inline( always) ]
94
119
fn project_field (
95
120
self ,
@@ -120,6 +145,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
120
145
mplace. into ( )
121
146
}
122
147
148
+ #[ inline( always) ]
149
+ fn project_downcast (
150
+ self ,
151
+ ectx : & EvalContext < ' a , ' mir , ' tcx , M >
152
+ ) -> EvalResult < ' tcx , ( Self , usize ) > {
153
+ let idx = ectx. read_discriminant ( ectx. place_to_op ( self ) ?) ?. 1 ;
154
+ Ok ( ( ectx. place_downcast ( self , idx) ?, idx) )
155
+ }
156
+
123
157
#[ inline( always) ]
124
158
fn project_field (
125
159
self ,
@@ -155,12 +189,6 @@ pub trait ValueVisitor<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: fmt::Debug +
155
189
field : usize ,
156
190
) -> EvalResult < ' tcx > ;
157
191
158
- // This is an enum, downcast it to whatever the current variant is.
159
- // (We do this here and not in `Value` to keep error handling
160
- // under control of th visitor.)
161
- fn downcast_enum ( & mut self , ectx : & EvalContext < ' a , ' mir , ' tcx , M > )
162
- -> EvalResult < ' tcx > ;
163
-
164
192
// A chance for the visitor to do special (different or more efficient) handling for some
165
193
// array types. Return `true` if the value was handled and we should return.
166
194
#[ inline]
@@ -202,8 +230,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
202
230
match v. layout ( ) . variants {
203
231
layout:: Variants :: NicheFilling { .. } |
204
232
layout:: Variants :: Tagged { .. } => {
205
- v. downcast_enum ( self ) ?;
206
- trace ! ( "variant layout: {:#?}" , v. layout( ) ) ;
233
+ let ( inner, idx) = v. value ( ) . project_downcast ( self ) ?;
234
+ trace ! ( "variant layout: {:#?}" , inner. layout( ) ) ;
235
+ // recurse with the inner type
236
+ return v. visit_field ( self , inner, idx) ;
207
237
}
208
238
layout:: Variants :: Single { .. } => { }
209
239
}
@@ -215,6 +245,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
215
245
// immediate trait objects are not a thing
216
246
let dest = v. value ( ) . force_allocation ( self ) ?;
217
247
let inner = self . unpack_dyn_trait ( dest) ?. 1 ;
248
+ trace ! ( "dyn object layout: {:#?}" , inner. layout) ;
218
249
// recurse with the inner type
219
250
return v. visit_field ( self , Value :: from_mem_place ( inner) , 0 ) ;
220
251
} ,
0 commit comments