@@ -14,15 +14,6 @@ use rustc::mir::CastKind;
14
14
use super :: { InterpCx , Machine , PlaceTy , OpTy , ImmTy , Immediate , FnVal } ;
15
15
16
16
impl < ' mir , ' tcx , M : Machine < ' mir , ' tcx > > InterpCx < ' mir , ' tcx , M > {
17
- fn type_is_fat_ptr ( & self , ty : Ty < ' tcx > ) -> bool {
18
- match ty. sty {
19
- ty:: RawPtr ( ty:: TypeAndMut { ty, .. } ) |
20
- ty:: Ref ( _, ty, _) => !self . type_is_sized ( ty) ,
21
- ty:: Adt ( def, _) if def. is_box ( ) => !self . type_is_sized ( ty. boxed_ty ( ) ) ,
22
- _ => false ,
23
- }
24
- }
25
-
26
17
pub fn cast (
27
18
& mut self ,
28
19
src : OpTy < ' tcx , M :: PointerTag > ,
@@ -99,68 +90,59 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
99
90
src : ImmTy < ' tcx , M :: PointerTag > ,
100
91
dest_layout : TyLayout < ' tcx > ,
101
92
) -> InterpResult < ' tcx , Immediate < M :: PointerTag > > {
102
- if self . type_is_fat_ptr ( src. layout . ty ) {
103
- return match ( * src, self . type_is_fat_ptr ( dest_layout. ty ) ) {
104
- // pointers to extern types
105
- ( Immediate :: Scalar ( _) , _) |
106
- // slices and trait objects to other slices/trait objects
107
- ( Immediate :: ScalarPair ( ..) , true ) => {
108
- // No change to immediate
109
- Ok ( * src)
110
- }
111
- // slices and trait objects to thin pointers (dropping the metadata)
112
- ( Immediate :: ScalarPair ( data, _) , false ) => {
113
- Ok ( data. into ( ) )
114
- }
115
- } ;
116
- } else {
117
- match src. layout . variants {
118
- layout:: Variants :: Single { index } => {
119
- if let Some ( discr) =
120
- src. layout . ty . discriminant_for_variant ( * self . tcx , index)
121
- {
122
- // Cast from a univariant enum
123
- assert ! ( src. layout. is_zst( ) ) ;
124
- return Ok ( Scalar :: from_uint ( discr. val , dest_layout. size ) . into ( ) ) ;
125
- }
126
- }
127
- layout:: Variants :: Multiple { .. } => { } ,
128
- }
129
-
130
- return Ok ( self . cast_scalar ( src. to_scalar ( ) ?, src. layout , dest_layout) ?. into ( ) ) ;
131
- }
132
- }
133
-
134
- fn cast_scalar (
135
- & self ,
136
- val : Scalar < M :: PointerTag > ,
137
- src_layout : TyLayout < ' tcx > ,
138
- dest_layout : TyLayout < ' tcx > ,
139
- ) -> InterpResult < ' tcx , Scalar < M :: PointerTag > > {
140
93
use rustc:: ty:: TyKind :: * ;
141
- trace ! ( "Casting {:?}: {:?} to {:?}" , val , src_layout . ty, dest_layout. ty) ;
94
+ trace ! ( "Casting {:?}: {:?} to {:?}" , * src , src . layout . ty, dest_layout. ty) ;
142
95
143
- match src_layout . ty . sty {
96
+ match src . layout . ty . sty {
144
97
// Floating point
145
- Float ( FloatTy :: F32 ) => self . cast_from_float ( val. to_f32 ( ) ?, dest_layout. ty ) ,
146
- Float ( FloatTy :: F64 ) => self . cast_from_float ( val. to_f64 ( ) ?, dest_layout. ty ) ,
147
- // Integer(-like), including fn ptr casts and casts from enums that
148
- // are represented as integers (this excludes univariant enums, which
149
- // are handled in `cast` directly).
150
- _ => {
98
+ Float ( FloatTy :: F32 ) =>
99
+ return Ok ( self . cast_from_float ( src. to_scalar ( ) ?. to_f32 ( ) ?, dest_layout. ty ) ?. into ( ) ) ,
100
+ Float ( FloatTy :: F64 ) =>
101
+ return Ok ( self . cast_from_float ( src. to_scalar ( ) ?. to_f64 ( ) ?, dest_layout. ty ) ?. into ( ) ) ,
102
+ // The rest is integer/pointer-"like", including fn ptr casts and casts from enums that
103
+ // are represented as integers.
104
+ _ =>
151
105
assert ! (
152
- src_layout. ty. is_bool( ) || src_layout. ty. is_char( ) ||
153
- src_layout. ty. is_enum( ) || src_layout. ty. is_integral( ) ||
154
- src_layout. ty. is_unsafe_ptr( ) || src_layout. ty. is_fn_ptr( ) ||
155
- src_layout. ty. is_region_ptr( ) ,
156
- "Unexpected cast from type {:?}" , src_layout. ty
157
- ) ;
158
- match val. to_bits_or_ptr ( src_layout. size , self ) {
159
- Err ( ptr) => self . cast_from_ptr ( ptr, src_layout, dest_layout) ,
160
- Ok ( data) => self . cast_from_int ( data, src_layout, dest_layout) ,
106
+ src. layout. ty. is_bool( ) || src. layout. ty. is_char( ) ||
107
+ src. layout. ty. is_enum( ) || src. layout. ty. is_integral( ) ||
108
+ src. layout. ty. is_unsafe_ptr( ) || src. layout. ty. is_fn_ptr( ) ||
109
+ src. layout. ty. is_region_ptr( ) ,
110
+ "Unexpected cast from type {:?}" , src. layout. ty
111
+ )
112
+ }
113
+
114
+ // Handle cast the metadata away from a fat pointer.
115
+ if dest_layout. size != src. layout . size {
116
+ assert_eq ! ( dest_layout. size, self . memory. pointer_size( ) ) ;
117
+ return match * src {
118
+ Immediate :: ScalarPair ( data, _) => Ok ( data. into ( ) ) ,
119
+ Immediate :: Scalar ( ..) =>
120
+ bug ! (
121
+ "{:?} input to a fat-to-thin cast ({:?} -> {:?})" ,
122
+ * src, src. layout. ty, dest_layout. ty
123
+ ) ,
124
+ } ;
125
+ }
126
+
127
+ // Handle cast from a univariant (ZST) enum
128
+ match src. layout . variants {
129
+ layout:: Variants :: Single { index } => {
130
+ if let Some ( discr) =
131
+ src. layout . ty . discriminant_for_variant ( * self . tcx , index)
132
+ {
133
+ assert ! ( src. layout. is_zst( ) ) ;
134
+ return Ok ( Scalar :: from_uint ( discr. val , dest_layout. size ) . into ( ) ) ;
161
135
}
162
136
}
137
+ layout:: Variants :: Multiple { .. } => { } ,
163
138
}
139
+
140
+ // Handle all the rest.
141
+ let val = src. to_scalar ( ) ?;
142
+ Ok ( match val. to_bits_or_ptr ( src. layout . size , self ) {
143
+ Err ( ptr) => self . cast_from_ptr ( ptr, src. layout , dest_layout) ?,
144
+ Ok ( data) => self . cast_from_int ( data, src. layout , dest_layout) ?,
145
+ } . into ( ) )
164
146
}
165
147
166
148
fn cast_from_int (
0 commit comments