Skip to content

Commit

Permalink
Rollup merge of #121997 - RalfJung:cast-float-ty, r=compiler-errors
Browse files Browse the repository at this point in the history
interpret/cast: make more matches on FloatTy properly exhaustive

Actually implementing these is pretty trivial (at least once all the scalar methods are added, which happens in #121926), but I'm staying consistent with the other f16/f128 PRs. Also adding adding all the tests to Miri would be quite a lot of work.

There's probably some way to reduce the code duplication here with more use of generics... but that's a future refactor.^^

r? `@tgross35`
  • Loading branch information
jhpratt committed Mar 5, 2024
2 parents ac4eb31 681dc38 commit 4a65a53
Showing 1 changed file with 35 additions and 23 deletions.
58 changes: 35 additions & 23 deletions compiler/rustc_const_eval/src/interpret/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 182,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
use rustc_type_ir::TyKind::*;

let val = match src.layout.ty.kind() {
// Floating point
Float(FloatTy::F32) => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty),
Float(FloatTy::F64) => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty),
_ => {
bug!("Can't cast 'Float' type into {}", cast_to.ty);
}
let Float(fty) = src.layout.ty.kind() else {
bug!("FloatToFloat/FloatToInt cast: source type {} is not a float type", src.layout.ty)
};
let val = match fty {
FloatTy::F16 => unimplemented!("f16_f128"),
FloatTy::F32 => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty),
FloatTy::F64 => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty),
FloatTy::F128 => unimplemented!("f16_f128"),
};
Ok(ImmTy::from_scalar(val, cast_to))
}
Expand Down Expand Up @@ -275,6 276,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
trace!("cast_from_scalar: {}, {} -> {}", v, src_layout.ty, cast_ty);

Ok(match *cast_ty.kind() {
// int -> int
Int(_) | Uint(_) => {
let size = match *cast_ty.kind() {
Int(t) => Integer::from_int_ty(self, t).size(),
Expand All @@ -285,15 287,26 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Scalar::from_uint(v, size)
}

Float(FloatTy::F32) if signed => Scalar::from_f32(Single::from_i128(v as i128).value),
Float(FloatTy::F64) if signed => Scalar::from_f64(Double::from_i128(v as i128).value),
Float(FloatTy::F32) => Scalar::from_f32(Single::from_u128(v).value),
Float(FloatTy::F64) => Scalar::from_f64(Double::from_u128(v).value),

Char => {
// `u8` to `char` cast
Scalar::from_u32(u8::try_from(v).unwrap().into())
// signed int -> float
Float(fty) if signed => {
let v = v as i128;
match fty {
FloatTy::F16 => unimplemented!("f16_f128"),
FloatTy::F32 => Scalar::from_f32(Single::from_i128(v).value),
FloatTy::F64 => Scalar::from_f64(Double::from_i128(v).value),
FloatTy::F128 => unimplemented!("f16_f128"),
}
}
// unsigned int -> float
Float(fty) => match fty {
FloatTy::F16 => unimplemented!("f16_f128"),
FloatTy::F32 => Scalar::from_f32(Single::from_u128(v).value),
FloatTy::F64 => Scalar::from_f64(Double::from_u128(v).value),
FloatTy::F128 => unimplemented!("f16_f128"),
},

// u8 -> char
Char => Scalar::from_u32(u8::try_from(v).unwrap().into()),

// Casts to bool are not permitted by rustc, no need to handle them here.
_ => span_bug!(self.cur_span(), "invalid int to {} cast", cast_ty),
Expand Down Expand Up @@ -339,14 352,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let v = f.to_i128(size.bits_usize()).value;
Scalar::from_int(v, size)
}
// float -> f32
Float(FloatTy::F32) => {
Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value))
}
// float -> f64
Float(FloatTy::F64) => {
Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value))
}
// float -> float
Float(fty) => match fty {
FloatTy::F16 => unimplemented!("f16_f128"),
FloatTy::F32 => Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value)),
FloatTy::F64 => Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value)),
FloatTy::F128 => unimplemented!("f16_f128"),
},
// That's it.
_ => span_bug!(self.cur_span(), "invalid float to {} cast", dest_ty),
}
Expand Down

0 comments on commit 4a65a53

Please sign in to comment.