From a1486589e70f2b17614ac96692d51cb325f48a18 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 14 Mar 2024 15:08:53 -0700 Subject: [PATCH] Stabilize `unchecked_{add,sub,mul}` --- library/core/src/intrinsics.rs | 15 +++++---- library/core/src/lib.rs | 2 -- library/core/src/num/int_macros.rs | 48 ++++++++++++++++++----------- library/core/src/num/uint_macros.rs | 48 ++++++++++++++++++----------- 4 files changed, 69 insertions(+), 44 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 86b9a39d68a67..9b11a3cdbde5f 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2224,24 +2224,27 @@ extern "rust-intrinsic" { /// Returns the result of an unchecked addition, resulting in /// undefined behavior when `x + y > T::MAX` or `x + y < T::MIN`. /// - /// This intrinsic does not have a stable counterpart. - #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")] + /// The stable counterpart of this intrinsic is `unchecked_add` on the various + /// integer types, such as [`u16::unchecked_add`] and [`i64::unchecked_add`]. + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[rustc_nounwind] pub fn unchecked_add(x: T, y: T) -> T; /// Returns the result of an unchecked subtraction, resulting in /// undefined behavior when `x - y > T::MAX` or `x - y < T::MIN`. /// - /// This intrinsic does not have a stable counterpart. - #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")] + /// The stable counterpart of this intrinsic is `unchecked_sub` on the various + /// integer types, such as [`u16::unchecked_sub`] and [`i64::unchecked_sub`]. + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[rustc_nounwind] pub fn unchecked_sub(x: T, y: T) -> T; /// Returns the result of an unchecked multiplication, resulting in /// undefined behavior when `x * y > T::MAX` or `x * y < T::MIN`. /// - /// This intrinsic does not have a stable counterpart. - #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")] + /// The stable counterpart of this intrinsic is `unchecked_mul` on the various + /// integer types, such as [`u16::unchecked_mul`] and [`i64::unchecked_mul`]. + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[rustc_nounwind] pub fn unchecked_mul(x: T, y: T) -> T; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 9b786feba8988..5aeeacc4372aa 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -134,7 +134,6 @@ #![feature(const_heap)] #![feature(const_hint_assert_unchecked)] #![feature(const_index_range_slice_index)] -#![feature(const_int_unchecked_arith)] #![feature(const_intrinsic_copy)] #![feature(const_intrinsic_forget)] #![feature(const_ipv4)] @@ -193,7 +192,6 @@ #![feature(str_split_inclusive_remainder)] #![feature(str_split_remainder)] #![feature(strict_provenance)] -#![feature(unchecked_math)] #![feature(unchecked_shifts)] #![feature(utf16_extra)] #![feature(utf16_extra_const)] diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index fa37ee4ffb204..9101d5064f9e3 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -492,21 +492,25 @@ macro_rules! int_impl { /// Unchecked integer addition. Computes `self + rhs`, assuming overflow /// cannot occur. /// + /// Calling `x.unchecked_add(y)` is semantically equivalent to calling + /// `x.`[`checked_add`]`(y).`[`unwrap_unchecked`]`()`. + /// + /// If you're just trying to avoid the panic in debug mode, then **do not** + /// use this. Instead, you're looking for [`wrapping_add`]. + /// /// # Safety /// /// This results in undefined behavior when #[doc = concat!("`self + rhs > ", stringify!($SelfT), "::MAX` or `self + rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_add`] would return `None`. /// + /// [`unwrap_unchecked`]: Option::unwrap_unchecked #[doc = concat!("[`checked_add`]: ", stringify!($SelfT), "::checked_add")] - #[unstable( - feature = "unchecked_math", - reason = "niche optimization path", - issue = "85122", - )] + #[doc = concat!("[`wrapping_add`]: ", stringify!($SelfT), "::wrapping_add")] + #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_math", issue = "85122")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { @@ -630,21 +634,25 @@ macro_rules! int_impl { /// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow /// cannot occur. /// + /// Calling `x.unchecked_sub(y)` is semantically equivalent to calling + /// `x.`[`checked_sub`]`(y).`[`unwrap_unchecked`]`()`. + /// + /// If you're just trying to avoid the panic in debug mode, then **do not** + /// use this. Instead, you're looking for [`wrapping_sub`]. + /// /// # Safety /// /// This results in undefined behavior when #[doc = concat!("`self - rhs > ", stringify!($SelfT), "::MAX` or `self - rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_sub`] would return `None`. /// + /// [`unwrap_unchecked`]: Option::unwrap_unchecked #[doc = concat!("[`checked_sub`]: ", stringify!($SelfT), "::checked_sub")] - #[unstable( - feature = "unchecked_math", - reason = "niche optimization path", - issue = "85122", - )] + #[doc = concat!("[`wrapping_sub`]: ", stringify!($SelfT), "::wrapping_sub")] + #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_math", issue = "85122")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { @@ -768,21 +776,25 @@ macro_rules! int_impl { /// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow /// cannot occur. /// + /// Calling `x.unchecked_mul(y)` is semantically equivalent to calling + /// `x.`[`checked_mul`]`(y).`[`unwrap_unchecked`]`()`. + /// + /// If you're just trying to avoid the panic in debug mode, then **do not** + /// use this. Instead, you're looking for [`wrapping_mul`]. + /// /// # Safety /// /// This results in undefined behavior when #[doc = concat!("`self * rhs > ", stringify!($SelfT), "::MAX` or `self * rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_mul`] would return `None`. /// + /// [`unwrap_unchecked`]: Option::unwrap_unchecked #[doc = concat!("[`checked_mul`]: ", stringify!($SelfT), "::checked_mul")] - #[unstable( - feature = "unchecked_math", - reason = "niche optimization path", - issue = "85122", - )] + #[doc = concat!("[`wrapping_mul`]: ", stringify!($SelfT), "::wrapping_mul")] + #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_math", issue = "85122")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self { diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 081a3c0b118ea..c098f1894a610 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -500,21 +500,25 @@ macro_rules! uint_impl { /// Unchecked integer addition. Computes `self + rhs`, assuming overflow /// cannot occur. /// + /// Calling `x.unchecked_add(y)` is semantically equivalent to calling + /// `x.`[`checked_add`]`(y).`[`unwrap_unchecked`]`()`. + /// + /// If you're just trying to avoid the panic in debug mode, then **do not** + /// use this. Instead, you're looking for [`wrapping_add`]. + /// /// # Safety /// /// This results in undefined behavior when #[doc = concat!("`self + rhs > ", stringify!($SelfT), "::MAX` or `self + rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_add`] would return `None`. /// + /// [`unwrap_unchecked`]: Option::unwrap_unchecked #[doc = concat!("[`checked_add`]: ", stringify!($SelfT), "::checked_add")] - #[unstable( - feature = "unchecked_math", - reason = "niche optimization path", - issue = "85122", - )] + #[doc = concat!("[`wrapping_add`]: ", stringify!($SelfT), "::wrapping_add")] + #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_math", issue = "85122")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { @@ -644,21 +648,25 @@ macro_rules! uint_impl { /// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow /// cannot occur. /// + /// Calling `x.unchecked_sub(y)` is semantically equivalent to calling + /// `x.`[`checked_sub`]`(y).`[`unwrap_unchecked`]`()`. + /// + /// If you're just trying to avoid the panic in debug mode, then **do not** + /// use this. Instead, you're looking for [`wrapping_sub`]. + /// /// # Safety /// /// This results in undefined behavior when #[doc = concat!("`self - rhs > ", stringify!($SelfT), "::MAX` or `self - rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_sub`] would return `None`. /// + /// [`unwrap_unchecked`]: Option::unwrap_unchecked #[doc = concat!("[`checked_sub`]: ", stringify!($SelfT), "::checked_sub")] - #[unstable( - feature = "unchecked_math", - reason = "niche optimization path", - issue = "85122", - )] + #[doc = concat!("[`wrapping_sub`]: ", stringify!($SelfT), "::wrapping_sub")] + #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_math", issue = "85122")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { @@ -726,21 +734,25 @@ macro_rules! uint_impl { /// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow /// cannot occur. /// + /// Calling `x.unchecked_mul(y)` is semantically equivalent to calling + /// `x.`[`checked_mul`]`(y).`[`unwrap_unchecked`]`()`. + /// + /// If you're just trying to avoid the panic in debug mode, then **do not** + /// use this. Instead, you're looking for [`wrapping_mul`]. + /// /// # Safety /// /// This results in undefined behavior when #[doc = concat!("`self * rhs > ", stringify!($SelfT), "::MAX` or `self * rhs < ", stringify!($SelfT), "::MIN`,")] /// i.e. when [`checked_mul`] would return `None`. /// + /// [`unwrap_unchecked`]: Option::unwrap_unchecked #[doc = concat!("[`checked_mul`]: ", stringify!($SelfT), "::checked_mul")] - #[unstable( - feature = "unchecked_math", - reason = "niche optimization path", - issue = "85122", - )] + #[doc = concat!("[`wrapping_mul`]: ", stringify!($SelfT), "::wrapping_mul")] + #[stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "unchecked_math", since = "CURRENT_RUSTC_VERSION")] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_math", issue = "85122")] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {