@@ -120,29 +120,42 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
120
120
variant : Option < usize > ,
121
121
field : mir:: Field ,
122
122
base_ty : Ty < ' tcx > ,
123
- ) -> EvalResult < ' tcx , Option < ( Value , Ty < ' tcx > ) > > {
123
+ ) -> EvalResult < ' tcx , ValTy < ' tcx > > {
124
124
let mut base_layout = self . layout_of ( base_ty) ?;
125
125
if let Some ( variant_index) = variant {
126
126
base_layout = base_layout. for_variant ( self , variant_index) ;
127
127
}
128
128
let field_index = field. index ( ) ;
129
129
let field = base_layout. field ( self , field_index) ?;
130
130
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
+ } ) ;
132
135
}
133
136
let offset = base_layout. fields . offset ( field_index) ;
134
- match base {
137
+ let value = match base {
135
138
// the field covers the entire type
136
139
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
139
142
Value :: ScalarPair ( a, b) => {
140
143
let val = if offset. bytes ( ) == 0 { a } else { b } ;
141
- Ok ( Some ( ( Value :: Scalar ( val) , field . ty ) ) )
144
+ Value :: Scalar ( val)
142
145
} ,
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
+ } )
146
159
}
147
160
148
161
fn try_read_place_projection (
@@ -156,7 +169,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
156
169
} ;
157
170
let base_ty = self . place_ty ( & proj. base ) ;
158
171
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 ) ) ,
160
173
// The NullablePointer cases should work fine, need to take care for normal enums
161
174
Downcast ( ..) |
162
175
Subslice { .. } |
0 commit comments