@@ -34,31 +34,31 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
3434 CastKind :: PointerExposeAddress => {
3535 let src = self . read_immediate ( src) ?;
3636 let res = self . pointer_expose_address_cast ( & src, cast_ty) ?;
37- self . write_immediate ( res, dest) ?;
37+ self . write_immediate ( * res, dest) ?;
3838 }
3939
4040 CastKind :: PointerFromExposedAddress => {
4141 let src = self . read_immediate ( src) ?;
4242 let res = self . pointer_from_exposed_address_cast ( & src, cast_ty) ?;
43- self . write_immediate ( res, dest) ?;
43+ self . write_immediate ( * res, dest) ?;
4444 }
4545
4646 CastKind :: IntToInt | CastKind :: IntToFloat => {
4747 let src = self . read_immediate ( src) ?;
4848 let res = self . int_to_int_or_float ( & src, cast_ty) ?;
49- self . write_immediate ( res, dest) ?;
49+ self . write_immediate ( * res, dest) ?;
5050 }
5151
5252 CastKind :: FloatToFloat | CastKind :: FloatToInt => {
5353 let src = self . read_immediate ( src) ?;
5454 let res = self . float_to_float_or_int ( & src, cast_ty) ?;
55- self . write_immediate ( res, dest) ?;
55+ self . write_immediate ( * res, dest) ?;
5656 }
5757
5858 CastKind :: FnPtrToPtr | CastKind :: PtrToPtr => {
5959 let src = self . read_immediate ( src) ?;
6060 let res = self . ptr_to_ptr ( & src, cast_ty) ?;
61- self . write_immediate ( res, dest) ?;
61+ self . write_immediate ( * res, dest) ?;
6262 }
6363
6464 CastKind :: PointerCoercion (
@@ -165,55 +165,57 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
165165 & self ,
166166 src : & ImmTy < ' tcx , M :: Provenance > ,
167167 cast_ty : Ty < ' tcx > ,
168- ) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
168+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , M :: Provenance > > {
169169 assert ! ( src. layout. ty. is_integral( ) || src. layout. ty. is_char( ) || src. layout. ty. is_bool( ) ) ;
170170 assert ! ( cast_ty. is_floating_point( ) || cast_ty. is_integral( ) || cast_ty. is_char( ) ) ;
171171
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+ ) )
173177 }
174178
175179 /// Handles 'FloatToFloat' and 'FloatToInt' casts.
176180 pub fn float_to_float_or_int (
177181 & self ,
178182 src : & ImmTy < ' tcx , M :: Provenance > ,
179183 cast_ty : Ty < ' tcx > ,
180- ) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
184+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , M :: Provenance > > {
181185 use rustc_type_ir:: sty:: TyKind :: * ;
182186
183- match src. layout . ty . kind ( ) {
187+ let layout = self . layout_of ( cast_ty) ?;
188+ let val = match src. layout . ty . kind ( ) {
184189 // 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) ,
191192 _ => {
192193 bug ! ( "Can't cast 'Float' type into {:?}" , cast_ty) ;
193194 }
194- }
195+ } ;
196+ Ok ( ImmTy :: from_scalar ( val, layout) )
195197 }
196198
197199 /// Handles 'FnPtrToPtr' and 'PtrToPtr' casts.
198200 pub fn ptr_to_ptr (
199201 & self ,
200202 src : & ImmTy < ' tcx , M :: Provenance > ,
201203 cast_ty : Ty < ' tcx > ,
202- ) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
204+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , M :: Provenance > > {
203205 assert ! ( src. layout. ty. is_any_ptr( ) ) ;
204206 assert ! ( cast_ty. is_unsafe_ptr( ) ) ;
205207 // Handle casting any ptr to raw ptr (might be a fat ptr).
206208 let dest_layout = self . layout_of ( cast_ty) ?;
207209 if dest_layout. size == src. layout . size {
208210 // 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 ) ) ;
210212 } else {
211213 // Casting the metadata away from a fat ptr.
212214 assert_eq ! ( src. layout. size, 2 * self . pointer_size( ) ) ;
213215 assert_eq ! ( dest_layout. size, self . pointer_size( ) ) ;
214216 assert ! ( src. layout. ty. is_unsafe_ptr( ) ) ;
215217 return match * * src {
216- Immediate :: ScalarPair ( data, _) => Ok ( data . into ( ) ) ,
218+ Immediate :: ScalarPair ( data, _) => Ok ( ImmTy :: from_scalar ( data , dest_layout ) ) ,
217219 Immediate :: Scalar ( ..) => span_bug ! (
218220 self . cur_span( ) ,
219221 "{:?} input to a fat-to-thin cast ({:?} -> {:?})" ,
@@ -230,7 +232,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
230232 & mut self ,
231233 src : & ImmTy < ' tcx , M :: Provenance > ,
232234 cast_ty : Ty < ' tcx > ,
233- ) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
235+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , M :: Provenance > > {
234236 assert_matches ! ( src. layout. ty. kind( ) , ty:: RawPtr ( _) | ty:: FnPtr ( _) ) ;
235237 assert ! ( cast_ty. is_integral( ) ) ;
236238
@@ -240,14 +242,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
240242 Ok ( ptr) => M :: expose_ptr ( self , ptr) ?,
241243 Err ( _) => { } // Do nothing, exposing an invalid pointer (`None` provenance) is a NOP.
242244 } ;
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) )
244247 }
245248
246249 pub fn pointer_from_exposed_address_cast (
247250 & self ,
248251 src : & ImmTy < ' tcx , M :: Provenance > ,
249252 cast_ty : Ty < ' tcx > ,
250- ) -> InterpResult < ' tcx , Immediate < M :: Provenance > > {
253+ ) -> InterpResult < ' tcx , ImmTy < ' tcx , M :: Provenance > > {
251254 assert ! ( src. layout. ty. is_integral( ) ) ;
252255 assert_matches ! ( cast_ty. kind( ) , ty:: RawPtr ( _) ) ;
253256
@@ -258,12 +261,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
258261
259262 // Then turn address into pointer.
260263 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) )
262266 }
263267
264268 /// Low-level cast helper function. This works directly on scalars and can take 'int-like' input
265269 /// 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 (
267271 & self ,
268272 scalar : Scalar < M :: Provenance > , // input value (there is no ScalarTy so we separate data+layout)
269273 src_layout : TyAndLayout < ' tcx > ,
0 commit comments