diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-04-03 00:32:00 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-03 00:32:00 +0200 |
| commit | 1eabbd024c0e49d8ca66c804f502c65cbad90ced (patch) | |
| tree | 04acfbfa5c0af0d21c6742ee7019398c57c211c6 /src | |
| parent | 537ccdf3ac44c8c7a8d36cbdbe6fb224afabb7ae (diff) | |
| parent | 56147219a552b8383e66f9e3e8f0c92ea332aaf4 (diff) | |
| download | rust-1eabbd024c0e49d8ca66c804f502c65cbad90ced.tar.gz rust-1eabbd024c0e49d8ca66c804f502c65cbad90ced.zip | |
Rollup merge of #70487 - Mark-Simulacrum:float-unchecked-casts, r=SimonSapin
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. As such, I believe this also likely unblocks #10184 (our oldest I-unsound issue!), as once this rolls out to stable it would be far easier IMO to change the behavior of `as` to be safe by default. This does not stabilize the trait or the associated method, as they are deemed internal implementation details (and consumers should not, generally, want to expose them, as in practice all callers likely know statically/without generics what the return type is). Closes #67058
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcore/convert/num.rs | 15 | ||||
| -rw-r--r-- | src/libcore/intrinsics.rs | 8 | ||||
| -rw-r--r-- | src/libcore/num/f32.rs | 12 | ||||
| -rw-r--r-- | src/libcore/num/f64.rs | 12 | ||||
| -rw-r--r-- | src/librustc_codegen_llvm/intrinsic.rs | 6 | ||||
| -rw-r--r-- | src/librustc_typeck/check/intrinsic.rs | 2 |
6 files changed, 33 insertions, 22 deletions
diff --git a/src/libcore/convert/num.rs b/src/libcore/convert/num.rs index 752199c94b8..66ae760fc1f 100644 --- a/src/libcore/convert/num.rs +++ b/src/libcore/convert/num.rs @@ -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) + } } } )+ diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 0c956104221..7e9140faa64 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -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 diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 3fdc2bae338..09f1eab2d4b 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -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`. diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 129df937c0b..65ef7ba9ac7 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -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`. diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index bc7a9c566b4..5734eae7d59 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -543,13 +543,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] @@ -570,7 +570,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 diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index ce7166b2c76..05028ff0b2c 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -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), |
