Skip to content

Commit 1eabbd0

Browse files
authored
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
2 parents 537ccdf + 5614721 commit 1eabbd0

File tree

6 files changed

+33
-22
lines changed

6 files changed

+33
-22
lines changed

src/libcore/convert/num.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ mod private {
1313
/// Typically doesn’t need to be used directly.
1414
#[unstable(feature = "convert_float_to_int", issue = "67057")]
1515
pub trait FloatToInt<Int>: private::Sealed + Sized {
16-
#[unstable(feature = "float_approx_unchecked_to", issue = "67058")]
16+
#[unstable(feature = "convert_float_to_int", issue = "67057")]
1717
#[doc(hidden)]
18-
unsafe fn approx_unchecked(self) -> Int;
18+
unsafe fn to_int_unchecked(self) -> Int;
1919
}
2020

2121
macro_rules! impl_float_to_int {
@@ -27,8 +27,15 @@ macro_rules! impl_float_to_int {
2727
impl FloatToInt<$Int> for $Float {
2828
#[doc(hidden)]
2929
#[inline]
30-
unsafe fn approx_unchecked(self) -> $Int {
31-
crate::intrinsics::float_to_int_approx_unchecked(self)
30+
unsafe fn to_int_unchecked(self) -> $Int {
31+
#[cfg(bootstrap)]
32+
{
33+
crate::intrinsics::float_to_int_approx_unchecked(self)
34+
}
35+
#[cfg(not(bootstrap))]
36+
{
37+
crate::intrinsics::float_to_int_unchecked(self)
38+
}
3239
}
3340
}
3441
)+

src/libcore/intrinsics.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1582,8 +1582,16 @@ extern "rust-intrinsic" {
15821582
/// Convert with LLVM’s fptoui/fptosi, which may return undef for values out of range
15831583
/// (<https://github.com/rust-lang/rust/issues/10184>)
15841584
/// This is under stabilization at <https://github.com/rust-lang/rust/issues/67058>
1585+
#[cfg(bootstrap)]
15851586
pub fn float_to_int_approx_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
15861587

1588+
/// Convert with LLVM’s fptoui/fptosi, which may return undef for values out of range
1589+
/// (<https://github.com/rust-lang/rust/issues/10184>)
1590+
///
1591+
/// Stabilized as `f32::to_int_unchecked` and `f64::to_int_unchecked`.
1592+
#[cfg(not(bootstrap))]
1593+
pub fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
1594+
15871595
/// Returns the number of bits set in an integer type `T`
15881596
///
15891597
/// The stabilized versions of this intrinsic are available on the integer

src/libcore/num/f32.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -464,14 +464,12 @@ impl f32 {
464464
/// assuming that the value is finite and fits in that type.
465465
///
466466
/// ```
467-
/// #![feature(float_approx_unchecked_to)]
468-
///
469467
/// let value = 4.6_f32;
470-
/// let rounded = unsafe { value.approx_unchecked_to::<u16>() };
468+
/// let rounded = unsafe { value.to_int_unchecked::<u16>() };
471469
/// assert_eq!(rounded, 4);
472470
///
473471
/// let value = -128.9_f32;
474-
/// let rounded = unsafe { value.approx_unchecked_to::<i8>() };
472+
/// let rounded = unsafe { value.to_int_unchecked::<i8>() };
475473
/// assert_eq!(rounded, std::i8::MIN);
476474
/// ```
477475
///
@@ -482,13 +480,13 @@ impl f32 {
482480
/// * Not be `NaN`
483481
/// * Not be infinite
484482
/// * Be representable in the return type `Int`, after truncating off its fractional part
485-
#[unstable(feature = "float_approx_unchecked_to", issue = "67058")]
483+
#[stable(feature = "float_approx_unchecked_to", since = "1.44.0")]
486484
#[inline]
487-
pub unsafe fn approx_unchecked_to<Int>(self) -> Int
485+
pub unsafe fn to_int_unchecked<Int>(self) -> Int
488486
where
489487
Self: FloatToInt<Int>,
490488
{
491-
FloatToInt::<Int>::approx_unchecked(self)
489+
FloatToInt::<Int>::to_int_unchecked(self)
492490
}
493491

494492
/// Raw transmutation to `u32`.

src/libcore/num/f64.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -478,14 +478,12 @@ impl f64 {
478478
/// assuming that the value is finite and fits in that type.
479479
///
480480
/// ```
481-
/// #![feature(float_approx_unchecked_to)]
482-
///
483481
/// let value = 4.6_f32;
484-
/// let rounded = unsafe { value.approx_unchecked_to::<u16>() };
482+
/// let rounded = unsafe { value.to_int_unchecked::<u16>() };
485483
/// assert_eq!(rounded, 4);
486484
///
487485
/// let value = -128.9_f32;
488-
/// let rounded = unsafe { value.approx_unchecked_to::<i8>() };
486+
/// let rounded = unsafe { value.to_int_unchecked::<i8>() };
489487
/// assert_eq!(rounded, std::i8::MIN);
490488
/// ```
491489
///
@@ -496,13 +494,13 @@ impl f64 {
496494
/// * Not be `NaN`
497495
/// * Not be infinite
498496
/// * Be representable in the return type `Int`, after truncating off its fractional part
499-
#[unstable(feature = "float_approx_unchecked_to", issue = "67058")]
497+
#[stable(feature = "float_approx_unchecked_to", since = "1.44.0")]
500498
#[inline]
501-
pub unsafe fn approx_unchecked_to<Int>(self) -> Int
499+
pub unsafe fn to_int_unchecked<Int>(self) -> Int
502500
where
503501
Self: FloatToInt<Int>,
504502
{
505-
FloatToInt::<Int>::approx_unchecked(self)
503+
FloatToInt::<Int>::to_int_unchecked(self)
506504
}
507505

508506
/// Raw transmutation to `u64`.

src/librustc_codegen_llvm/intrinsic.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -543,13 +543,13 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
543543
}
544544
}
545545

546-
"float_to_int_approx_unchecked" => {
546+
"float_to_int_unchecked" => {
547547
if float_type_width(arg_tys[0]).is_none() {
548548
span_invalid_monomorphization_error(
549549
tcx.sess,
550550
span,
551551
&format!(
552-
"invalid monomorphization of `float_to_int_approx_unchecked` \
552+
"invalid monomorphization of `float_to_int_unchecked` \
553553
intrinsic: expected basic float type, \
554554
found `{}`",
555555
arg_tys[0]
@@ -570,7 +570,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
570570
tcx.sess,
571571
span,
572572
&format!(
573-
"invalid monomorphization of `float_to_int_approx_unchecked` \
573+
"invalid monomorphization of `float_to_int_unchecked` \
574574
intrinsic: expected basic integer type, \
575575
found `{}`",
576576
ret_ty

src/librustc_typeck/check/intrinsic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
275275
"fadd_fast" | "fsub_fast" | "fmul_fast" | "fdiv_fast" | "frem_fast" => {
276276
(1, vec![param(0), param(0)], param(0))
277277
}
278-
"float_to_int_approx_unchecked" => (2, vec![param(0)], param(1)),
278+
"float_to_int_unchecked" => (2, vec![param(0)], param(1)),
279279

280280
"assume" => (0, vec![tcx.types.bool], tcx.mk_unit()),
281281
"likely" => (0, vec![tcx.types.bool], tcx.types.bool),

0 commit comments

Comments
 (0)