@@ -34,31 +34,31 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
34
34
CastKind :: PointerExposeAddress => {
35
35
let src = self . read_immediate ( src) ?;
36
36
let res = self . pointer_expose_address_cast ( & src, cast_ty) ?;
37
- self . write_immediate ( res, dest) ?;
37
+ self . write_immediate ( * res, dest) ?;
38
38
}
39
39
40
40
CastKind :: PointerFromExposedAddress => {
41
41
let src = self . read_immediate ( src) ?;
42
42
let res = self . pointer_from_exposed_address_cast ( & src, cast_ty) ?;
43
- self . write_immediate ( res, dest) ?;
43
+ self . write_immediate ( * res, dest) ?;
44
44
}
45
45
46
46
CastKind :: IntToInt | CastKind :: IntToFloat => {
47
47
let src = self . read_immediate ( src) ?;
48
48
let res = self . int_to_int_or_float ( & src, cast_ty) ?;
49
- self . write_immediate ( res, dest) ?;
49
+ self . write_immediate ( * res, dest) ?;
50
50
}
51
51
52
52
CastKind :: FloatToFloat | CastKind :: FloatToInt => {
53
53
let src = self . read_immediate ( src) ?;
54
54
let res = self . float_to_float_or_int ( & src, cast_ty) ?;
55
- self . write_immediate ( res, dest) ?;
55
+ self . write_immediate ( * res, dest) ?;
56
56
}
57
57
58
58
CastKind :: FnPtrToPtr | CastKind :: PtrToPtr => {
59
59
let src = self . read_immediate ( src) ?;
60
60
let res = self . ptr_to_ptr ( & src, cast_ty) ?;
61
- self . write_immediate ( res, dest) ?;
61
+ self . write_immediate ( * res, dest) ?;
62
62
}
63
63
64
64
CastKind :: PointerCoercion (
@@ -165,55 +165,57 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
165
165
& self ,
166
166
src : & ImmTy < ' tcx , M :: Provenance > ,
167
167
cast_ty : Ty < ' tcx > ,
168
- ) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
168
+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , M :: Provenance > > {
169
169
assert ! ( src. layout. ty. is_integral( ) || src. layout. ty. is_char( ) || src. layout. ty. is_bool( ) ) ;
170
170
assert ! ( cast_ty. is_floating_point( ) || cast_ty. is_integral( ) || cast_ty. is_char( ) ) ;
171
171
172
- Ok ( self . cast_from_int_like ( src. to_scalar ( ) , src. layout , cast_ty) ?. into ( ) )
172
+ let layout = self . layout_of ( cast_ty) ?;
173
+ Ok ( ImmTy :: from_scalar (
174
+ self . cast_from_int_like ( src. to_scalar ( ) , src. layout , cast_ty) ?,
175
+ layout,
176
+ ) )
173
177
}
174
178
175
179
/// Handles 'FloatToFloat' and 'FloatToInt' casts.
176
180
pub fn float_to_float_or_int (
177
181
& self ,
178
182
src : & ImmTy < ' tcx , M :: Provenance > ,
179
183
cast_ty : Ty < ' tcx > ,
180
- ) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
184
+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , M :: Provenance > > {
181
185
use rustc_type_ir:: sty:: TyKind :: * ;
182
186
183
- match src. layout . ty . kind ( ) {
187
+ let layout = self . layout_of ( cast_ty) ?;
188
+ let val = match src. layout . ty . kind ( ) {
184
189
// Floating point
185
- Float ( FloatTy :: F32 ) => {
186
- return Ok ( self . cast_from_float ( src. to_scalar ( ) . to_f32 ( ) ?, cast_ty) . into ( ) ) ;
187
- }
188
- Float ( FloatTy :: F64 ) => {
189
- return Ok ( self . cast_from_float ( src. to_scalar ( ) . to_f64 ( ) ?, cast_ty) . into ( ) ) ;
190
- }
190
+ Float ( FloatTy :: F32 ) => self . cast_from_float ( src. to_scalar ( ) . to_f32 ( ) ?, cast_ty) ,
191
+ Float ( FloatTy :: F64 ) => self . cast_from_float ( src. to_scalar ( ) . to_f64 ( ) ?, cast_ty) ,
191
192
_ => {
192
193
bug ! ( "Can't cast 'Float' type into {:?}" , cast_ty) ;
193
194
}
194
- }
195
+ } ;
196
+ Ok ( ImmTy :: from_scalar ( val, layout) )
195
197
}
196
198
197
199
/// Handles 'FnPtrToPtr' and 'PtrToPtr' casts.
198
200
pub fn ptr_to_ptr (
199
201
& self ,
200
202
src : & ImmTy < ' tcx , M :: Provenance > ,
201
203
cast_ty : Ty < ' tcx > ,
202
- ) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
204
+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , M :: Provenance > > {
203
205
assert ! ( src. layout. ty. is_any_ptr( ) ) ;
204
206
assert ! ( cast_ty. is_unsafe_ptr( ) ) ;
205
207
// Handle casting any ptr to raw ptr (might be a fat ptr).
206
208
let dest_layout = self . layout_of ( cast_ty) ?;
207
209
if dest_layout. size == src. layout . size {
208
210
// Thin or fat pointer that just hast the ptr kind of target type changed.
209
- return Ok ( * * src) ;
211
+ return Ok ( ImmTy :: from_immediate ( * * src, dest_layout ) ) ;
210
212
} else {
211
213
// Casting the metadata away from a fat ptr.
212
214
assert_eq ! ( src. layout. size, 2 * self . pointer_size( ) ) ;
213
215
assert_eq ! ( dest_layout. size, self . pointer_size( ) ) ;
214
216
assert ! ( src. layout. ty. is_unsafe_ptr( ) ) ;
215
217
return match * * src {
216
- Immediate :: ScalarPair ( data, _) => Ok ( data . into ( ) ) ,
218
+ Immediate :: ScalarPair ( data, _) => Ok ( ImmTy :: from_scalar ( data , dest_layout ) ) ,
217
219
Immediate :: Scalar ( ..) => span_bug ! (
218
220
self . cur_span( ) ,
219
221
"{:?} input to a fat-to-thin cast ({:?} -> {:?})" ,
@@ -230,7 +232,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
230
232
& mut self ,
231
233
src : & ImmTy < ' tcx , M :: Provenance > ,
232
234
cast_ty : Ty < ' tcx > ,
233
- ) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
235
+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , M :: Provenance > > {
234
236
assert_matches ! ( src. layout. ty. kind( ) , ty:: RawPtr ( _) | ty:: FnPtr ( _) ) ;
235
237
assert ! ( cast_ty. is_integral( ) ) ;
236
238
@@ -240,14 +242,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
240
242
Ok ( ptr) => M :: expose_ptr ( self , ptr) ?,
241
243
Err ( _) => { } // Do nothing, exposing an invalid pointer (`None` provenance) is a NOP.
242
244
} ;
243
- Ok ( self . cast_from_int_like ( scalar, src. layout , cast_ty) ?. into ( ) )
245
+ let layout = self . layout_of ( cast_ty) ?;
246
+ Ok ( ImmTy :: from_scalar ( self . cast_from_int_like ( scalar, src. layout , cast_ty) ?, layout) )
244
247
}
245
248
246
249
pub fn pointer_from_exposed_address_cast (
247
250
& self ,
248
251
src : & ImmTy < ' tcx , M :: Provenance > ,
249
252
cast_ty : Ty < ' tcx > ,
250
- ) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
253
+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , M :: Provenance > > {
251
254
assert ! ( src. layout. ty. is_integral( ) ) ;
252
255
assert_matches ! ( cast_ty. kind( ) , ty:: RawPtr ( _) ) ;
253
256
@@ -258,12 +261,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
258
261
259
262
// Then turn address into pointer.
260
263
let ptr = M :: ptr_from_addr_cast ( & self , addr) ?;
261
- Ok ( Scalar :: from_maybe_pointer ( ptr, self ) . into ( ) )
264
+ let layout = self . layout_of ( cast_ty) ?;
265
+ Ok ( ImmTy :: from_scalar ( Scalar :: from_maybe_pointer ( ptr, self ) , layout) )
262
266
}
263
267
264
268
/// Low-level cast helper function. This works directly on scalars and can take 'int-like' input
265
269
/// type (basically everything with a scalar layout) to int/float/char types.
266
- pub fn cast_from_int_like (
270
+ fn cast_from_int_like (
267
271
& self ,
268
272
scalar : Scalar < M :: Provenance > , // input value (there is no ScalarTy so we separate data+layout)
269
273
src_layout : TyAndLayout < ' tcx > ,
0 commit comments