Stabilize float::to_int_unchecked
This renames and stabilizes unsafe floating point to integer casts, which are intended to be the substitute for the currently unsound `as` behavior, once that changes to safe-but-slower saturating casts.
This commit is contained in:
parent
8ab82b87af
commit
56147219a5
@ -13,9 +13,9 @@ mod private {
|
||||
/// Typically doesn’t need to be used directly.
|
||||
#[unstable(feature = "convert_float_to_int", issue = "67057")]
|
||||
pub trait FloatToInt<Int>: private::Sealed + Sized {
|
||||
#[unstable(feature = "float_approx_unchecked_to", issue = "67058")]
|
||||
#[unstable(feature = "convert_float_to_int", issue = "67057")]
|
||||
#[doc(hidden)]
|
||||
unsafe fn approx_unchecked(self) -> Int;
|
||||
unsafe fn to_int_unchecked(self) -> Int;
|
||||
}
|
||||
|
||||
macro_rules! impl_float_to_int {
|
||||
@ -27,8 +27,15 @@ macro_rules! impl_float_to_int {
|
||||
impl FloatToInt<$Int> for $Float {
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
unsafe fn approx_unchecked(self) -> $Int {
|
||||
crate::intrinsics::float_to_int_approx_unchecked(self)
|
||||
unsafe fn to_int_unchecked(self) -> $Int {
|
||||
#[cfg(bootstrap)]
|
||||
{
|
||||
crate::intrinsics::float_to_int_approx_unchecked(self)
|
||||
}
|
||||
#[cfg(not(bootstrap))]
|
||||
{
|
||||
crate::intrinsics::float_to_int_unchecked(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
)+
|
||||
|
@ -1582,8 +1582,16 @@ extern "rust-intrinsic" {
|
||||
/// Convert with LLVM’s fptoui/fptosi, which may return undef for values out of range
|
||||
/// (<https://github.com/rust-lang/rust/issues/10184>)
|
||||
/// This is under stabilization at <https://github.com/rust-lang/rust/issues/67058>
|
||||
#[cfg(bootstrap)]
|
||||
pub fn float_to_int_approx_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
|
||||
|
||||
/// Convert with LLVM’s fptoui/fptosi, which may return undef for values out of range
|
||||
/// (<https://github.com/rust-lang/rust/issues/10184>)
|
||||
///
|
||||
/// Stabilized as `f32::to_int_unchecked` and `f64::to_int_unchecked`.
|
||||
#[cfg(not(bootstrap))]
|
||||
pub fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
|
||||
|
||||
/// Returns the number of bits set in an integer type `T`
|
||||
///
|
||||
/// The stabilized versions of this intrinsic are available on the integer
|
||||
|
@ -464,14 +464,12 @@ impl f32 {
|
||||
/// assuming that the value is finite and fits in that type.
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(float_approx_unchecked_to)]
|
||||
///
|
||||
/// let value = 4.6_f32;
|
||||
/// let rounded = unsafe { value.approx_unchecked_to::<u16>() };
|
||||
/// let rounded = unsafe { value.to_int_unchecked::<u16>() };
|
||||
/// assert_eq!(rounded, 4);
|
||||
///
|
||||
/// let value = -128.9_f32;
|
||||
/// let rounded = unsafe { value.approx_unchecked_to::<i8>() };
|
||||
/// let rounded = unsafe { value.to_int_unchecked::<i8>() };
|
||||
/// assert_eq!(rounded, std::i8::MIN);
|
||||
/// ```
|
||||
///
|
||||
@ -482,13 +480,13 @@ impl f32 {
|
||||
/// * Not be `NaN`
|
||||
/// * Not be infinite
|
||||
/// * Be representable in the return type `Int`, after truncating off its fractional part
|
||||
#[unstable(feature = "float_approx_unchecked_to", issue = "67058")]
|
||||
#[stable(feature = "float_approx_unchecked_to", since = "1.44.0")]
|
||||
#[inline]
|
||||
pub unsafe fn approx_unchecked_to<Int>(self) -> Int
|
||||
pub unsafe fn to_int_unchecked<Int>(self) -> Int
|
||||
where
|
||||
Self: FloatToInt<Int>,
|
||||
{
|
||||
FloatToInt::<Int>::approx_unchecked(self)
|
||||
FloatToInt::<Int>::to_int_unchecked(self)
|
||||
}
|
||||
|
||||
/// Raw transmutation to `u32`.
|
||||
|
@ -478,14 +478,12 @@ impl f64 {
|
||||
/// assuming that the value is finite and fits in that type.
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(float_approx_unchecked_to)]
|
||||
///
|
||||
/// let value = 4.6_f32;
|
||||
/// let rounded = unsafe { value.approx_unchecked_to::<u16>() };
|
||||
/// let rounded = unsafe { value.to_int_unchecked::<u16>() };
|
||||
/// assert_eq!(rounded, 4);
|
||||
///
|
||||
/// let value = -128.9_f32;
|
||||
/// let rounded = unsafe { value.approx_unchecked_to::<i8>() };
|
||||
/// let rounded = unsafe { value.to_int_unchecked::<i8>() };
|
||||
/// assert_eq!(rounded, std::i8::MIN);
|
||||
/// ```
|
||||
///
|
||||
@ -496,13 +494,13 @@ impl f64 {
|
||||
/// * Not be `NaN`
|
||||
/// * Not be infinite
|
||||
/// * Be representable in the return type `Int`, after truncating off its fractional part
|
||||
#[unstable(feature = "float_approx_unchecked_to", issue = "67058")]
|
||||
#[stable(feature = "float_approx_unchecked_to", since = "1.44.0")]
|
||||
#[inline]
|
||||
pub unsafe fn approx_unchecked_to<Int>(self) -> Int
|
||||
pub unsafe fn to_int_unchecked<Int>(self) -> Int
|
||||
where
|
||||
Self: FloatToInt<Int>,
|
||||
{
|
||||
FloatToInt::<Int>::approx_unchecked(self)
|
||||
FloatToInt::<Int>::to_int_unchecked(self)
|
||||
}
|
||||
|
||||
/// Raw transmutation to `u64`.
|
||||
|
@ -544,13 +544,13 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
"float_to_int_approx_unchecked" => {
|
||||
"float_to_int_unchecked" => {
|
||||
if float_type_width(arg_tys[0]).is_none() {
|
||||
span_invalid_monomorphization_error(
|
||||
tcx.sess,
|
||||
span,
|
||||
&format!(
|
||||
"invalid monomorphization of `float_to_int_approx_unchecked` \
|
||||
"invalid monomorphization of `float_to_int_unchecked` \
|
||||
intrinsic: expected basic float type, \
|
||||
found `{}`",
|
||||
arg_tys[0]
|
||||
@ -571,7 +571,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
tcx.sess,
|
||||
span,
|
||||
&format!(
|
||||
"invalid monomorphization of `float_to_int_approx_unchecked` \
|
||||
"invalid monomorphization of `float_to_int_unchecked` \
|
||||
intrinsic: expected basic integer type, \
|
||||
found `{}`",
|
||||
ret_ty
|
||||
|
@ -275,7 +275,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
|
||||
"fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => {
|
||||
(1, vec![param(0), param(0)], param(0))
|
||||
}
|
||||
"float_to_int_approx_unchecked" => (2, vec![param(0)], param(1)),
|
||||
"float_to_int_unchecked" => (2, vec![param(0)], param(1)),
|
||||
|
||||
"assume" => (0, vec![tcx.types.bool], tcx.mk_unit()),
|
||||
"likely" => (0, vec![tcx.types.bool], tcx.types.bool),
|
||||
|
Loading…
x
Reference in New Issue
Block a user