@@ -120,29 +120,42 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
120120 variant : Option < usize > ,
121121 field : mir:: Field ,
122122 base_ty : Ty < ' tcx > ,
123- ) -> EvalResult < ' tcx , Option < ( Value , Ty < ' tcx > ) > > {
123+ ) -> EvalResult < ' tcx , ValTy < ' tcx > > {
124124 let mut base_layout = self . layout_of ( base_ty) ?;
125125 if let Some ( variant_index) = variant {
126126 base_layout = base_layout. for_variant ( self , variant_index) ;
127127 }
128128 let field_index = field. index ( ) ;
129129 let field = base_layout. field ( self , field_index) ?;
130130 if field. size . bytes ( ) == 0 {
131- return Ok ( Some ( ( Value :: Scalar ( Scalar :: undef ( ) ) , field. ty ) ) )
131+ return Ok ( ValTy {
132+ value : Value :: Scalar ( Scalar :: undef ( ) ) ,
133+ ty : field. ty ,
134+ } ) ;
132135 }
133136 let offset = base_layout. fields . offset ( field_index) ;
134- match base {
137+ let value = match base {
135138 // the field covers the entire type
136139 Value :: ScalarPair ( ..) |
137- Value :: Scalar ( _) if offset. bytes ( ) == 0 && field. size == base_layout. size => Ok ( Some ( ( base, field . ty ) ) ) ,
138- // split fat pointers, 2 element tuples, ...
140+ Value :: Scalar ( _) if offset. bytes ( ) == 0 && field. size == base_layout. size => base,
141+ // extract fields from types with `ScalarPair` ABI
139142 Value :: ScalarPair ( a, b) => {
140143 let val = if offset. bytes ( ) == 0 { a } else { b } ;
141- Ok ( Some ( ( Value :: Scalar ( val) , field . ty ) ) )
144+ Value :: Scalar ( val)
142145 } ,
143- // FIXME(oli-obk): figure out whether we should be calling `try_read_value` here
144- _ => Ok ( None ) ,
145- }
146+ Value :: ByRef ( base_ptr, align) => {
147+ let offset = base_layout. fields . offset ( field_index) ;
148+ let ptr = base_ptr. ptr_offset ( offset, self ) ?;
149+ let align = align. min ( base_layout. align ) . min ( field. align ) ;
150+ assert ! ( !field. is_unsized( ) ) ;
151+ Value :: ByRef ( ptr, align)
152+ } ,
153+ Value :: Scalar ( val) => bug ! ( "field access on non aggregate {:?}, {:?}" , val, base_ty) ,
154+ } ;
155+ Ok ( ValTy {
156+ value,
157+ ty : field. ty ,
158+ } )
146159 }
147160
148161 fn try_read_place_projection (
@@ -156,7 +169,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
156169 } ;
157170 let base_ty = self . place_ty ( & proj. base ) ;
158171 match proj. elem {
159- Field ( field, _) => Ok ( self . read_field ( base, None , field, base_ty) ?. map ( | ( f , _ ) | f ) ) ,
172+ Field ( field, _) => Ok ( Some ( self . read_field ( base, None , field, base_ty) ?. value ) ) ,
160173 // The NullablePointer cases should work fine, need to take care for normal enums
161174 Downcast ( ..) |
162175 Subslice { .. } |
0 commit comments