@@ -42,10 +42,22 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
42
42
let res = self.pointer_from_exposed_address_cast(&src, cast_ty)?;
43
43
self.write_immediate(res, dest)?;
44
44
}
45
- // FIXME: We shouldn't use `misc_cast` for these but handle them separately.
46
- IntToInt | FloatToInt | FloatToFloat | IntToFloat | FnPtrToPtr | PtrToPtr => {
45
+
46
+ IntToInt | IntToFloat => {
47
47
let src = self.read_immediate(src)?;
48
- let res = self.misc_cast(&src, cast_ty)?;
48
+ let res = self.int_to_int_or_float(&src, cast_ty)?;
49
+ self.write_immediate(res, dest)?;
50
+ }
51
+
52
+ FloatToFloat | FloatToInt => {
53
+ let src = self.read_immediate(src)?;
54
+ let res = self.float_to_float_or_int(&src, cast_ty)?;
55
+ self.write_immediate(res, dest)?;
56
+ }
57
+
58
+ FnPtrToPtr | PtrToPtr => {
59
+ let src = self.read_immediate(&src)?;
60
+ let res = self.ptr_to_ptr(&src, cast_ty)?;
49
61
self.write_immediate(res, dest)?;
50
62
}
51
63
@@ -126,13 +138,27 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
126
138
Ok(())
127
139
}
128
140
129
- pub fn misc_cast(
141
+ pub fn int_to_int_or_float(
142
+ &mut self,
143
+ src: &ImmTy<'tcx, M::Provenance>,
144
+ cast_ty: Ty<'tcx>,
145
+ ) -> InterpResult<'tcx, Immediate<M::Provenance>> {
146
+ if (src.layout.ty.is_integral() || src.layout.ty.is_char() || src.layout.ty.is_bool())
147
+ && (cast_ty.is_floating_point() || cast_ty.is_integral() || cast_ty.is_char())
148
+ {
149
+ let scalar = src.to_scalar();
150
+ Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into())
151
+ } else {
152
+ bug!("Unexpected cast from type {:?}", src.layout.ty)
153
+ }
154
+ }
155
+
156
+ pub fn float_to_float_or_int(
130
157
&mut self,
131
158
src: &ImmTy<'tcx, M::Provenance>,
132
159
cast_ty: Ty<'tcx>,
133
160
) -> InterpResult<'tcx, Immediate<M::Provenance>> {
134
161
use rustc_type_ir::sty::TyKind::*;
135
- trace!("Casting {:?}: {:?} to {:?}", *src, src.layout.ty, cast_ty);
136
162
137
163
match src.layout.ty.kind() {
138
164
// Floating point
@@ -142,19 +168,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
142
168
Float(FloatTy::F64) => {
143
169
return Ok(self.cast_from_float(src.to_scalar().to_f64()?, cast_ty).into());
144
170
}
145
- // The rest is integer/pointer-"like", including fn ptr casts
146
- _ => assert!(
147
- src.layout.ty.is_bool()
148
- || src.layout.ty.is_char()
149
- || src.layout.ty.is_integral()
150
- || src.layout.ty.is_any_ptr(),
151
- "Unexpected cast from type {:?}",
152
- src.layout.ty
153
- ),
171
+ _ => {
172
+ bug!("Can't cast 'Float' type into {:?}", cast_ty);
173
+ }
154
174
}
175
+ }
155
176
156
- // # First handle non-scalar source values.
157
-
177
+ /// Handles 'FnPtrToPtr' and 'PtrToPtr' casts.
178
+ pub fn ptr_to_ptr(
179
+ &mut self,
180
+ src: &ImmTy<'tcx, M::Provenance>,
181
+ cast_ty: Ty<'tcx>,
182
+ ) -> InterpResult<'tcx, Immediate<M::Provenance>> {
158
183
// Handle casting any ptr to raw ptr (might be a fat ptr).
159
184
if src.layout.ty.is_any_ptr() && cast_ty.is_unsafe_ptr() {
160
185
let dest_layout = self.layout_of(cast_ty)?;
@@ -178,11 +203,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
178
203
Immediate::Uninit => throw_ub!(InvalidUninitBytes(None)),
179
204
};
180
205
}
206
+ } else {
207
+ bug!("Can't cast 'Ptr' or 'FnPtr' into {:?}", cast_ty);
181
208
}
182
-
183
- // # The remaining source values are scalar and "int-like".
184
- let scalar = src.to_scalar();
185
- Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into())
186
209
}
187
210
188
211
pub fn pointer_expose_address_cast(
0 commit comments