Rollup merge of #119726 - NCGThompson:div-overflow-doc, r=Nilstrieb

Tweak Library Integer Division Docs

Improved the documentation and diagnostics related to panicking in the division-like methods in std:

* For signed methods that can overflow, clarified "results in overflow" to "self is -1 and rhs is Self::MIN." This is more concise than saying "results in overflow" and then explaining how it could overflow.
* For floor/ceil_div, corrected the documentation and made it more like the documentation in other methods.
* For signed methods that can overflow, explicitly mention that they are not affected by compiler flags.
* Removed all unused rustc_inherit_overflow_checks attributes. The non-division-like operations will never overflow.
* Added track_caller attributes to all methods that can panic. The panic messages will always be correct. For example, division methods all have / before %.
* Edited the saturating_div documentation to be consistent with similar methods.
This commit is contained in:
Matthias Krüger 2024-01-22 07:56:42 +01:00 committed by GitHub
commit 7d7c2257d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 34 additions and 36 deletions

View File

@ -1643,6 +1643,10 @@ macro_rules! int_impl {
/// Saturating integer division. Computes `self / rhs`, saturating at the /// Saturating integer division. Computes `self / rhs`, saturating at the
/// numeric bounds instead of overflowing. /// numeric bounds instead of overflowing.
/// ///
/// # Panics
///
/// This function will panic if `rhs` is 0.
///
/// # Examples /// # Examples
/// ///
/// Basic usage: /// Basic usage:
@ -1653,11 +1657,6 @@ macro_rules! int_impl {
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.saturating_div(-1), ", stringify!($SelfT), "::MAX);")] #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.saturating_div(-1), ", stringify!($SelfT), "::MAX);")]
/// ///
/// ``` /// ```
///
/// ```should_panic
#[doc = concat!("let _ = 1", stringify!($SelfT), ".saturating_div(0);")]
///
/// ```
#[stable(feature = "saturating_div", since = "1.58.0")] #[stable(feature = "saturating_div", since = "1.58.0")]
#[rustc_const_stable(feature = "saturating_div", since = "1.58.0")] #[rustc_const_stable(feature = "saturating_div", since = "1.58.0")]
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
@ -2435,6 +2434,7 @@ macro_rules! int_impl {
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline] #[inline]
#[track_caller]
pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
if unlikely!(rhs == -1) { if unlikely!(rhs == -1) {
(0, self == Self::MIN) (0, self == Self::MIN)
@ -2674,7 +2674,8 @@ macro_rules! int_impl {
/// ///
/// # Panics /// # Panics
/// ///
/// This function will panic if `rhs` is 0 or the division results in overflow. /// This function will panic if `rhs` is 0 or if `self` is -1 and `rhs` is
/// `Self::MIN`. This behavior is not affected by the `overflow-checks` flag.
/// ///
/// # Examples /// # Examples
/// ///
@ -2694,7 +2695,7 @@ macro_rules! int_impl {
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline] #[inline]
#[rustc_inherit_overflow_checks] #[track_caller]
pub const fn div_euclid(self, rhs: Self) -> Self { pub const fn div_euclid(self, rhs: Self) -> Self {
let q = self / rhs; let q = self / rhs;
if self % rhs < 0 { if self % rhs < 0 {
@ -2712,7 +2713,8 @@ macro_rules! int_impl {
/// ///
/// # Panics /// # Panics
/// ///
/// This function will panic if `rhs` is 0 or the division results in overflow. /// This function will panic if `rhs` is 0 or if `self` is -1 and `rhs` is
/// `Self::MIN`. This behavior is not affected by the `overflow-checks` flag.
/// ///
/// # Examples /// # Examples
/// ///
@ -2733,7 +2735,7 @@ macro_rules! int_impl {
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline] #[inline]
#[rustc_inherit_overflow_checks] #[track_caller]
pub const fn rem_euclid(self, rhs: Self) -> Self { pub const fn rem_euclid(self, rhs: Self) -> Self {
let r = self % rhs; let r = self % rhs;
if r < 0 { if r < 0 {
@ -2755,12 +2757,8 @@ macro_rules! int_impl {
/// ///
/// # Panics /// # Panics
/// ///
/// This function will panic if `rhs` is zero. /// This function will panic if `rhs` is 0 or if `self` is -1 and `rhs` is
/// /// `Self::MIN`. This behavior is not affected by the `overflow-checks` flag.
/// ## Overflow behavior
///
/// On overflow, this function will panic if overflow checks are enabled (default in debug
/// mode) and wrap if overflow checks are disabled (default in release mode).
/// ///
/// # Examples /// # Examples
/// ///
@ -2780,7 +2778,7 @@ macro_rules! int_impl {
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline] #[inline]
#[rustc_inherit_overflow_checks] #[track_caller]
pub const fn div_floor(self, rhs: Self) -> Self { pub const fn div_floor(self, rhs: Self) -> Self {
let d = self / rhs; let d = self / rhs;
let r = self % rhs; let r = self % rhs;
@ -2795,12 +2793,8 @@ macro_rules! int_impl {
/// ///
/// # Panics /// # Panics
/// ///
/// This function will panic if `rhs` is zero. /// This function will panic if `rhs` is 0 or if `self` is -1 and `rhs` is
/// /// `Self::MIN`. This behavior is not affected by the `overflow-checks` flag.
/// ## Overflow behavior
///
/// On overflow, this function will panic if overflow checks are enabled (default in debug
/// mode) and wrap if overflow checks are disabled (default in release mode).
/// ///
/// # Examples /// # Examples
/// ///
@ -2820,7 +2814,7 @@ macro_rules! int_impl {
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline] #[inline]
#[rustc_inherit_overflow_checks] #[track_caller]
pub const fn div_ceil(self, rhs: Self) -> Self { pub const fn div_ceil(self, rhs: Self) -> Self {
let d = self / rhs; let d = self / rhs;
let r = self % rhs; let r = self % rhs;

View File

@ -1531,6 +1531,10 @@ macro_rules! uint_impl {
/// Saturating integer division. Computes `self / rhs`, saturating at the /// Saturating integer division. Computes `self / rhs`, saturating at the
/// numeric bounds instead of overflowing. /// numeric bounds instead of overflowing.
/// ///
/// # Panics
///
/// This function will panic if `rhs` is 0.
///
/// # Examples /// # Examples
/// ///
/// Basic usage: /// Basic usage:
@ -1539,16 +1543,12 @@ macro_rules! uint_impl {
#[doc = concat!("assert_eq!(5", stringify!($SelfT), ".saturating_div(2), 2);")] #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".saturating_div(2), 2);")]
/// ///
/// ``` /// ```
///
/// ```should_panic
#[doc = concat!("let _ = 1", stringify!($SelfT), ".saturating_div(0);")]
///
/// ```
#[stable(feature = "saturating_div", since = "1.58.0")] #[stable(feature = "saturating_div", since = "1.58.0")]
#[rustc_const_stable(feature = "saturating_div", since = "1.58.0")] #[rustc_const_stable(feature = "saturating_div", since = "1.58.0")]
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline] #[inline]
#[track_caller]
pub const fn saturating_div(self, rhs: Self) -> Self { pub const fn saturating_div(self, rhs: Self) -> Self {
// on unsigned types, there is no overflow in integer division // on unsigned types, there is no overflow in integer division
self.wrapping_div(rhs) self.wrapping_div(rhs)
@ -1683,6 +1683,7 @@ macro_rules! uint_impl {
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline(always)] #[inline(always)]
#[track_caller]
pub const fn wrapping_div(self, rhs: Self) -> Self { pub const fn wrapping_div(self, rhs: Self) -> Self {
self / rhs self / rhs
} }
@ -1712,6 +1713,7 @@ macro_rules! uint_impl {
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline(always)] #[inline(always)]
#[track_caller]
pub const fn wrapping_div_euclid(self, rhs: Self) -> Self { pub const fn wrapping_div_euclid(self, rhs: Self) -> Self {
self / rhs self / rhs
} }
@ -1739,6 +1741,7 @@ macro_rules! uint_impl {
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline(always)] #[inline(always)]
#[track_caller]
pub const fn wrapping_rem(self, rhs: Self) -> Self { pub const fn wrapping_rem(self, rhs: Self) -> Self {
self % rhs self % rhs
} }
@ -1769,6 +1772,7 @@ macro_rules! uint_impl {
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline(always)] #[inline(always)]
#[track_caller]
pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self { pub const fn wrapping_rem_euclid(self, rhs: Self) -> Self {
self % rhs self % rhs
} }
@ -2151,6 +2155,7 @@ macro_rules! uint_impl {
#[rustc_const_stable(feature = "const_overflowing_int_methods", since = "1.52.0")] #[rustc_const_stable(feature = "const_overflowing_int_methods", since = "1.52.0")]
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[track_caller]
pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) { pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
(self / rhs, false) (self / rhs, false)
} }
@ -2181,6 +2186,7 @@ macro_rules! uint_impl {
#[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")] #[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")]
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[track_caller]
pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) { pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
(self / rhs, false) (self / rhs, false)
} }
@ -2208,6 +2214,7 @@ macro_rules! uint_impl {
#[rustc_const_stable(feature = "const_overflowing_int_methods", since = "1.52.0")] #[rustc_const_stable(feature = "const_overflowing_int_methods", since = "1.52.0")]
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[track_caller]
pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) { pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
(self % rhs, false) (self % rhs, false)
} }
@ -2238,6 +2245,7 @@ macro_rules! uint_impl {
#[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")] #[rustc_const_stable(feature = "const_euclidean_int_methods", since = "1.52.0")]
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[track_caller]
pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) { pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
(self % rhs, false) (self % rhs, false)
} }
@ -2473,7 +2481,7 @@ macro_rules! uint_impl {
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline(always)] #[inline(always)]
#[rustc_inherit_overflow_checks] #[track_caller]
pub const fn div_euclid(self, rhs: Self) -> Self { pub const fn div_euclid(self, rhs: Self) -> Self {
self / rhs self / rhs
} }
@ -2502,7 +2510,7 @@ macro_rules! uint_impl {
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline(always)] #[inline(always)]
#[rustc_inherit_overflow_checks] #[track_caller]
pub const fn rem_euclid(self, rhs: Self) -> Self { pub const fn rem_euclid(self, rhs: Self) -> Self {
self % rhs self % rhs
} }
@ -2527,6 +2535,7 @@ macro_rules! uint_impl {
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline(always)] #[inline(always)]
#[track_caller]
pub const fn div_floor(self, rhs: Self) -> Self { pub const fn div_floor(self, rhs: Self) -> Self {
self / rhs self / rhs
} }
@ -2537,11 +2546,6 @@ macro_rules! uint_impl {
/// ///
/// This function will panic if `rhs` is zero. /// This function will panic if `rhs` is zero.
/// ///
/// ## Overflow behavior
///
/// On overflow, this function will panic if overflow checks are enabled (default in debug
/// mode) and wrap if overflow checks are disabled (default in release mode).
///
/// # Examples /// # Examples
/// ///
/// Basic usage: /// Basic usage:
@ -2554,7 +2558,7 @@ macro_rules! uint_impl {
#[must_use = "this returns the result of the operation, \ #[must_use = "this returns the result of the operation, \
without modifying the original"] without modifying the original"]
#[inline] #[inline]
#[rustc_inherit_overflow_checks] #[track_caller]
pub const fn div_ceil(self, rhs: Self) -> Self { pub const fn div_ceil(self, rhs: Self) -> Self {
let d = self / rhs; let d = self / rhs;
let r = self % rhs; let r = self % rhs;