@@ -30,6 +30,13 @@ pub trait Value<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: Copy
3030 // Create this from an `MPlaceTy`.
3131 fn from_mem_place ( MPlaceTy < ' tcx , M :: PointerTag > ) -> Self ;
3232
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+
3340 // Project to the n-th field.
3441 fn project_field (
3542 self ,
@@ -60,6 +67,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
6067 mplace. into ( )
6168 }
6269
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+
6379 #[ inline( always) ]
6480 fn project_field (
6581 self ,
@@ -90,6 +106,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
90106 mplace
91107 }
92108
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+
93118 #[ inline( always) ]
94119 fn project_field (
95120 self ,
@@ -120,6 +145,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
120145 mplace. into ( )
121146 }
122147
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+
123157 #[ inline( always) ]
124158 fn project_field (
125159 self ,
@@ -155,12 +189,6 @@ pub trait ValueVisitor<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: fmt::Debug +
155189 field : usize ,
156190 ) -> EvalResult < ' tcx > ;
157191
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-
164192 // A chance for the visitor to do special (different or more efficient) handling for some
165193 // array types. Return `true` if the value was handled and we should return.
166194 #[ inline]
@@ -202,8 +230,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
202230 match v. layout ( ) . variants {
203231 layout:: Variants :: NicheFilling { .. } |
204232 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) ;
207237 }
208238 layout:: Variants :: Single { .. } => { }
209239 }
@@ -215,6 +245,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
215245 // immediate trait objects are not a thing
216246 let dest = v. value ( ) . force_allocation ( self ) ?;
217247 let inner = self . unpack_dyn_trait ( dest) ?. 1 ;
248+ trace ! ( "dyn object layout: {:#?}" , inner. layout) ;
218249 // recurse with the inner type
219250 return v. visit_field ( self , Value :: from_mem_place ( inner) , 0 ) ;
220251 } ,
0 commit comments