about summary refs log tree commit diff
path: root/library/core/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-01-21 13:13:03 +0000
committerbors <bors@rust-lang.org>2024-01-21 13:13:03 +0000
commit70e720bc685e21bbae276445fedf7d89613ecb0d (patch)
treebea46b5cbfb4f8baa9e4b0e34be77eb9600be0da /library/core/src
parent0c8e1e6f444d28742aff75f8789df69007ca589a (diff)
parent7092c660077d185df375eaf07d649be2b49018d0 (diff)
downloadrust-70e720bc685e21bbae276445fedf7d89613ecb0d.tar.gz
rust-70e720bc685e21bbae276445fedf7d89613ecb0d.zip
Auto merge of #3270 - rust-lang:rustup-2024-01-21, r=RalfJung
Automatic Rustup
Diffstat (limited to 'library/core/src')
-rw-r--r--library/core/src/array/mod.rs8
-rw-r--r--library/core/src/ascii.rs11
-rw-r--r--library/core/src/error.rs2
-rw-r--r--library/core/src/iter/adapters/flatten.rs8
-rw-r--r--library/core/src/iter/adapters/fuse.rs4
-rw-r--r--library/core/src/iter/adapters/map.rs4
-rw-r--r--library/core/src/iter/traits/iterator.rs26
-rw-r--r--library/core/src/lib.rs3
-rw-r--r--library/core/src/macros/mod.rs4
-rw-r--r--library/core/src/mem/mod.rs16
-rw-r--r--library/core/src/net/ip_addr.rs25
-rw-r--r--library/core/src/num/int_macros.rs538
-rw-r--r--library/core/src/num/mod.rs19
-rw-r--r--library/core/src/num/nonzero.rs2572
-rw-r--r--library/core/src/num/overflow_panic.rs51
-rw-r--r--library/core/src/num/uint_macros.rs424
-rw-r--r--library/core/src/ops/range.rs4
-rw-r--r--library/core/src/option.rs13
-rw-r--r--library/core/src/primitive_docs.rs10
-rw-r--r--library/core/src/result.rs2
-rw-r--r--library/core/src/slice/ascii.rs41
-rw-r--r--library/core/src/slice/iter.rs9
-rw-r--r--library/core/src/slice/mod.rs315
-rw-r--r--library/core/src/sync/atomic.rs13
24 files changed, 2555 insertions, 1567 deletions
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 34213637a32..9d95b32409c 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -647,7 +647,7 @@ impl<T, const N: usize> [T; N] {
     )]
     #[inline]
     pub fn split_array_ref<const M: usize>(&self) -> (&[T; M], &[T]) {
-        (&self[..]).split_array_ref::<M>()
+        (&self[..]).split_first_chunk::<M>().unwrap()
     }
 
     /// Divides one mutable array reference into two at an index.
@@ -680,7 +680,7 @@ impl<T, const N: usize> [T; N] {
     )]
     #[inline]
     pub fn split_array_mut<const M: usize>(&mut self) -> (&mut [T; M], &mut [T]) {
-        (&mut self[..]).split_array_mut::<M>()
+        (&mut self[..]).split_first_chunk_mut::<M>().unwrap()
     }
 
     /// Divides one array reference into two at an index from the end.
@@ -725,7 +725,7 @@ impl<T, const N: usize> [T; N] {
     )]
     #[inline]
     pub fn rsplit_array_ref<const M: usize>(&self) -> (&[T], &[T; M]) {
-        (&self[..]).rsplit_array_ref::<M>()
+        (&self[..]).split_last_chunk::<M>().unwrap()
     }
 
     /// Divides one mutable array reference into two at an index from the end.
@@ -758,7 +758,7 @@ impl<T, const N: usize> [T; N] {
     )]
     #[inline]
     pub fn rsplit_array_mut<const M: usize>(&mut self) -> (&mut [T], &mut [T; M]) {
-        (&mut self[..]).rsplit_array_mut::<M>()
+        (&mut self[..]).split_last_chunk_mut::<M>().unwrap()
     }
 }
 
diff --git a/library/core/src/ascii.rs b/library/core/src/ascii.rs
index ef8e4d098ed..02867789b79 100644
--- a/library/core/src/ascii.rs
+++ b/library/core/src/ascii.rs
@@ -96,6 +96,17 @@ pub fn escape_default(c: u8) -> EscapeDefault {
     EscapeDefault(escape::EscapeIterInner::new(data, range))
 }
 
+impl EscapeDefault {
+    pub(crate) fn empty() -> Self {
+        let data = [Char::Null; 4];
+        EscapeDefault(escape::EscapeIterInner::new(data, 0..0))
+    }
+
+    pub(crate) fn as_str(&self) -> &str {
+        self.0.as_str()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Iterator for EscapeDefault {
     type Item = u8;
diff --git a/library/core/src/error.rs b/library/core/src/error.rs
index f1a7ad93548..ded17e69bd9 100644
--- a/library/core/src/error.rs
+++ b/library/core/src/error.rs
@@ -415,7 +415,7 @@ where
 // Request and its methods
 ///////////////////////////////////////////////////////////////////////////////
 
-/// `Request` supports generic, type-driven access to data. It's use is currently restricted to the
+/// `Request` supports generic, type-driven access to data. Its use is currently restricted to the
 /// standard library in cases where trait authors wish to allow trait implementors to share generic
 /// information across trait boundaries. The motivating and prototypical use case is
 /// `core::error::Error` which would otherwise require a method per concrete type (eg.
diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs
index 6122332da0d..7d6f746845e 100644
--- a/library/core/src/iter/adapters/flatten.rs
+++ b/library/core/src/iter/adapters/flatten.rs
@@ -24,6 +24,14 @@ impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> FlatMap<I, U, F> {
     pub(in crate::iter) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
         FlatMap { inner: FlattenCompat::new(iter.map(f)) }
     }
+
+    pub(crate) fn into_parts(self) -> (Option<U::IntoIter>, Option<I>, Option<U::IntoIter>) {
+        (
+            self.inner.frontiter,
+            self.inner.iter.into_inner().map(Map::into_inner),
+            self.inner.backiter,
+        )
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/iter/adapters/fuse.rs b/library/core/src/iter/adapters/fuse.rs
index 462a7e87733..7781ed088b7 100644
--- a/library/core/src/iter/adapters/fuse.rs
+++ b/library/core/src/iter/adapters/fuse.rs
@@ -24,6 +24,10 @@ impl<I> Fuse<I> {
     pub(in crate::iter) fn new(iter: I) -> Fuse<I> {
         Fuse { iter: Some(iter) }
     }
+
+    pub(crate) fn into_inner(self) -> Option<I> {
+        self.iter
+    }
 }
 
 #[stable(feature = "fused", since = "1.26.0")]
diff --git a/library/core/src/iter/adapters/map.rs b/library/core/src/iter/adapters/map.rs
index e27fc7257f6..c882c9e7f3f 100644
--- a/library/core/src/iter/adapters/map.rs
+++ b/library/core/src/iter/adapters/map.rs
@@ -69,6 +69,10 @@ impl<I, F> Map<I, F> {
     pub(in crate::iter) fn new(iter: I, f: F) -> Map<I, F> {
         Map { iter, f }
     }
+
+    pub(crate) fn into_inner(self) -> I {
+        self.iter
+    }
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index d94a508b5b2..83f8fd25b50 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -4033,42 +4033,42 @@ pub trait Iterator {
         Self: Sized,
         Self::Item: PartialOrd,
     {
-        self.is_sorted_by(PartialOrd::partial_cmp)
+        self.is_sorted_by(|a, b| a <= b)
     }
 
     /// Checks if the elements of this iterator are sorted using the given comparator function.
     ///
     /// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare`
-    /// function to determine the ordering of two elements. Apart from that, it's equivalent to
-    /// [`is_sorted`]; see its documentation for more information.
+    /// function to determine whether two elements are to be considered in sorted order.
     ///
     /// # Examples
     ///
     /// ```
     /// #![feature(is_sorted)]
     ///
-    /// assert!([1, 2, 2, 9].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
-    /// assert!(![1, 3, 2, 4].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
-    /// assert!([0].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
-    /// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| a.partial_cmp(b)));
-    /// assert!(![0.0, 1.0, f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
-    /// ```
+    /// assert!([1, 2, 2, 9].iter().is_sorted_by(|a, b| a <= b));
+    /// assert!(![1, 2, 2, 9].iter().is_sorted_by(|a, b| a < b));
     ///
-    /// [`is_sorted`]: Iterator::is_sorted
+    /// assert!([0].iter().is_sorted_by(|a, b| true));
+    /// assert!([0].iter().is_sorted_by(|a, b| false));
+    ///
+    /// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| false));
+    /// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| true));
+    /// ```
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
     #[rustc_do_not_const_check]
     fn is_sorted_by<F>(mut self, compare: F) -> bool
     where
         Self: Sized,
-        F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
+        F: FnMut(&Self::Item, &Self::Item) -> bool,
     {
         #[inline]
         fn check<'a, T>(
             last: &'a mut T,
-            mut compare: impl FnMut(&T, &T) -> Option<Ordering> + 'a,
+            mut compare: impl FnMut(&T, &T) -> bool + 'a,
         ) -> impl FnMut(T) -> bool + 'a {
             move |curr| {
-                if let Some(Ordering::Greater) | None = compare(&last, &curr) {
+                if !compare(&last, &curr) {
                     return false;
                 }
                 *last = curr;
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 1a8f245c8be..24ad78efa83 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -111,6 +111,7 @@
 //
 // Library features:
 // tidy-alphabetical-start
+#![cfg_attr(not(bootstrap), feature(offset_of_nested))]
 #![feature(char_indices_offset)]
 #![feature(const_align_of_val)]
 #![feature(const_align_of_val_raw)]
@@ -160,6 +161,7 @@
 #![feature(const_slice_ptr_len)]
 #![feature(const_slice_split_at_mut)]
 #![feature(const_str_from_utf8_unchecked_mut)]
+#![feature(const_strict_overflow_ops)]
 #![feature(const_swap)]
 #![feature(const_try)]
 #![feature(const_type_id)]
@@ -176,7 +178,6 @@
 #![feature(isqrt)]
 #![feature(maybe_uninit_uninit_array)]
 #![feature(non_null_convenience)]
-#![feature(offset_of)]
 #![feature(offset_of_enum)]
 #![feature(panic_internals)]
 #![feature(ptr_alignment_type)]
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index a2437feeeb9..9bbaf62a5ca 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1596,7 +1596,7 @@ pub(crate) mod builtin {
     ///
     /// [the reference]: ../../../reference/attributes/testing.html#the-test-attribute
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[allow_internal_unstable(test, rustc_attrs)]
+    #[allow_internal_unstable(test, rustc_attrs, coverage_attribute)]
     #[rustc_builtin_macro]
     pub macro test($item:item) {
         /* compiler built-in */
@@ -1609,7 +1609,7 @@ pub(crate) mod builtin {
         soft,
         reason = "`bench` is a part of custom test frameworks which are unstable"
     )]
-    #[allow_internal_unstable(test, rustc_attrs)]
+    #[allow_internal_unstable(test, rustc_attrs, coverage_attribute)]
     #[rustc_builtin_macro]
     pub macro bench($item:item) {
         /* compiler built-in */
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 407954001e4..318a99e23ec 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -736,7 +736,7 @@ pub const fn swap<T>(x: &mut T, y: &mut T) {
         // tends to copy the whole thing to stack rather than doing it one part
         // at a time, so instead treat them as one-element slices and piggy-back
         // the slice optimizations that will split up the swaps.
-        if size_of::<T>() / align_of::<T>() > 4 {
+        if const { size_of::<T>() / align_of::<T>() > 2 } {
             // SAFETY: exclusive references always point to one non-overlapping
             // element and are non-null and properly aligned.
             return unsafe { ptr::swap_nonoverlapping(x, y, 1) };
@@ -1303,11 +1303,12 @@ impl<T> SizedTypeProperties for T {}
 /// Enum variants may be traversed as if they were fields. Variants themselves do
 /// not have an offset.
 ///
+/// However, on stable only a single field name is supported, which blocks the use of
+/// enum support.
+///
 /// Visibility is respected - all types and fields must be visible to the call site:
 ///
 /// ```
-/// #![feature(offset_of)]
-///
 /// mod nested {
 ///     #[repr(C)]
 ///     pub struct Struct {
@@ -1330,8 +1331,6 @@ impl<T> SizedTypeProperties for T {}
 /// not *identical*, e.g.:
 ///
 /// ```
-/// #![feature(offset_of)]
-///
 /// struct Wrapper<T, U>(T, U);
 ///
 /// type A = Wrapper<u8, u8>;
@@ -1359,8 +1358,7 @@ impl<T> SizedTypeProperties for T {}
 /// # Examples
 ///
 /// ```
-/// #![feature(offset_of)]
-/// # #![feature(offset_of_enum)]
+/// #![feature(offset_of_enum, offset_of_nested)]
 ///
 /// use std::mem;
 /// #[repr(C)]
@@ -1396,7 +1394,7 @@ impl<T> SizedTypeProperties for T {}
 /// assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0);
 /// ```
 #[cfg(not(bootstrap))]
-#[unstable(feature = "offset_of", issue = "106655")]
+#[stable(feature = "offset_of", since = "CURRENT_RUSTC_VERSION")]
 #[allow_internal_unstable(builtin_syntax, hint_must_use)]
 pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) {
     // The `{}` is for better error messages
@@ -1404,7 +1402,7 @@ pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) {
 }
 
 #[cfg(bootstrap)]
-#[unstable(feature = "offset_of", issue = "106655")]
+#[stable(feature = "offset_of", since = "CURRENT_RUSTC_VERSION")]
 #[allow_internal_unstable(builtin_syntax, hint_must_use)]
 #[allow(missing_docs)]
 pub macro offset_of($Container:ty, $($fields:tt).+ $(,)?) {
diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs
index 4b5862d98a3..408002d18ca 100644
--- a/library/core/src/net/ip_addr.rs
+++ b/library/core/src/net/ip_addr.rs
@@ -1785,6 +1785,31 @@ impl Ipv6Addr {
         (self.segments()[0] & 0xff00) == 0xff00
     }
 
+    /// Returns [`true`] if the address is an IPv4-mapped address (`::ffff:0:0/96`).
+    ///
+    /// IPv4-mapped addresses can be converted to their canonical IPv4 address with
+    /// [`to_ipv4_mapped`](Ipv6Addr::to_ipv4_mapped).
+    ///
+    /// # Examples
+    /// ```
+    /// #![feature(ip)]
+    ///
+    /// use std::net::{Ipv4Addr, Ipv6Addr};
+    ///
+    /// let ipv4_mapped = Ipv4Addr::new(192, 0, 2, 255).to_ipv6_mapped();
+    /// assert_eq!(ipv4_mapped.is_ipv4_mapped(), true);
+    /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc000, 0x2ff).is_ipv4_mapped(), true);
+    ///
+    /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_ipv4_mapped(), false);
+    /// ```
+    #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")]
+    #[unstable(feature = "ip", issue = "27709")]
+    #[must_use]
+    #[inline]
+    pub const fn is_ipv4_mapped(&self) -> bool {
+        matches!(self.segments(), [0, 0, 0, 0, 0, 0xffff, _, _])
+    }
+
     /// Converts this address to an [`IPv4` address] if it's an [IPv4-mapped] address,
     /// as defined in [IETF RFC 4291 section 2.5.5.2], otherwise returns [`None`].
     ///
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index fd01f1b2610..451a2e14fe9 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -451,7 +451,40 @@ macro_rules! int_impl {
         #[inline]
         pub const fn checked_add(self, rhs: Self) -> Option<Self> {
             let (a, b) = self.overflowing_add(rhs);
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
+        }
+
+        /// Strict integer addition. Computes `self + rhs`, panicking
+        /// if overflow occurred.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).strict_add(1), ", stringify!($SelfT), "::MAX - 1);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = (", stringify!($SelfT), "::MAX - 2).strict_add(3);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_add(self, rhs: Self) -> Self {
+            let (a, b) = self.overflowing_add(rhs);
+            if unlikely!(b) { overflow_panic::add() } else { a }
         }
 
         /// Unchecked integer addition. Computes `self + rhs`, assuming overflow
@@ -498,7 +531,40 @@ macro_rules! int_impl {
         #[inline]
         pub const fn checked_add_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
             let (a, b) = self.overflowing_add_unsigned(rhs);
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
+        }
+
+        /// Strict addition with an unsigned integer. Computes `self + rhs`,
+        /// panicking if overflow occurred.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".strict_add_unsigned(2), 3);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = (", stringify!($SelfT), "::MAX - 2).strict_add_unsigned(3);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_add_unsigned(self, rhs: $UnsignedT) -> Self {
+            let (a, b) = self.overflowing_add_unsigned(rhs);
+            if unlikely!(b) { overflow_panic::add() } else { a }
         }
 
         /// Checked integer subtraction. Computes `self - rhs`, returning `None` if
@@ -519,7 +585,40 @@ macro_rules! int_impl {
         #[inline]
         pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
             let (a, b) = self.overflowing_sub(rhs);
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
+        }
+
+        /// Strict integer subtraction. Computes `self - rhs`, panicking if
+        /// overflow occurred.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 2).strict_sub(1), ", stringify!($SelfT), "::MIN + 1);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = (", stringify!($SelfT), "::MIN + 2).strict_sub(3);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_sub(self, rhs: Self) -> Self {
+            let (a, b) = self.overflowing_sub(rhs);
+            if unlikely!(b) { overflow_panic::sub() } else { a }
         }
 
         /// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow
@@ -566,7 +665,40 @@ macro_rules! int_impl {
         #[inline]
         pub const fn checked_sub_unsigned(self, rhs: $UnsignedT) -> Option<Self> {
             let (a, b) = self.overflowing_sub_unsigned(rhs);
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
+        }
+
+        /// Strict subtraction with an unsigned integer. Computes `self - rhs`,
+        /// panicking if overflow occurred.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".strict_sub_unsigned(2), -1);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = (", stringify!($SelfT), "::MIN + 2).strict_sub_unsigned(3);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_sub_unsigned(self, rhs: $UnsignedT) -> Self {
+            let (a, b) = self.overflowing_sub_unsigned(rhs);
+            if unlikely!(b) { overflow_panic::sub() } else { a }
         }
 
         /// Checked integer multiplication. Computes `self * rhs`, returning `None` if
@@ -587,7 +719,40 @@ macro_rules! int_impl {
         #[inline]
         pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
             let (a, b) = self.overflowing_mul(rhs);
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
+        }
+
+        /// Strict integer multiplication. Computes `self * rhs`, panicking if
+        /// overflow occurred.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.strict_mul(1), ", stringify!($SelfT), "::MAX);")]
+        /// ```
+        ///
+        /// ``` should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = ", stringify!($SelfT), "::MAX.strict_mul(2);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_mul(self, rhs: Self) -> Self {
+            let (a, b) = self.overflowing_mul(rhs);
+            if unlikely!(b) { overflow_panic::mul() } else { a }
         }
 
         /// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow
@@ -642,6 +807,50 @@ macro_rules! int_impl {
             }
         }
 
+        /// Strict integer division. Computes `self / rhs`, panicking
+        /// if overflow occurred.
+        ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is zero.
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// The only case where such an overflow can occur is when one divides `MIN / -1` on a signed type (where
+        /// `MIN` is the negative minimal value for the type); this is equivalent to `-MIN`, a positive value
+        /// that is too large to represent in the type.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).strict_div(-1), ", stringify!($Max), ");")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = ", stringify!($SelfT), "::MIN.strict_div(-1);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = (1", stringify!($SelfT), ").strict_div(0);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_div(self, rhs: Self) -> Self {
+            let (a, b) = self.overflowing_div(rhs);
+            if unlikely!(b) { overflow_panic::div() } else { a }
+        }
+
         /// Checked Euclidean division. Computes `self.div_euclid(rhs)`,
         /// returning `None` if `rhs == 0` or the division results in overflow.
         ///
@@ -668,6 +877,50 @@ macro_rules! int_impl {
             }
         }
 
+        /// Strict Euclidean division. Computes `self.div_euclid(rhs)`, panicking
+        /// if overflow occurred.
+        ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is zero.
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// The only case where such an overflow can occur is when one divides `MIN / -1` on a signed type (where
+        /// `MIN` is the negative minimal value for the type); this is equivalent to `-MIN`, a positive value
+        /// that is too large to represent in the type.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MIN + 1).strict_div_euclid(-1), ", stringify!($Max), ");")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = ", stringify!($SelfT), "::MIN.strict_div_euclid(-1);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = (1", stringify!($SelfT), ").strict_div_euclid(0);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_div_euclid(self, rhs: Self) -> Self {
+            let (a, b) = self.overflowing_div_euclid(rhs);
+            if unlikely!(b) { overflow_panic::div() } else { a }
+        }
+
         /// Checked integer remainder. Computes `self % rhs`, returning `None` if
         /// `rhs == 0` or the division results in overflow.
         ///
@@ -694,6 +947,49 @@ macro_rules! int_impl {
             }
         }
 
+        /// Strict integer remainder. Computes `self % rhs`, panicking if
+        /// the division results in overflow.
+        ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is zero.
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// The only case where such an overflow can occur is `x % y` for `MIN / -1` on a
+        /// signed type (where `MIN` is the negative minimal value), which is invalid due to implementation artifacts.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".strict_rem(2), 1);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = 5", stringify!($SelfT), ".strict_rem(0);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = ", stringify!($SelfT), "::MIN.strict_rem(-1);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_rem(self, rhs: Self) -> Self {
+            let (a, b) = self.overflowing_rem(rhs);
+            if unlikely!(b) { overflow_panic::rem() } else { a }
+        }
+
         /// Checked Euclidean remainder. Computes `self.rem_euclid(rhs)`, returning `None`
         /// if `rhs == 0` or the division results in overflow.
         ///
@@ -720,6 +1016,49 @@ macro_rules! int_impl {
             }
         }
 
+        /// Strict Euclidean remainder. Computes `self.rem_euclid(rhs)`, panicking if
+        /// the division results in overflow.
+        ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is zero.
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// The only case where such an overflow can occur is `x % y` for `MIN / -1` on a
+        /// signed type (where `MIN` is the negative minimal value), which is invalid due to implementation artifacts.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".strict_rem_euclid(2), 1);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = 5", stringify!($SelfT), ".strict_rem_euclid(0);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = ", stringify!($SelfT), "::MIN.strict_rem_euclid(-1);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
+            let (a, b) = self.overflowing_rem_euclid(rhs);
+            if unlikely!(b) { overflow_panic::rem() } else { a }
+        }
+
         /// Checked negation. Computes `-self`, returning `None` if `self == MIN`.
         ///
         /// # Examples
@@ -737,7 +1076,7 @@ macro_rules! int_impl {
         #[inline]
         pub const fn checked_neg(self) -> Option<Self> {
             let (a, b) = self.overflowing_neg();
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
         }
 
         /// Unchecked negation. Computes `-self`, assuming overflow cannot occur.
@@ -765,6 +1104,38 @@ macro_rules! int_impl {
             unsafe { intrinsics::unchecked_sub(0, self) }
         }
 
+        /// Strict negation. Computes `-self`, panicking if `self == MIN`.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".strict_neg(), -5);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = ", stringify!($SelfT), "::MIN.strict_neg();")]
+        ///
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_neg(self) -> Self {
+            let (a, b) = self.overflowing_neg();
+            if unlikely!(b) { overflow_panic::neg() } else { a }
+        }
+
         /// Checked shift left. Computes `self << rhs`, returning `None` if `rhs` is larger
         /// than or equal to the number of bits in `self`.
         ///
@@ -783,7 +1154,40 @@ macro_rules! int_impl {
         #[inline]
         pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
             let (a, b) = self.overflowing_shl(rhs);
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
+        }
+
+        /// Strict shift left. Computes `self << rhs`, panicking if `rhs` is larger
+        /// than or equal to the number of bits in `self`.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".strict_shl(4), 0x10);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = 0x1", stringify!($SelfT), ".strict_shl(129);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_shl(self, rhs: u32) -> Self {
+            let (a, b) = self.overflowing_shl(rhs);
+            if unlikely!(b) { overflow_panic::shl() } else { a }
         }
 
         /// Unchecked shift left. Computes `self << rhs`, assuming that
@@ -831,7 +1235,40 @@ macro_rules! int_impl {
         #[inline]
         pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
             let (a, b) = self.overflowing_shr(rhs);
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
+        }
+
+        /// Strict shift right. Computes `self >> rhs`, panicking `rhs` is
+        /// larger than or equal to the number of bits in `self`.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".strict_shr(4), 0x1);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = 0x10", stringify!($SelfT), ".strict_shr(128);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_shr(self, rhs: u32) -> Self {
+            let (a, b) = self.overflowing_shr(rhs);
+            if unlikely!(b) { overflow_panic::shr() } else { a }
         }
 
         /// Unchecked shift right. Computes `self >> rhs`, assuming that
@@ -885,6 +1322,42 @@ macro_rules! int_impl {
             }
         }
 
+        /// Strict absolute value. Computes `self.abs()`, panicking if
+        /// `self == MIN`.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!((-5", stringify!($SelfT), ").strict_abs(), 5);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = ", stringify!($SelfT), "::MIN.strict_abs();")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_abs(self) -> Self {
+            if self.is_negative() {
+                self.strict_neg()
+            } else {
+                self
+            }
+        }
+
         /// Checked exponentiation. Computes `self.pow(exp)`, returning `None` if
         /// overflow occurred.
         ///
@@ -923,6 +1396,55 @@ macro_rules! int_impl {
             acc.checked_mul(base)
         }
 
+        /// Strict exponentiation. Computes `self.pow(exp)`, panicking if
+        /// overflow occurred.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(8", stringify!($SelfT), ".strict_pow(2), 64);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = ", stringify!($SelfT), "::MAX.strict_pow(2);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_pow(self, mut exp: u32) -> Self {
+            if exp == 0 {
+                return 1;
+            }
+            let mut base = self;
+            let mut acc: Self = 1;
+
+            while exp > 1 {
+                if (exp & 1) == 1 {
+                    acc = acc.strict_mul(base);
+                }
+                exp /= 2;
+                base = base.strict_mul(base);
+            }
+            // since exp!=0, finally the exp must be 1.
+            // Deal with the final bit of the exponent separately, since
+            // squaring the base afterwards is not necessary and may cause a
+            // needless overflow.
+            acc.strict_mul(base)
+        }
+
         /// Returns the square root of the number, rounded down.
         ///
         /// Returns `None` if `self` is negative.
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 695e87aaabf..4d85addadf5 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -44,6 +44,7 @@ mod uint_macros; // import uint_impl!
 mod error;
 mod int_log10;
 mod nonzero;
+mod overflow_panic;
 mod saturating;
 mod wrapping;
 
@@ -59,6 +60,8 @@ pub use dec2flt::ParseFloatError;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use error::ParseIntError;
 
+pub(crate) use nonzero::NonZero;
+
 #[stable(feature = "nonzero", since = "1.28.0")]
 pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
 
@@ -482,7 +485,7 @@ impl u8 {
         Self = u8,
         ActualT = u8,
         SignedT = i8,
-        NonZeroT = NonZeroU8,
+        NonZeroT = NonZero<u8>,
         BITS = 8,
         MAX = 255,
         rot = 2,
@@ -1097,7 +1100,7 @@ impl u16 {
         Self = u16,
         ActualT = u16,
         SignedT = i16,
-        NonZeroT = NonZeroU16,
+        NonZeroT = NonZero<u16>,
         BITS = 16,
         MAX = 65535,
         rot = 4,
@@ -1146,7 +1149,7 @@ impl u32 {
         Self = u32,
         ActualT = u32,
         SignedT = i32,
-        NonZeroT = NonZeroU32,
+        NonZeroT = NonZero<u32>,
         BITS = 32,
         MAX = 4294967295,
         rot = 8,
@@ -1170,7 +1173,7 @@ impl u64 {
         Self = u64,
         ActualT = u64,
         SignedT = i64,
-        NonZeroT = NonZeroU64,
+        NonZeroT = NonZero<u64>,
         BITS = 64,
         MAX = 18446744073709551615,
         rot = 12,
@@ -1194,7 +1197,7 @@ impl u128 {
         Self = u128,
         ActualT = u128,
         SignedT = i128,
-        NonZeroT = NonZeroU128,
+        NonZeroT = NonZero<u128>,
         BITS = 128,
         MAX = 340282366920938463463374607431768211455,
         rot = 16,
@@ -1220,7 +1223,7 @@ impl usize {
         Self = usize,
         ActualT = u16,
         SignedT = isize,
-        NonZeroT = NonZeroUsize,
+        NonZeroT = NonZero<usize>,
         BITS = 16,
         MAX = 65535,
         rot = 4,
@@ -1245,7 +1248,7 @@ impl usize {
         Self = usize,
         ActualT = u32,
         SignedT = isize,
-        NonZeroT = NonZeroUsize,
+        NonZeroT = NonZero<usize>,
         BITS = 32,
         MAX = 4294967295,
         rot = 8,
@@ -1270,7 +1273,7 @@ impl usize {
         Self = usize,
         ActualT = u64,
         SignedT = isize,
-        NonZeroT = NonZeroUsize,
+        NonZeroT = NonZero<usize>,
         BITS = 64,
         MAX = 18446744073709551615,
         rot = 12,
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 2df38ab5848..bda691b16d4 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -8,6 +8,69 @@ use super::from_str_radix;
 use super::{IntErrorKind, ParseIntError};
 use crate::intrinsics;
 
+mod private {
+    #[unstable(
+        feature = "nonzero_internals",
+        reason = "implementation detail which may disappear or be replaced at any time",
+        issue = "none"
+    )]
+    #[const_trait]
+    pub trait Sealed {}
+}
+
+/// A marker trait for primitive types which can be zero.
+///
+/// This is an implementation detail for [`NonZero<T>`](NonZero) which may disappear or be replaced at any time.
+#[unstable(
+    feature = "nonzero_internals",
+    reason = "implementation detail which may disappear or be replaced at any time",
+    issue = "none"
+)]
+#[const_trait]
+pub trait ZeroablePrimitive: Sized + Copy + private::Sealed {
+    type NonZero;
+}
+
+#[unstable(
+    feature = "nonzero_internals",
+    reason = "implementation detail which may disappear or be replaced at any time",
+    issue = "none"
+)]
+pub(crate) type NonZero<T> = <T as ZeroablePrimitive>::NonZero;
+
+macro_rules! impl_zeroable_primitive {
+    ($NonZero:ident ( $primitive:ty )) => {
+        #[unstable(
+            feature = "nonzero_internals",
+            reason = "implementation detail which may disappear or be replaced at any time",
+            issue = "none"
+        )]
+        impl const private::Sealed for $primitive {}
+
+        #[unstable(
+            feature = "nonzero_internals",
+            reason = "implementation detail which may disappear or be replaced at any time",
+            issue = "none"
+        )]
+        impl const ZeroablePrimitive for $primitive {
+            type NonZero = $NonZero;
+        }
+    };
+}
+
+impl_zeroable_primitive!(NonZeroU8(u8));
+impl_zeroable_primitive!(NonZeroU16(u16));
+impl_zeroable_primitive!(NonZeroU32(u32));
+impl_zeroable_primitive!(NonZeroU64(u64));
+impl_zeroable_primitive!(NonZeroU128(u128));
+impl_zeroable_primitive!(NonZeroUsize(usize));
+impl_zeroable_primitive!(NonZeroI8(i8));
+impl_zeroable_primitive!(NonZeroI16(i16));
+impl_zeroable_primitive!(NonZeroI32(i32));
+impl_zeroable_primitive!(NonZeroI64(i64));
+impl_zeroable_primitive!(NonZeroI128(i128));
+impl_zeroable_primitive!(NonZeroIsize(isize));
+
 macro_rules! impl_nonzero_fmt {
     ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
         $(
@@ -22,193 +85,483 @@ macro_rules! impl_nonzero_fmt {
     }
 }
 
-macro_rules! nonzero_integers {
-    ( $( #[$stability: meta] #[$const_new_unchecked_stability: meta] $Ty: ident($Int: ty); )+ ) => {
-        $(
-            /// An integer that is known not to equal zero.
+macro_rules! nonzero_integer {
+    (
+        #[$stability:meta]
+        #[$const_new_unchecked_stability:meta]
+        Self = $Ty:ident,
+        Primitive = $signedness:ident $Int:ident,
+        $(UnsignedNonZero = $UnsignedNonZero:ident,)?
+        UnsignedPrimitive = $UnsignedPrimitive:ty,
+
+        // Used in doc comments.
+        leading_zeros_test = $leading_zeros_test:expr,
+    ) => {
+        /// An integer that is known not to equal zero.
+        ///
+        /// This enables some memory layout optimization.
+        #[doc = concat!("For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:")]
+        ///
+        /// ```rust
+        /// use std::mem::size_of;
+        #[doc = concat!("assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int), ">());")]
+        /// ```
+        ///
+        /// # Layout
+        ///
+        #[doc = concat!("`", stringify!($Ty), "` is guaranteed to have the same layout and bit validity as `", stringify!($Int), "`")]
+        /// with the exception that `0` is not a valid instance.
+        #[doc = concat!("`Option<", stringify!($Ty), ">` is guaranteed to be compatible with `", stringify!($Int), "`,")]
+        /// including in FFI.
+        ///
+        /// Thanks to the [null pointer optimization],
+        #[doc = concat!("`", stringify!($Ty), "` and `Option<", stringify!($Ty), ">`")]
+        /// are guaranteed to have the same size and alignment:
+        ///
+        /// ```
+        /// # use std::mem::{size_of, align_of};
+        #[doc = concat!("use std::num::", stringify!($Ty), ";")]
+        ///
+        #[doc = concat!("assert_eq!(size_of::<", stringify!($Ty), ">(), size_of::<Option<", stringify!($Ty), ">>());")]
+        #[doc = concat!("assert_eq!(align_of::<", stringify!($Ty), ">(), align_of::<Option<", stringify!($Ty), ">>());")]
+        /// ```
+        ///
+        /// [null pointer optimization]: crate::option#representation
+        #[$stability]
+        #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+        #[repr(transparent)]
+        #[rustc_layout_scalar_valid_range_start(1)]
+        #[rustc_nonnull_optimization_guaranteed]
+        #[rustc_diagnostic_item = stringify!($Ty)]
+        pub struct $Ty($Int);
+
+        impl $Ty {
+            /// Creates a non-zero without checking whether the value is non-zero.
+            /// This results in undefined behaviour if the value is zero.
+            ///
+            /// # Safety
+            ///
+            /// The value must not be zero.
+            #[$stability]
+            #[$const_new_unchecked_stability]
+            #[must_use]
+            #[inline]
+            pub const unsafe fn new_unchecked(n: $Int) -> Self {
+                crate::panic::debug_assert_nounwind!(
+                    n != 0,
+                    concat!(stringify!($Ty), "::new_unchecked requires a non-zero argument")
+                );
+                // SAFETY: this is guaranteed to be safe by the caller.
+                unsafe {
+                    Self(n)
+                }
+            }
+
+            /// Creates a non-zero if the given value is not zero.
+            #[$stability]
+            #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
+            #[must_use]
+            #[inline]
+            pub const fn new(n: $Int) -> Option<Self> {
+                if n != 0 {
+                    // SAFETY: we just checked that there's no `0`
+                    Some(unsafe { Self(n) })
+                } else {
+                    None
+                }
+            }
+
+            /// Converts a primitive mutable reference to a non-zero mutable reference
+            /// without checking whether the referenced value is non-zero.
+            /// This results in undefined behavior if `*n` is zero.
+            ///
+            /// # Safety
+            /// The referenced value must not be currently zero.
+            #[unstable(feature = "nonzero_from_mut", issue = "106290")]
+            #[must_use]
+            #[inline]
+            pub unsafe fn from_mut_unchecked(n: &mut $Int) -> &mut Self {
+                // SAFETY: Self is repr(transparent), and the value is assumed to be non-zero.
+                unsafe {
+                    let n_alias = &mut *n;
+                    core::intrinsics::assert_unsafe_precondition!(
+                        concat!(stringify!($Ty), "::from_mut_unchecked requires the argument to dereference as non-zero"),
+                        (n_alias: &mut $Int) => *n_alias != 0
+                    );
+                    &mut *(n as *mut $Int as *mut Self)
+                }
+            }
+
+            /// Converts a primitive mutable reference to a non-zero mutable reference
+            /// if the referenced integer is not zero.
+            #[unstable(feature = "nonzero_from_mut", issue = "106290")]
+            #[must_use]
+            #[inline]
+            pub fn from_mut(n: &mut $Int) -> Option<&mut Self> {
+                // SAFETY: Self is repr(transparent), and the value is non-zero.
+                // As long as the returned reference is alive,
+                // the user cannot `*n = 0` directly.
+                (*n != 0).then(|| unsafe { &mut *(n as *mut $Int as *mut Self) })
+            }
+
+            /// Returns the value as a primitive type.
+            #[$stability]
+            #[inline]
+            #[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")]
+            pub const fn get(self) -> $Int {
+                // FIXME: Remove this after LLVM supports `!range` metadata for function
+                // arguments https://github.com/llvm/llvm-project/issues/76628
+                //
+                // Rustc can set range metadata only if it loads `self` from
+                // memory somewhere. If the value of `self` was from by-value argument
+                // of some not-inlined function, LLVM don't have range metadata
+                // to understand that the value cannot be zero.
+
+                // SAFETY: It is an invariant of this type.
+                unsafe {
+                    intrinsics::assume(self.0 != 0);
+                }
+                self.0
+            }
+
+            /// The size of this non-zero integer type in bits.
             ///
-            /// This enables some memory layout optimization.
-            #[doc = concat!("For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:")]
+            #[doc = concat!("This value is equal to [`", stringify!($Int), "::BITS`].")]
             ///
-            /// ```rust
-            /// use std::mem::size_of;
-            #[doc = concat!("assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int), ">());")]
+            /// # Examples
+            ///
+            /// ```
+            #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+            ///
+            #[doc = concat!("assert_eq!(", stringify!($Ty), "::BITS, ", stringify!($Int), "::BITS);")]
             /// ```
+            #[stable(feature = "nonzero_bits", since = "1.67.0")]
+            pub const BITS: u32 = <$Int>::BITS;
+
+            /// Returns the number of leading zeros in the binary representation of `self`.
             ///
-            /// # Layout
+            /// On many architectures, this function can perform better than `leading_zeros()` on the underlying integer type, as special handling of zero can be avoided.
             ///
-            #[doc = concat!("`", stringify!($Ty), "` is guaranteed to have the same layout and bit validity as `", stringify!($Int), "`")]
-            /// with the exception that `0` is not a valid instance.
-            #[doc = concat!("`Option<", stringify!($Ty), ">` is guaranteed to be compatible with `", stringify!($Int), "`,")]
-            /// including in FFI.
+            /// # Examples
             ///
-            /// Thanks to the [null pointer optimization],
-            #[doc = concat!("`", stringify!($Ty), "` and `Option<", stringify!($Ty), ">`")]
-            /// are guaranteed to have the same size and alignment:
+            /// Basic usage:
             ///
             /// ```
-            /// # use std::mem::{size_of, align_of};
-            #[doc = concat!("use std::num::", stringify!($Ty), ";")]
+            #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(", $leading_zeros_test, ").unwrap();")]
             ///
-            #[doc = concat!("assert_eq!(size_of::<", stringify!($Ty), ">(), size_of::<Option<", stringify!($Ty), ">>());")]
-            #[doc = concat!("assert_eq!(align_of::<", stringify!($Ty), ">(), align_of::<Option<", stringify!($Ty), ">>());")]
+            /// assert_eq!(n.leading_zeros(), 0);
             /// ```
+            #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
+            #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
+            #[inline]
+            pub const fn leading_zeros(self) -> u32 {
+                // SAFETY: since `self` cannot be zero, it is safe to call `ctlz_nonzero`.
+                unsafe { intrinsics::ctlz_nonzero(self.get() as $UnsignedPrimitive) as u32 }
+            }
+
+            /// Returns the number of trailing zeros in the binary representation
+            /// of `self`.
             ///
-            /// [null pointer optimization]: crate::option#representation
-            #[$stability]
-            #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
-            #[repr(transparent)]
-            #[rustc_layout_scalar_valid_range_start(1)]
-            #[rustc_nonnull_optimization_guaranteed]
-            #[rustc_diagnostic_item = stringify!($Ty)]
-            pub struct $Ty($Int);
-
-            impl $Ty {
-                /// Creates a non-zero without checking whether the value is non-zero.
-                /// This results in undefined behaviour if the value is zero.
-                ///
-                /// # Safety
-                ///
-                /// The value must not be zero.
-                #[$stability]
-                #[$const_new_unchecked_stability]
-                #[must_use]
-                #[inline]
-                pub const unsafe fn new_unchecked(n: $Int) -> Self {
-                    crate::panic::debug_assert_nounwind!(
-                        n != 0,
-                        concat!(stringify!($Ty), "::new_unchecked requires a non-zero argument")
-                    );
-                    // SAFETY: this is guaranteed to be safe by the caller.
-                    unsafe {
-                        Self(n)
-                    }
-                }
+            /// On many architectures, this function can perform better than `trailing_zeros()` on the underlying integer type, as special handling of zero can be avoided.
+            ///
+            /// # Examples
+            ///
+            /// Basic usage:
+            ///
+            /// ```
+            #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(0b0101000).unwrap();")]
+            ///
+            /// assert_eq!(n.trailing_zeros(), 3);
+            /// ```
+            #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
+            #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
+            #[inline]
+            pub const fn trailing_zeros(self) -> u32 {
+                // SAFETY: since `self` cannot be zero, it is safe to call `cttz_nonzero`.
+                unsafe { intrinsics::cttz_nonzero(self.get() as $UnsignedPrimitive) as u32 }
+            }
 
-                /// Creates a non-zero if the given value is not zero.
-                #[$stability]
-                #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
-                #[must_use]
-                #[inline]
-                pub const fn new(n: $Int) -> Option<Self> {
-                    if n != 0 {
-                        // SAFETY: we just checked that there's no `0`
-                        Some(unsafe { Self(n) })
-                    } else {
-                        None
-                    }
-                }
+            nonzero_integer_signedness_dependent_methods! {
+                Self = $Ty,
+                Primitive = $signedness $Int,
+                $(UnsignedNonZero = $UnsignedNonZero,)?
+                UnsignedPrimitive = $UnsignedPrimitive,
+            }
 
-                /// Returns the value as a primitive type.
-                #[$stability]
-                #[inline]
-                #[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")]
-                pub const fn get(self) -> $Int {
-                    // FIXME: Remove this after LLVM supports `!range` metadata for function
-                    // arguments https://github.com/llvm/llvm-project/issues/76628
+            /// Multiplies two non-zero integers together.
+            /// Checks for overflow and returns [`None`] on overflow.
+            /// As a consequence, the result cannot wrap to zero.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+            /// # fn main() { test().unwrap(); }
+            /// # fn test() -> Option<()> {
+            #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+            #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
+            #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                            stringify!($Int), "::MAX)?;")]
+            ///
+            /// assert_eq!(Some(four), two.checked_mul(two));
+            /// assert_eq!(None, max.checked_mul(two));
+            /// # Some(())
+            /// # }
+            /// ```
+            #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+            #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
+            #[inline]
+            pub const fn checked_mul(self, other: $Ty) -> Option<$Ty> {
+                if let Some(result) = self.get().checked_mul(other.get()) {
+                    // SAFETY:
+                    // - `checked_mul` returns `None` on overflow
+                    // - `self` and `other` are non-zero
+                    // - the only way to get zero from a multiplication without overflow is for one
+                    //   of the sides to be zero
                     //
-                    // Rustc can set range metadata only if it loads `self` from
-                    // memory somewhere. If the value of `self` was from by-value argument
-                    // of some not-inlined function, LLVM don't have range metadata
-                    // to understand that the value cannot be zero.
-
-                    // SAFETY: It is an invariant of this type.
-                    unsafe {
-                        intrinsics::assume(self.0 != 0);
-                    }
-                    self.0
+                    // So the result cannot be zero.
+                    Some(unsafe { $Ty::new_unchecked(result) })
+                } else {
+                    None
                 }
+            }
 
+            /// Multiplies two non-zero integers together.
+            #[doc = concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.")]
+            ///
+            /// # Examples
+            ///
+            /// ```
+            #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+            /// # fn main() { test().unwrap(); }
+            /// # fn test() -> Option<()> {
+            #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+            #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
+            #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                            stringify!($Int), "::MAX)?;")]
+            ///
+            /// assert_eq!(four, two.saturating_mul(two));
+            /// assert_eq!(max, four.saturating_mul(max));
+            /// # Some(())
+            /// # }
+            /// ```
+            #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+            #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
+            #[inline]
+            pub const fn saturating_mul(self, other: $Ty) -> $Ty {
+                // SAFETY:
+                // - `saturating_mul` returns `u*::MAX`/`i*::MAX`/`i*::MIN` on overflow/underflow,
+                //   all of which are non-zero
+                // - `self` and `other` are non-zero
+                // - the only way to get zero from a multiplication without overflow is for one
+                //   of the sides to be zero
+                //
+                // So the result cannot be zero.
+                unsafe { $Ty::new_unchecked(self.get().saturating_mul(other.get())) }
             }
 
-            #[stable(feature = "from_nonzero", since = "1.31.0")]
-            impl From<$Ty> for $Int {
-                #[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")]
-                #[inline]
-                fn from(nonzero: $Ty) -> Self {
-                    // Call nonzero to keep information range information
-                    // from get method.
-                    nonzero.get()
+            /// Multiplies two non-zero integers together,
+            /// assuming overflow cannot occur.
+            /// Overflow is unchecked, and it is undefined behaviour to overflow
+            /// *even if the result would wrap to a non-zero value*.
+            /// The behaviour is undefined as soon as
+            #[doc = sign_dependent_expr!{
+                $signedness ?
+                if signed {
+                    concat!("`self * rhs > ", stringify!($Int), "::MAX`, ",
+                            "or `self * rhs < ", stringify!($Int), "::MIN`.")
+                }
+                if unsigned {
+                    concat!("`self * rhs > ", stringify!($Int), "::MAX`.")
                 }
+            }]
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// #![feature(nonzero_ops)]
+            ///
+            #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+            /// # fn main() { test().unwrap(); }
+            /// # fn test() -> Option<()> {
+            #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+            #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
+            ///
+            /// assert_eq!(four, unsafe { two.unchecked_mul(two) });
+            /// # Some(())
+            /// # }
+            /// ```
+            #[unstable(feature = "nonzero_ops", issue = "84186")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
+            #[inline]
+            pub const unsafe fn unchecked_mul(self, other: $Ty) -> $Ty {
+                // SAFETY: The caller ensures there is no overflow.
+                unsafe { $Ty::new_unchecked(self.get().unchecked_mul(other.get())) }
             }
 
-            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
-            impl BitOr for $Ty {
-                type Output = Self;
-                #[inline]
-                fn bitor(self, rhs: Self) -> Self::Output {
-                    // SAFETY: since `self` and `rhs` are both nonzero, the
-                    // result of the bitwise-or will be nonzero.
-                    unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
+            /// Raises non-zero value to an integer power.
+            /// Checks for overflow and returns [`None`] on overflow.
+            /// As a consequence, the result cannot wrap to zero.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+            /// # fn main() { test().unwrap(); }
+            /// # fn test() -> Option<()> {
+            #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
+            #[doc = concat!("let twenty_seven = ", stringify!($Ty), "::new(27)?;")]
+            #[doc = concat!("let half_max = ", stringify!($Ty), "::new(",
+                            stringify!($Int), "::MAX / 2)?;")]
+            ///
+            /// assert_eq!(Some(twenty_seven), three.checked_pow(3));
+            /// assert_eq!(None, half_max.checked_pow(3));
+            /// # Some(())
+            /// # }
+            /// ```
+            #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+            #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
+            #[inline]
+            pub const fn checked_pow(self, other: u32) -> Option<$Ty> {
+                if let Some(result) = self.get().checked_pow(other) {
+                    // SAFETY:
+                    // - `checked_pow` returns `None` on overflow/underflow
+                    // - `self` is non-zero
+                    // - the only way to get zero from an exponentiation without overflow is
+                    //   for base to be zero
+                    //
+                    // So the result cannot be zero.
+                    Some(unsafe { $Ty::new_unchecked(result) })
+                } else {
+                    None
                 }
             }
 
-            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
-            impl BitOr<$Int> for $Ty {
-                type Output = Self;
-                #[inline]
-                fn bitor(self, rhs: $Int) -> Self::Output {
-                    // SAFETY: since `self` is nonzero, the result of the
-                    // bitwise-or will be nonzero regardless of the value of
-                    // `rhs`.
-                    unsafe { $Ty::new_unchecked(self.get() | rhs) }
+            /// Raise non-zero value to an integer power.
+            #[doc = sign_dependent_expr!{
+                $signedness ?
+                if signed {
+                    concat!("Return [`", stringify!($Ty), "::MIN`] ",
+                                "or [`", stringify!($Ty), "::MAX`] on overflow.")
+                }
+                if unsigned {
+                    concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.")
                 }
+            }]
+            ///
+            /// # Examples
+            ///
+            /// ```
+            #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+            /// # fn main() { test().unwrap(); }
+            /// # fn test() -> Option<()> {
+            #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
+            #[doc = concat!("let twenty_seven = ", stringify!($Ty), "::new(27)?;")]
+            #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                            stringify!($Int), "::MAX)?;")]
+            ///
+            /// assert_eq!(twenty_seven, three.saturating_pow(3));
+            /// assert_eq!(max, max.saturating_pow(3));
+            /// # Some(())
+            /// # }
+            /// ```
+            #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+            #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
+            #[must_use = "this returns the result of the operation, \
+                          without modifying the original"]
+            #[inline]
+            pub const fn saturating_pow(self, other: u32) -> $Ty {
+                // SAFETY:
+                // - `saturating_pow` returns `u*::MAX`/`i*::MAX`/`i*::MIN` on overflow/underflow,
+                //   all of which are non-zero
+                // - `self` is non-zero
+                // - the only way to get zero from an exponentiation without overflow is
+                //   for base to be zero
+                //
+                // So the result cannot be zero.
+                unsafe { $Ty::new_unchecked(self.get().saturating_pow(other)) }
             }
+        }
 
-            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
-            impl BitOr<$Ty> for $Int {
-                type Output = $Ty;
-                #[inline]
-                fn bitor(self, rhs: $Ty) -> Self::Output {
-                    // SAFETY: since `rhs` is nonzero, the result of the
-                    // bitwise-or will be nonzero regardless of the value of
-                    // `self`.
-                    unsafe { $Ty::new_unchecked(self | rhs.get()) }
-                }
+        #[stable(feature = "from_nonzero", since = "1.31.0")]
+        impl From<$Ty> for $Int {
+            #[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")]
+            #[inline]
+            fn from(nonzero: $Ty) -> Self {
+                // Call nonzero to keep information range information
+                // from get method.
+                nonzero.get()
             }
+        }
 
-            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
-            impl BitOrAssign for $Ty {
-                #[inline]
-                fn bitor_assign(&mut self, rhs: Self) {
-                    *self = *self | rhs;
-                }
+        #[stable(feature = "nonzero_bitor", since = "1.45.0")]
+        impl BitOr for $Ty {
+            type Output = Self;
+            #[inline]
+            fn bitor(self, rhs: Self) -> Self::Output {
+                // SAFETY: since `self` and `rhs` are both nonzero, the
+                // result of the bitwise-or will be nonzero.
+                unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
             }
+        }
 
-            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
-            impl BitOrAssign<$Int> for $Ty {
-                #[inline]
-                fn bitor_assign(&mut self, rhs: $Int) {
-                    *self = *self | rhs;
-                }
+        #[stable(feature = "nonzero_bitor", since = "1.45.0")]
+        impl BitOr<$Int> for $Ty {
+            type Output = Self;
+            #[inline]
+            fn bitor(self, rhs: $Int) -> Self::Output {
+                // SAFETY: since `self` is nonzero, the result of the
+                // bitwise-or will be nonzero regardless of the value of
+                // `rhs`.
+                unsafe { $Ty::new_unchecked(self.get() | rhs) }
+            }
+        }
+
+        #[stable(feature = "nonzero_bitor", since = "1.45.0")]
+        impl BitOr<$Ty> for $Int {
+            type Output = $Ty;
+            #[inline]
+            fn bitor(self, rhs: $Ty) -> Self::Output {
+                // SAFETY: since `rhs` is nonzero, the result of the
+                // bitwise-or will be nonzero regardless of the value of
+                // `self`.
+                unsafe { $Ty::new_unchecked(self | rhs.get()) }
             }
+        }
 
-            impl_nonzero_fmt! {
-                #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
+        #[stable(feature = "nonzero_bitor", since = "1.45.0")]
+        impl BitOrAssign for $Ty {
+            #[inline]
+            fn bitor_assign(&mut self, rhs: Self) {
+                *self = *self | rhs;
             }
-        )+
-    }
-}
+        }
 
-nonzero_integers! {
-    #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
-    #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
-    #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
-    #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
-    #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
-    #[stable(feature = "nonzero", since = "1.28.0")] #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
-    #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
-    #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
-    #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
-    #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
-    #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
-    #[stable(feature = "signed_nonzero", since = "1.34.0")] #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
-}
+        #[stable(feature = "nonzero_bitor", since = "1.45.0")]
+        impl BitOrAssign<$Int> for $Ty {
+            #[inline]
+            fn bitor_assign(&mut self, rhs: $Int) {
+                *self = *self | rhs;
+            }
+        }
+
+        impl_nonzero_fmt! {
+            #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
+        }
 
-macro_rules! from_str_radix_nzint_impl {
-    ($($t:ty)*) => {$(
         #[stable(feature = "nonzero_parse", since = "1.35.0")]
-        impl FromStr for $t {
+        impl FromStr for $Ty {
             type Err = ParseIntError;
             fn from_str(src: &str) -> Result<Self, Self::Err> {
                 Self::new(from_str_radix(src, 10)?)
@@ -217,989 +570,791 @@ macro_rules! from_str_radix_nzint_impl {
                     })
             }
         }
-    )*}
-}
-
-from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
-NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
-
-macro_rules! nonzero_leading_trailing_zeros {
-    ( $( $Ty: ident($Uint: ty) , $LeadingTestExpr:expr ;)+ ) => {
-        $(
-            impl $Ty {
-                /// Returns the number of leading zeros in the binary representation of `self`.
-                ///
-                /// On many architectures, this function can perform better than `leading_zeros()` on the underlying integer type, as special handling of zero can be avoided.
-                ///
-                /// # Examples
-                ///
-                /// Basic usage:
-                ///
-                /// ```
-                #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(", stringify!($LeadingTestExpr), ").unwrap();")]
-                ///
-                /// assert_eq!(n.leading_zeros(), 0);
-                /// ```
-                #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
-                #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn leading_zeros(self) -> u32 {
-                    // SAFETY: since `self` cannot be zero, it is safe to call `ctlz_nonzero`.
-                    unsafe { intrinsics::ctlz_nonzero(self.get() as $Uint) as u32 }
-                }
 
-                /// Returns the number of trailing zeros in the binary representation
-                /// of `self`.
-                ///
-                /// On many architectures, this function can perform better than `trailing_zeros()` on the underlying integer type, as special handling of zero can be avoided.
-                ///
-                /// # Examples
-                ///
-                /// Basic usage:
-                ///
-                /// ```
-                #[doc = concat!("let n = std::num::", stringify!($Ty), "::new(0b0101000).unwrap();")]
-                ///
-                /// assert_eq!(n.trailing_zeros(), 3);
-                /// ```
-                #[stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
-                #[rustc_const_stable(feature = "nonzero_leading_trailing_zeros", since = "1.53.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn trailing_zeros(self) -> u32 {
-                    // SAFETY: since `self` cannot be zero, it is safe to call `cttz_nonzero`.
-                    unsafe { intrinsics::cttz_nonzero(self.get() as $Uint) as u32 }
-                }
+        nonzero_integer_signedness_dependent_impls!($Ty $signedness $Int);
+    };
 
-            }
-        )+
-    }
-}
+    (Self = $Ty:ident, Primitive = unsigned $Int:ident $(,)?) => {
+        nonzero_integer! {
+            #[stable(feature = "nonzero", since = "1.28.0")]
+            #[rustc_const_stable(feature = "nonzero", since = "1.28.0")]
+            Self = $Ty,
+            Primitive = unsigned $Int,
+            UnsignedPrimitive = $Int,
+            leading_zeros_test = concat!(stringify!($Int), "::MAX"),
+        }
+    };
 
-nonzero_leading_trailing_zeros! {
-    NonZeroU8(u8), u8::MAX;
-    NonZeroU16(u16), u16::MAX;
-    NonZeroU32(u32), u32::MAX;
-    NonZeroU64(u64), u64::MAX;
-    NonZeroU128(u128), u128::MAX;
-    NonZeroUsize(usize), usize::MAX;
-    NonZeroI8(u8), -1i8;
-    NonZeroI16(u16), -1i16;
-    NonZeroI32(u32), -1i32;
-    NonZeroI64(u64), -1i64;
-    NonZeroI128(u128), -1i128;
-    NonZeroIsize(usize), -1isize;
+    (Self = $Ty:ident, Primitive = signed $Int:ident, $($rest:tt)*) => {
+        nonzero_integer! {
+            #[stable(feature = "signed_nonzero", since = "1.34.0")]
+            #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")]
+            Self = $Ty,
+            Primitive = signed $Int,
+            $($rest)*
+            leading_zeros_test = concat!("-1", stringify!($Int)),
+        }
+    };
 }
 
-macro_rules! nonzero_integers_div {
-    ( $( $Ty: ident($Int: ty); )+ ) => {
-        $(
-            #[stable(feature = "nonzero_div", since = "1.51.0")]
-            impl Div<$Ty> for $Int {
-                type Output = $Int;
-                /// This operation rounds towards zero,
-                /// truncating any fractional part of the exact result, and cannot panic.
-                #[inline]
-                fn div(self, other: $Ty) -> $Int {
-                    // SAFETY: div by zero is checked because `other` is a nonzero,
-                    // and MIN/-1 is checked because `self` is an unsigned int.
-                    unsafe { crate::intrinsics::unchecked_div(self, other.get()) }
-                }
+macro_rules! nonzero_integer_signedness_dependent_impls {
+    // Impls for unsigned nonzero types only.
+    ($Ty:ident unsigned $Int:ty) => {
+        #[stable(feature = "nonzero_div", since = "1.51.0")]
+        impl Div<$Ty> for $Int {
+            type Output = $Int;
+            /// This operation rounds towards zero,
+            /// truncating any fractional part of the exact result, and cannot panic.
+            #[inline]
+            fn div(self, other: $Ty) -> $Int {
+                // SAFETY: div by zero is checked because `other` is a nonzero,
+                // and MIN/-1 is checked because `self` is an unsigned int.
+                unsafe { crate::intrinsics::unchecked_div(self, other.get()) }
             }
+        }
 
-            #[stable(feature = "nonzero_div", since = "1.51.0")]
-            impl Rem<$Ty> for $Int {
-                type Output = $Int;
-                /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic.
-                #[inline]
-                fn rem(self, other: $Ty) -> $Int {
-                    // SAFETY: rem by zero is checked because `other` is a nonzero,
-                    // and MIN/-1 is checked because `self` is an unsigned int.
-                    unsafe { crate::intrinsics::unchecked_rem(self, other.get()) }
-                }
+        #[stable(feature = "nonzero_div", since = "1.51.0")]
+        impl Rem<$Ty> for $Int {
+            type Output = $Int;
+            /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic.
+            #[inline]
+            fn rem(self, other: $Ty) -> $Int {
+                // SAFETY: rem by zero is checked because `other` is a nonzero,
+                // and MIN/-1 is checked because `self` is an unsigned int.
+                unsafe { crate::intrinsics::unchecked_rem(self, other.get()) }
             }
-        )+
-    }
-}
-
-nonzero_integers_div! {
-    NonZeroU8(u8);
-    NonZeroU16(u16);
-    NonZeroU32(u32);
-    NonZeroU64(u64);
-    NonZeroU128(u128);
-    NonZeroUsize(usize);
-}
-
-// A bunch of methods for unsigned nonzero types only.
-macro_rules! nonzero_unsigned_operations {
-    ( $( $Ty: ident($Int: ident); )+ ) => {
-        $(
-            impl $Ty {
-                /// Adds an unsigned integer to a non-zero value.
-                /// Checks for overflow and returns [`None`] on overflow.
-                /// As a consequence, the result cannot wrap to zero.
-                ///
-                ///
-                /// # Examples
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
-                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
-                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MAX)?;")]
-                ///
-                /// assert_eq!(Some(two), one.checked_add(1));
-                /// assert_eq!(None, max.checked_add(1));
-                /// # Some(())
-                /// # }
-                /// ```
-                #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
-                #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn checked_add(self, other: $Int) -> Option<$Ty> {
-                    if let Some(result) = self.get().checked_add(other) {
-                        // SAFETY:
-                        // - `checked_add` returns `None` on overflow
-                        // - `self` is non-zero
-                        // - the only way to get zero from an addition without overflow is for both
-                        //   sides to be zero
-                        //
-                        // So the result cannot be zero.
-                        Some(unsafe { $Ty::new_unchecked(result) })
-                    } else {
-                        None
-                    }
-                }
-
-                /// Adds an unsigned integer to a non-zero value.
-                #[doc = concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.")]
-                ///
-                /// # Examples
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
-                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
-                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MAX)?;")]
-                ///
-                /// assert_eq!(two, one.saturating_add(1));
-                /// assert_eq!(max, max.saturating_add(1));
-                /// # Some(())
-                /// # }
-                /// ```
-                #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
-                #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn saturating_add(self, other: $Int) -> $Ty {
-                    // SAFETY:
-                    // - `saturating_add` returns `u*::MAX` on overflow, which is non-zero
-                    // - `self` is non-zero
-                    // - the only way to get zero from an addition without overflow is for both
-                    //   sides to be zero
-                    //
-                    // So the result cannot be zero.
-                    unsafe { $Ty::new_unchecked(self.get().saturating_add(other)) }
-                }
-
-                /// Adds an unsigned integer to a non-zero value,
-                /// assuming overflow cannot occur.
-                /// Overflow is unchecked, and it is undefined behaviour to overflow
-                /// *even if the result would wrap to a non-zero value*.
-                /// The behaviour is undefined as soon as
-                #[doc = concat!("`self + rhs > ", stringify!($Int), "::MAX`.")]
-                ///
-                /// # Examples
-                ///
-                /// ```
-                /// #![feature(nonzero_ops)]
-                ///
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
-                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
-                ///
-                /// assert_eq!(two, unsafe { one.unchecked_add(1) });
-                /// # Some(())
-                /// # }
-                /// ```
-                #[unstable(feature = "nonzero_ops", issue = "84186")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const unsafe fn unchecked_add(self, other: $Int) -> $Ty {
-                    // SAFETY: The caller ensures there is no overflow.
-                    unsafe { $Ty::new_unchecked(self.get().unchecked_add(other)) }
-                }
-
-                /// Returns the smallest power of two greater than or equal to n.
-                /// Checks for overflow and returns [`None`]
-                /// if the next power of two is greater than the type’s maximum value.
-                /// As a consequence, the result cannot wrap to zero.
-                ///
-                /// # Examples
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
-                #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
-                #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
-                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MAX)?;")]
-                ///
-                /// assert_eq!(Some(two), two.checked_next_power_of_two() );
-                /// assert_eq!(Some(four), three.checked_next_power_of_two() );
-                /// assert_eq!(None, max.checked_next_power_of_two() );
-                /// # Some(())
-                /// # }
-                /// ```
-                #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
-                #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn checked_next_power_of_two(self) -> Option<$Ty> {
-                    if let Some(nz) = self.get().checked_next_power_of_two() {
-                        // SAFETY: The next power of two is positive
-                        // and overflow is checked.
-                        Some(unsafe { $Ty::new_unchecked(nz) })
-                    } else {
-                        None
-                    }
-                }
-
-                /// Returns the base 2 logarithm of the number, rounded down.
-                ///
-                /// This is the same operation as
-                #[doc = concat!("[`", stringify!($Int), "::ilog2`],")]
-                /// except that it has no failure cases to worry about
-                /// since this value can never be zero.
-                ///
-                /// # Examples
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(7).unwrap().ilog2(), 2);")]
-                #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(8).unwrap().ilog2(), 3);")]
-                #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(9).unwrap().ilog2(), 3);")]
-                /// ```
-                #[stable(feature = "int_log", since = "1.67.0")]
-                #[rustc_const_stable(feature = "int_log", since = "1.67.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn ilog2(self) -> u32 {
-                    Self::BITS - 1 - self.leading_zeros()
-                }
+        }
+    };
 
-                /// Returns the base 10 logarithm of the number, rounded down.
-                ///
-                /// This is the same operation as
-                #[doc = concat!("[`", stringify!($Int), "::ilog10`],")]
-                /// except that it has no failure cases to worry about
-                /// since this value can never be zero.
-                ///
-                /// # Examples
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(99).unwrap().ilog10(), 1);")]
-                #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(100).unwrap().ilog10(), 2);")]
-                #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(101).unwrap().ilog10(), 2);")]
-                /// ```
-                #[stable(feature = "int_log", since = "1.67.0")]
-                #[rustc_const_stable(feature = "int_log", since = "1.67.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn ilog10(self) -> u32 {
-                    super::int_log10::$Int(self.get())
-                }
+    // Impls for signed nonzero types only.
+    ($Ty:ident signed $Int:ty) => {
+        #[stable(feature = "signed_nonzero_neg", since = "1.71.0")]
+        impl Neg for $Ty {
+            type Output = $Ty;
 
-                /// Calculates the middle point of `self` and `rhs`.
-                ///
-                /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a
-                /// sufficiently-large signed integral type. This implies that the result is
-                /// always rounded towards negative infinity and that no overflow will ever occur.
-                ///
-                /// # Examples
-                ///
-                /// ```
-                /// #![feature(num_midpoint)]
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                ///
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
-                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
-                #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
-                ///
-                /// assert_eq!(one.midpoint(four), two);
-                /// assert_eq!(four.midpoint(one), two);
-                /// # Some(())
-                /// # }
-                /// ```
-                #[unstable(feature = "num_midpoint", issue = "110840")]
-                #[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")]
-                #[rustc_allow_const_fn_unstable(const_num_midpoint)]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn midpoint(self, rhs: Self) -> Self {
-                    // SAFETY: The only way to get `0` with midpoint is to have two opposite or
-                    // near opposite numbers: (-5, 5), (0, 1), (0, 0) which is impossible because
-                    // of the unsignedness of this number and also because $Ty is guaranteed to
-                    // never being 0.
-                    unsafe { $Ty::new_unchecked(self.get().midpoint(rhs.get())) }
-                }
+            #[inline]
+            fn neg(self) -> $Ty {
+                // SAFETY: negation of nonzero cannot yield zero values.
+                unsafe { $Ty::new_unchecked(self.get().neg()) }
             }
-        )+
-    }
-}
+        }
 
-nonzero_unsigned_operations! {
-    NonZeroU8(u8);
-    NonZeroU16(u16);
-    NonZeroU32(u32);
-    NonZeroU64(u64);
-    NonZeroU128(u128);
-    NonZeroUsize(usize);
+        forward_ref_unop! { impl Neg, neg for $Ty,
+        #[stable(feature = "signed_nonzero_neg", since = "1.71.0")] }
+    };
 }
 
-// A bunch of methods for signed nonzero types only.
-macro_rules! nonzero_signed_operations {
-    ( $( $Ty: ident($Int: ty) -> $Uty: ident($Uint: ty); )+ ) => {
-        $(
-            impl $Ty {
-                /// Computes the absolute value of self.
-                #[doc = concat!("See [`", stringify!($Int), "::abs`]")]
-                /// for documentation on overflow behaviour.
-                ///
-                /// # Example
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
-                #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
-                ///
-                /// assert_eq!(pos, pos.abs());
-                /// assert_eq!(pos, neg.abs());
-                /// # Some(())
-                /// # }
-                /// ```
-                #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
-                #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn abs(self) -> $Ty {
-                    // SAFETY: This cannot overflow to zero.
-                    unsafe { $Ty::new_unchecked(self.get().abs()) }
-                }
-
-                /// Checked absolute value.
-                /// Checks for overflow and returns [`None`] if
-                #[doc = concat!("`self == ", stringify!($Ty), "::MIN`.")]
-                /// The result cannot be zero.
-                ///
-                /// # Example
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
-                #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
-                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MIN)?;")]
-                ///
-                /// assert_eq!(Some(pos), neg.checked_abs());
-                /// assert_eq!(None, min.checked_abs());
-                /// # Some(())
-                /// # }
-                /// ```
-                #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
-                #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn checked_abs(self) -> Option<$Ty> {
-                    if let Some(nz) = self.get().checked_abs() {
-                        // SAFETY: absolute value of nonzero cannot yield zero values.
-                        Some(unsafe { $Ty::new_unchecked(nz) })
-                    } else {
-                        None
-                    }
-                }
-
-                /// Computes the absolute value of self,
-                /// with overflow information, see
-                #[doc = concat!("[`", stringify!($Int), "::overflowing_abs`].")]
-                ///
-                /// # Example
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
-                #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
-                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MIN)?;")]
-                ///
-                /// assert_eq!((pos, false), pos.overflowing_abs());
-                /// assert_eq!((pos, false), neg.overflowing_abs());
-                /// assert_eq!((min, true), min.overflowing_abs());
-                /// # Some(())
-                /// # }
-                /// ```
-                #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
-                #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn overflowing_abs(self) -> ($Ty, bool) {
-                    let (nz, flag) = self.get().overflowing_abs();
-                    (
-                        // SAFETY: absolute value of nonzero cannot yield zero values.
-                        unsafe { $Ty::new_unchecked(nz) },
-                        flag,
-                    )
-                }
+#[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5974
+macro_rules! nonzero_integer_signedness_dependent_methods {
+    // Associated items for unsigned nonzero types only.
+    (
+        Self = $Ty:ident,
+        Primitive = unsigned $Int:ident,
+        UnsignedPrimitive = $Uint:ty,
+    ) => {
+        /// The smallest value that can be represented by this non-zero
+        /// integer type, 1.
+        ///
+        /// # Examples
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        #[doc = concat!("assert_eq!(", stringify!($Ty), "::MIN.get(), 1", stringify!($Int), ");")]
+        /// ```
+        #[stable(feature = "nonzero_min_max", since = "1.70.0")]
+        pub const MIN: Self = Self::new(1).unwrap();
+
+        /// The largest value that can be represented by this non-zero
+        /// integer type,
+        #[doc = concat!("equal to [`", stringify!($Int), "::MAX`].")]
+        ///
+        /// # Examples
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        #[doc = concat!("assert_eq!(", stringify!($Ty), "::MAX.get(), ", stringify!($Int), "::MAX);")]
+        /// ```
+        #[stable(feature = "nonzero_min_max", since = "1.70.0")]
+        pub const MAX: Self = Self::new(<$Int>::MAX).unwrap();
+
+        /// Adds an unsigned integer to a non-zero value.
+        /// Checks for overflow and returns [`None`] on overflow.
+        /// As a consequence, the result cannot wrap to zero.
+        ///
+        ///
+        /// # Examples
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
+        #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+        #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MAX)?;")]
+        ///
+        /// assert_eq!(Some(two), one.checked_add(1));
+        /// assert_eq!(None, max.checked_add(1));
+        /// # Some(())
+        /// # }
+        /// ```
+        #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+        #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn checked_add(self, other: $Int) -> Option<$Ty> {
+            if let Some(result) = self.get().checked_add(other) {
+                // SAFETY:
+                // - `checked_add` returns `None` on overflow
+                // - `self` is non-zero
+                // - the only way to get zero from an addition without overflow is for both
+                //   sides to be zero
+                //
+                // So the result cannot be zero.
+                Some(unsafe { $Ty::new_unchecked(result) })
+            } else {
+                None
+            }
+        }
 
-                /// Saturating absolute value, see
-                #[doc = concat!("[`", stringify!($Int), "::saturating_abs`].")]
-                ///
-                /// # Example
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
-                #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
-                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MIN)?;")]
-                #[doc = concat!("let min_plus = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MIN + 1)?;")]
-                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MAX)?;")]
-                ///
-                /// assert_eq!(pos, pos.saturating_abs());
-                /// assert_eq!(pos, neg.saturating_abs());
-                /// assert_eq!(max, min.saturating_abs());
-                /// assert_eq!(max, min_plus.saturating_abs());
-                /// # Some(())
-                /// # }
-                /// ```
-                #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
-                #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn saturating_abs(self) -> $Ty {
-                    // SAFETY: absolute value of nonzero cannot yield zero values.
-                    unsafe { $Ty::new_unchecked(self.get().saturating_abs()) }
-                }
+        /// Adds an unsigned integer to a non-zero value.
+        #[doc = concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.")]
+        ///
+        /// # Examples
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
+        #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+        #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MAX)?;")]
+        ///
+        /// assert_eq!(two, one.saturating_add(1));
+        /// assert_eq!(max, max.saturating_add(1));
+        /// # Some(())
+        /// # }
+        /// ```
+        #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+        #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn saturating_add(self, other: $Int) -> $Ty {
+            // SAFETY:
+            // - `saturating_add` returns `u*::MAX` on overflow, which is non-zero
+            // - `self` is non-zero
+            // - the only way to get zero from an addition without overflow is for both
+            //   sides to be zero
+            //
+            // So the result cannot be zero.
+            unsafe { $Ty::new_unchecked(self.get().saturating_add(other)) }
+        }
 
-                /// Wrapping absolute value, see
-                #[doc = concat!("[`", stringify!($Int), "::wrapping_abs`].")]
-                ///
-                /// # Example
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
-                #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
-                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MIN)?;")]
-                #[doc = concat!("# let max = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MAX)?;")]
-                ///
-                /// assert_eq!(pos, pos.wrapping_abs());
-                /// assert_eq!(pos, neg.wrapping_abs());
-                /// assert_eq!(min, min.wrapping_abs());
-                /// assert_eq!(max, (-max).wrapping_abs());
-                /// # Some(())
-                /// # }
-                /// ```
-                #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
-                #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn wrapping_abs(self) -> $Ty {
-                    // SAFETY: absolute value of nonzero cannot yield zero values.
-                    unsafe { $Ty::new_unchecked(self.get().wrapping_abs()) }
-                }
+        /// Adds an unsigned integer to a non-zero value,
+        /// assuming overflow cannot occur.
+        /// Overflow is unchecked, and it is undefined behaviour to overflow
+        /// *even if the result would wrap to a non-zero value*.
+        /// The behaviour is undefined as soon as
+        #[doc = concat!("`self + rhs > ", stringify!($Int), "::MAX`.")]
+        ///
+        /// # Examples
+        ///
+        /// ```
+        /// #![feature(nonzero_ops)]
+        ///
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
+        #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+        ///
+        /// assert_eq!(two, unsafe { one.unchecked_add(1) });
+        /// # Some(())
+        /// # }
+        /// ```
+        #[unstable(feature = "nonzero_ops", issue = "84186")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const unsafe fn unchecked_add(self, other: $Int) -> $Ty {
+            // SAFETY: The caller ensures there is no overflow.
+            unsafe { $Ty::new_unchecked(self.get().unchecked_add(other)) }
+        }
 
-                /// Computes the absolute value of self
-                /// without any wrapping or panicking.
-                ///
-                /// # Example
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                #[doc = concat!("# use std::num::", stringify!($Uty), ";")]
-                ///
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let u_pos = ", stringify!($Uty), "::new(1)?;")]
-                #[doc = concat!("let i_pos = ", stringify!($Ty), "::new(1)?;")]
-                #[doc = concat!("let i_neg = ", stringify!($Ty), "::new(-1)?;")]
-                #[doc = concat!("let i_min = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MIN)?;")]
-                #[doc = concat!("let u_max = ", stringify!($Uty), "::new(",
-                                stringify!($Uint), "::MAX / 2 + 1)?;")]
-                ///
-                /// assert_eq!(u_pos, i_pos.unsigned_abs());
-                /// assert_eq!(u_pos, i_neg.unsigned_abs());
-                /// assert_eq!(u_max, i_min.unsigned_abs());
-                /// # Some(())
-                /// # }
-                /// ```
-                #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
-                #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn unsigned_abs(self) -> $Uty {
-                    // SAFETY: absolute value of nonzero cannot yield zero values.
-                    unsafe { $Uty::new_unchecked(self.get().unsigned_abs()) }
-                }
+        /// Returns the smallest power of two greater than or equal to n.
+        /// Checks for overflow and returns [`None`]
+        /// if the next power of two is greater than the type’s maximum value.
+        /// As a consequence, the result cannot wrap to zero.
+        ///
+        /// # Examples
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+        #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
+        #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
+        #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MAX)?;")]
+        ///
+        /// assert_eq!(Some(two), two.checked_next_power_of_two() );
+        /// assert_eq!(Some(four), three.checked_next_power_of_two() );
+        /// assert_eq!(None, max.checked_next_power_of_two() );
+        /// # Some(())
+        /// # }
+        /// ```
+        #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+        #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn checked_next_power_of_two(self) -> Option<$Ty> {
+            if let Some(nz) = self.get().checked_next_power_of_two() {
+                // SAFETY: The next power of two is positive
+                // and overflow is checked.
+                Some(unsafe { $Ty::new_unchecked(nz) })
+            } else {
+                None
+            }
+        }
 
-                /// Returns `true` if `self` is positive and `false` if the
-                /// number is negative.
-                ///
-                /// # Example
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
-                #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
-                ///
-                /// assert!(pos_five.is_positive());
-                /// assert!(!neg_five.is_positive());
-                /// # Some(())
-                /// # }
-                /// ```
-                #[must_use]
-                #[inline]
-                #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
-                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
-                pub const fn is_positive(self) -> bool {
-                    self.get().is_positive()
-                }
+        /// Returns the base 2 logarithm of the number, rounded down.
+        ///
+        /// This is the same operation as
+        #[doc = concat!("[`", stringify!($Int), "::ilog2`],")]
+        /// except that it has no failure cases to worry about
+        /// since this value can never be zero.
+        ///
+        /// # Examples
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(7).unwrap().ilog2(), 2);")]
+        #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(8).unwrap().ilog2(), 3);")]
+        #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(9).unwrap().ilog2(), 3);")]
+        /// ```
+        #[stable(feature = "int_log", since = "1.67.0")]
+        #[rustc_const_stable(feature = "int_log", since = "1.67.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn ilog2(self) -> u32 {
+            Self::BITS - 1 - self.leading_zeros()
+        }
 
-                /// Returns `true` if `self` is negative and `false` if the
-                /// number is positive.
-                ///
-                /// # Example
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
-                #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
-                ///
-                /// assert!(neg_five.is_negative());
-                /// assert!(!pos_five.is_negative());
-                /// # Some(())
-                /// # }
-                /// ```
-                #[must_use]
-                #[inline]
-                #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
-                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
-                pub const fn is_negative(self) -> bool {
-                    self.get().is_negative()
-                }
+        /// Returns the base 10 logarithm of the number, rounded down.
+        ///
+        /// This is the same operation as
+        #[doc = concat!("[`", stringify!($Int), "::ilog10`],")]
+        /// except that it has no failure cases to worry about
+        /// since this value can never be zero.
+        ///
+        /// # Examples
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(99).unwrap().ilog10(), 1);")]
+        #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(100).unwrap().ilog10(), 2);")]
+        #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(101).unwrap().ilog10(), 2);")]
+        /// ```
+        #[stable(feature = "int_log", since = "1.67.0")]
+        #[rustc_const_stable(feature = "int_log", since = "1.67.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn ilog10(self) -> u32 {
+            super::int_log10::$Int(self.get())
+        }
 
-                /// Checked negation. Computes `-self`,
-                #[doc = concat!("returning `None` if `self == ", stringify!($Ty), "::MIN`.")]
-                ///
-                /// # Example
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
-                #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
-                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MIN)?;")]
-                ///
-                /// assert_eq!(pos_five.checked_neg(), Some(neg_five));
-                /// assert_eq!(min.checked_neg(), None);
-                /// # Some(())
-                /// # }
-                /// ```
-                #[inline]
-                #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
-                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
-                pub const fn checked_neg(self) -> Option<$Ty> {
-                    if let Some(result) = self.get().checked_neg() {
-                        // SAFETY: negation of nonzero cannot yield zero values.
-                        return Some(unsafe { $Ty::new_unchecked(result) });
-                    }
-                    None
-                }
+        /// Calculates the middle point of `self` and `rhs`.
+        ///
+        /// `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a
+        /// sufficiently-large signed integral type. This implies that the result is
+        /// always rounded towards negative infinity and that no overflow will ever occur.
+        ///
+        /// # Examples
+        ///
+        /// ```
+        /// #![feature(num_midpoint)]
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        ///
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let one = ", stringify!($Ty), "::new(1)?;")]
+        #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
+        #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
+        ///
+        /// assert_eq!(one.midpoint(four), two);
+        /// assert_eq!(four.midpoint(one), two);
+        /// # Some(())
+        /// # }
+        /// ```
+        #[unstable(feature = "num_midpoint", issue = "110840")]
+        #[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")]
+        #[rustc_allow_const_fn_unstable(const_num_midpoint)]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn midpoint(self, rhs: Self) -> Self {
+            // SAFETY: The only way to get `0` with midpoint is to have two opposite or
+            // near opposite numbers: (-5, 5), (0, 1), (0, 0) which is impossible because
+            // of the unsignedness of this number and also because $Ty is guaranteed to
+            // never being 0.
+            unsafe { $Ty::new_unchecked(self.get().midpoint(rhs.get())) }
+        }
 
-                /// Negates self, overflowing if this is equal to the minimum value.
-                ///
-                #[doc = concat!("See [`", stringify!($Int), "::overflowing_neg`]")]
-                /// for documentation on overflow behaviour.
-                ///
-                /// # Example
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
-                #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
-                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MIN)?;")]
-                ///
-                /// assert_eq!(pos_five.overflowing_neg(), (neg_five, false));
-                /// assert_eq!(min.overflowing_neg(), (min, true));
-                /// # Some(())
-                /// # }
-                /// ```
-                #[inline]
-                #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
-                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
-                pub const fn overflowing_neg(self) -> ($Ty, bool) {
-                    let (result, overflow) = self.get().overflowing_neg();
-                    // SAFETY: negation of nonzero cannot yield zero values.
-                    ((unsafe { $Ty::new_unchecked(result) }), overflow)
-                }
+        /// Returns `true` if and only if `self == (1 << k)` for some `k`.
+        ///
+        /// On many architectures, this function can perform better than `is_power_of_two()`
+        /// on the underlying integer type, as special handling of zero can be avoided.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        #[doc = concat!("let eight = std::num::", stringify!($Ty), "::new(8).unwrap();")]
+        /// assert!(eight.is_power_of_two());
+        #[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")]
+        /// assert!(!ten.is_power_of_two());
+        /// ```
+        #[must_use]
+        #[stable(feature = "nonzero_is_power_of_two", since = "1.59.0")]
+        #[rustc_const_stable(feature = "nonzero_is_power_of_two", since = "1.59.0")]
+        #[inline]
+        pub const fn is_power_of_two(self) -> bool {
+            // LLVM 11 normalizes `unchecked_sub(x, 1) & x == 0` to the implementation seen here.
+            // On the basic x86-64 target, this saves 3 instructions for the zero check.
+            // On x86_64 with BMI1, being nonzero lets it codegen to `BLSR`, which saves an instruction
+            // compared to the `POPCNT` implementation on the underlying integer type.
+
+            intrinsics::ctpop(self.get()) < 2
+        }
+    };
 
-                /// Saturating negation. Computes `-self`,
-                #[doc = concat!("returning [`", stringify!($Ty), "::MAX`]")]
-                #[doc = concat!("if `self == ", stringify!($Ty), "::MIN`")]
-                /// instead of overflowing.
-                ///
-                /// # Example
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
-                #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
-                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MIN)?;")]
-                #[doc = concat!("let min_plus_one = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MIN + 1)?;")]
-                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MAX)?;")]
-                ///
-                /// assert_eq!(pos_five.saturating_neg(), neg_five);
-                /// assert_eq!(min.saturating_neg(), max);
-                /// assert_eq!(max.saturating_neg(), min_plus_one);
-                /// # Some(())
-                /// # }
-                /// ```
-                #[inline]
-                #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
-                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
-                pub const fn saturating_neg(self) -> $Ty {
-                    if let Some(result) = self.checked_neg() {
-                        return result;
-                    }
-                    $Ty::MAX
-                }
+    // Associated items for signed nonzero types only.
+    (
+        Self = $Ty:ident,
+        Primitive = signed $Int:ident,
+        UnsignedNonZero = $Uty:ident,
+        UnsignedPrimitive = $Uint:ty,
+    ) => {
+        /// The smallest value that can be represented by this non-zero
+        /// integer type,
+        #[doc = concat!("equal to [`", stringify!($Int), "::MIN`].")]
+        ///
+        /// Note: While most integer types are defined for every whole
+        /// number between `MIN` and `MAX`, signed non-zero integers are
+        /// a special case. They have a "gap" at 0.
+        ///
+        /// # Examples
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        #[doc = concat!("assert_eq!(", stringify!($Ty), "::MIN.get(), ", stringify!($Int), "::MIN);")]
+        /// ```
+        #[stable(feature = "nonzero_min_max", since = "1.70.0")]
+        pub const MIN: Self = Self::new(<$Int>::MIN).unwrap();
+
+        /// The largest value that can be represented by this non-zero
+        /// integer type,
+        #[doc = concat!("equal to [`", stringify!($Int), "::MAX`].")]
+        ///
+        /// Note: While most integer types are defined for every whole
+        /// number between `MIN` and `MAX`, signed non-zero integers are
+        /// a special case. They have a "gap" at 0.
+        ///
+        /// # Examples
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        #[doc = concat!("assert_eq!(", stringify!($Ty), "::MAX.get(), ", stringify!($Int), "::MAX);")]
+        /// ```
+        #[stable(feature = "nonzero_min_max", since = "1.70.0")]
+        pub const MAX: Self = Self::new(<$Int>::MAX).unwrap();
+
+        /// Computes the absolute value of self.
+        #[doc = concat!("See [`", stringify!($Int), "::abs`]")]
+        /// for documentation on overflow behaviour.
+        ///
+        /// # Example
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
+        #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
+        ///
+        /// assert_eq!(pos, pos.abs());
+        /// assert_eq!(pos, neg.abs());
+        /// # Some(())
+        /// # }
+        /// ```
+        #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+        #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn abs(self) -> $Ty {
+            // SAFETY: This cannot overflow to zero.
+            unsafe { $Ty::new_unchecked(self.get().abs()) }
+        }
 
-                /// Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary
-                /// of the type.
-                ///
-                #[doc = concat!("See [`", stringify!($Int), "::wrapping_neg`]")]
-                /// for documentation on overflow behaviour.
-                ///
-                /// # Example
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
-                #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
-                #[doc = concat!("let min = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MIN)?;")]
-                ///
-                /// assert_eq!(pos_five.wrapping_neg(), neg_five);
-                /// assert_eq!(min.wrapping_neg(), min);
-                /// # Some(())
-                /// # }
-                /// ```
-                #[inline]
-                #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
-                #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
-                pub const fn wrapping_neg(self) -> $Ty {
-                    let result = self.get().wrapping_neg();
-                    // SAFETY: negation of nonzero cannot yield zero values.
-                    unsafe { $Ty::new_unchecked(result) }
-                }
+        /// Checked absolute value.
+        /// Checks for overflow and returns [`None`] if
+        #[doc = concat!("`self == ", stringify!($Ty), "::MIN`.")]
+        /// The result cannot be zero.
+        ///
+        /// # Example
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
+        #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
+        #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MIN)?;")]
+        ///
+        /// assert_eq!(Some(pos), neg.checked_abs());
+        /// assert_eq!(None, min.checked_abs());
+        /// # Some(())
+        /// # }
+        /// ```
+        #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+        #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn checked_abs(self) -> Option<$Ty> {
+            if let Some(nz) = self.get().checked_abs() {
+                // SAFETY: absolute value of nonzero cannot yield zero values.
+                Some(unsafe { $Ty::new_unchecked(nz) })
+            } else {
+                None
             }
+        }
 
-            #[stable(feature = "signed_nonzero_neg", since = "1.71.0")]
-            impl Neg for $Ty {
-                type Output = $Ty;
+        /// Computes the absolute value of self,
+        /// with overflow information, see
+        #[doc = concat!("[`", stringify!($Int), "::overflowing_abs`].")]
+        ///
+        /// # Example
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
+        #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
+        #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MIN)?;")]
+        ///
+        /// assert_eq!((pos, false), pos.overflowing_abs());
+        /// assert_eq!((pos, false), neg.overflowing_abs());
+        /// assert_eq!((min, true), min.overflowing_abs());
+        /// # Some(())
+        /// # }
+        /// ```
+        #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+        #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn overflowing_abs(self) -> ($Ty, bool) {
+            let (nz, flag) = self.get().overflowing_abs();
+            (
+                // SAFETY: absolute value of nonzero cannot yield zero values.
+                unsafe { $Ty::new_unchecked(nz) },
+                flag,
+            )
+        }
 
-                #[inline]
-                fn neg(self) -> $Ty {
-                    // SAFETY: negation of nonzero cannot yield zero values.
-                    unsafe { $Ty::new_unchecked(self.get().neg()) }
-                }
-            }
+        /// Saturating absolute value, see
+        #[doc = concat!("[`", stringify!($Int), "::saturating_abs`].")]
+        ///
+        /// # Example
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
+        #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
+        #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MIN)?;")]
+        #[doc = concat!("let min_plus = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MIN + 1)?;")]
+        #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MAX)?;")]
+        ///
+        /// assert_eq!(pos, pos.saturating_abs());
+        /// assert_eq!(pos, neg.saturating_abs());
+        /// assert_eq!(max, min.saturating_abs());
+        /// assert_eq!(max, min_plus.saturating_abs());
+        /// # Some(())
+        /// # }
+        /// ```
+        #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+        #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn saturating_abs(self) -> $Ty {
+            // SAFETY: absolute value of nonzero cannot yield zero values.
+            unsafe { $Ty::new_unchecked(self.get().saturating_abs()) }
+        }
 
-            forward_ref_unop! { impl Neg, neg for $Ty,
-                #[stable(feature = "signed_nonzero_neg", since = "1.71.0")] }
-        )+
-    }
-}
+        /// Wrapping absolute value, see
+        #[doc = concat!("[`", stringify!($Int), "::wrapping_abs`].")]
+        ///
+        /// # Example
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let pos = ", stringify!($Ty), "::new(1)?;")]
+        #[doc = concat!("let neg = ", stringify!($Ty), "::new(-1)?;")]
+        #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MIN)?;")]
+        #[doc = concat!("# let max = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MAX)?;")]
+        ///
+        /// assert_eq!(pos, pos.wrapping_abs());
+        /// assert_eq!(pos, neg.wrapping_abs());
+        /// assert_eq!(min, min.wrapping_abs());
+        /// assert_eq!(max, (-max).wrapping_abs());
+        /// # Some(())
+        /// # }
+        /// ```
+        #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+        #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn wrapping_abs(self) -> $Ty {
+            // SAFETY: absolute value of nonzero cannot yield zero values.
+            unsafe { $Ty::new_unchecked(self.get().wrapping_abs()) }
+        }
 
-nonzero_signed_operations! {
-    NonZeroI8(i8) -> NonZeroU8(u8);
-    NonZeroI16(i16) -> NonZeroU16(u16);
-    NonZeroI32(i32) -> NonZeroU32(u32);
-    NonZeroI64(i64) -> NonZeroU64(u64);
-    NonZeroI128(i128) -> NonZeroU128(u128);
-    NonZeroIsize(isize) -> NonZeroUsize(usize);
-}
+        /// Computes the absolute value of self
+        /// without any wrapping or panicking.
+        ///
+        /// # Example
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        #[doc = concat!("# use std::num::", stringify!($Uty), ";")]
+        ///
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let u_pos = ", stringify!($Uty), "::new(1)?;")]
+        #[doc = concat!("let i_pos = ", stringify!($Ty), "::new(1)?;")]
+        #[doc = concat!("let i_neg = ", stringify!($Ty), "::new(-1)?;")]
+        #[doc = concat!("let i_min = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MIN)?;")]
+        #[doc = concat!("let u_max = ", stringify!($Uty), "::new(",
+                        stringify!($Uint), "::MAX / 2 + 1)?;")]
+        ///
+        /// assert_eq!(u_pos, i_pos.unsigned_abs());
+        /// assert_eq!(u_pos, i_neg.unsigned_abs());
+        /// assert_eq!(u_max, i_min.unsigned_abs());
+        /// # Some(())
+        /// # }
+        /// ```
+        #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
+        #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn unsigned_abs(self) -> $Uty {
+            // SAFETY: absolute value of nonzero cannot yield zero values.
+            unsafe { $Uty::new_unchecked(self.get().unsigned_abs()) }
+        }
 
-// A bunch of methods for both signed and unsigned nonzero types.
-macro_rules! nonzero_unsigned_signed_operations {
-    ( $( $signedness:ident $Ty: ident($Int: ty); )+ ) => {
-        $(
-            impl $Ty {
-                /// Multiplies two non-zero integers together.
-                /// Checks for overflow and returns [`None`] on overflow.
-                /// As a consequence, the result cannot wrap to zero.
-                ///
-                /// # Examples
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
-                #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
-                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MAX)?;")]
-                ///
-                /// assert_eq!(Some(four), two.checked_mul(two));
-                /// assert_eq!(None, max.checked_mul(two));
-                /// # Some(())
-                /// # }
-                /// ```
-                #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
-                #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn checked_mul(self, other: $Ty) -> Option<$Ty> {
-                    if let Some(result) = self.get().checked_mul(other.get()) {
-                        // SAFETY:
-                        // - `checked_mul` returns `None` on overflow
-                        // - `self` and `other` are non-zero
-                        // - the only way to get zero from a multiplication without overflow is for one
-                        //   of the sides to be zero
-                        //
-                        // So the result cannot be zero.
-                        Some(unsafe { $Ty::new_unchecked(result) })
-                    } else {
-                        None
-                    }
-                }
+        /// Returns `true` if `self` is positive and `false` if the
+        /// number is negative.
+        ///
+        /// # Example
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
+        #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
+        ///
+        /// assert!(pos_five.is_positive());
+        /// assert!(!neg_five.is_positive());
+        /// # Some(())
+        /// # }
+        /// ```
+        #[must_use]
+        #[inline]
+        #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+        #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+        pub const fn is_positive(self) -> bool {
+            self.get().is_positive()
+        }
 
-                /// Multiplies two non-zero integers together.
-                #[doc = concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.")]
-                ///
-                /// # Examples
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
-                #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
-                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MAX)?;")]
-                ///
-                /// assert_eq!(four, two.saturating_mul(two));
-                /// assert_eq!(max, four.saturating_mul(max));
-                /// # Some(())
-                /// # }
-                /// ```
-                #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
-                #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn saturating_mul(self, other: $Ty) -> $Ty {
-                    // SAFETY:
-                    // - `saturating_mul` returns `u*::MAX`/`i*::MAX`/`i*::MIN` on overflow/underflow,
-                    //   all of which are non-zero
-                    // - `self` and `other` are non-zero
-                    // - the only way to get zero from a multiplication without overflow is for one
-                    //   of the sides to be zero
-                    //
-                    // So the result cannot be zero.
-                    unsafe { $Ty::new_unchecked(self.get().saturating_mul(other.get())) }
-                }
+        /// Returns `true` if `self` is negative and `false` if the
+        /// number is positive.
+        ///
+        /// # Example
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
+        #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
+        ///
+        /// assert!(neg_five.is_negative());
+        /// assert!(!pos_five.is_negative());
+        /// # Some(())
+        /// # }
+        /// ```
+        #[must_use]
+        #[inline]
+        #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+        #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+        pub const fn is_negative(self) -> bool {
+            self.get().is_negative()
+        }
 
-                /// Multiplies two non-zero integers together,
-                /// assuming overflow cannot occur.
-                /// Overflow is unchecked, and it is undefined behaviour to overflow
-                /// *even if the result would wrap to a non-zero value*.
-                /// The behaviour is undefined as soon as
-                #[doc = sign_dependent_expr!{
-                    $signedness ?
-                    if signed {
-                        concat!("`self * rhs > ", stringify!($Int), "::MAX`, ",
-                                "or `self * rhs < ", stringify!($Int), "::MIN`.")
-                    }
-                    if unsigned {
-                        concat!("`self * rhs > ", stringify!($Int), "::MAX`.")
-                    }
-                }]
-                ///
-                /// # Examples
-                ///
-                /// ```
-                /// #![feature(nonzero_ops)]
-                ///
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let two = ", stringify!($Ty), "::new(2)?;")]
-                #[doc = concat!("let four = ", stringify!($Ty), "::new(4)?;")]
-                ///
-                /// assert_eq!(four, unsafe { two.unchecked_mul(two) });
-                /// # Some(())
-                /// # }
-                /// ```
-                #[unstable(feature = "nonzero_ops", issue = "84186")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const unsafe fn unchecked_mul(self, other: $Ty) -> $Ty {
-                    // SAFETY: The caller ensures there is no overflow.
-                    unsafe { $Ty::new_unchecked(self.get().unchecked_mul(other.get())) }
-                }
+        /// Checked negation. Computes `-self`,
+        #[doc = concat!("returning `None` if `self == ", stringify!($Ty), "::MIN`.")]
+        ///
+        /// # Example
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
+        #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
+        #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MIN)?;")]
+        ///
+        /// assert_eq!(pos_five.checked_neg(), Some(neg_five));
+        /// assert_eq!(min.checked_neg(), None);
+        /// # Some(())
+        /// # }
+        /// ```
+        #[inline]
+        #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+        #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+        pub const fn checked_neg(self) -> Option<$Ty> {
+            if let Some(result) = self.get().checked_neg() {
+                // SAFETY: negation of nonzero cannot yield zero values.
+                return Some(unsafe { $Ty::new_unchecked(result) });
+            }
+            None
+        }
 
-                /// Raises non-zero value to an integer power.
-                /// Checks for overflow and returns [`None`] on overflow.
-                /// As a consequence, the result cannot wrap to zero.
-                ///
-                /// # Examples
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
-                #[doc = concat!("let twenty_seven = ", stringify!($Ty), "::new(27)?;")]
-                #[doc = concat!("let half_max = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MAX / 2)?;")]
-                ///
-                /// assert_eq!(Some(twenty_seven), three.checked_pow(3));
-                /// assert_eq!(None, half_max.checked_pow(3));
-                /// # Some(())
-                /// # }
-                /// ```
-                #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
-                #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn checked_pow(self, other: u32) -> Option<$Ty> {
-                    if let Some(result) = self.get().checked_pow(other) {
-                        // SAFETY:
-                        // - `checked_pow` returns `None` on overflow/underflow
-                        // - `self` is non-zero
-                        // - the only way to get zero from an exponentiation without overflow is
-                        //   for base to be zero
-                        //
-                        // So the result cannot be zero.
-                        Some(unsafe { $Ty::new_unchecked(result) })
-                    } else {
-                        None
-                    }
-                }
+        /// Negates self, overflowing if this is equal to the minimum value.
+        ///
+        #[doc = concat!("See [`", stringify!($Int), "::overflowing_neg`]")]
+        /// for documentation on overflow behaviour.
+        ///
+        /// # Example
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
+        #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
+        #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MIN)?;")]
+        ///
+        /// assert_eq!(pos_five.overflowing_neg(), (neg_five, false));
+        /// assert_eq!(min.overflowing_neg(), (min, true));
+        /// # Some(())
+        /// # }
+        /// ```
+        #[inline]
+        #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+        #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+        pub const fn overflowing_neg(self) -> ($Ty, bool) {
+            let (result, overflow) = self.get().overflowing_neg();
+            // SAFETY: negation of nonzero cannot yield zero values.
+            ((unsafe { $Ty::new_unchecked(result) }), overflow)
+        }
 
-                /// Raise non-zero value to an integer power.
-                #[doc = sign_dependent_expr!{
-                    $signedness ?
-                    if signed {
-                        concat!("Return [`", stringify!($Ty), "::MIN`] ",
-                                    "or [`", stringify!($Ty), "::MAX`] on overflow.")
-                    }
-                    if unsigned {
-                        concat!("Return [`", stringify!($Ty), "::MAX`] on overflow.")
-                    }
-                }]
-                ///
-                /// # Examples
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                /// # fn main() { test().unwrap(); }
-                /// # fn test() -> Option<()> {
-                #[doc = concat!("let three = ", stringify!($Ty), "::new(3)?;")]
-                #[doc = concat!("let twenty_seven = ", stringify!($Ty), "::new(27)?;")]
-                #[doc = concat!("let max = ", stringify!($Ty), "::new(",
-                                stringify!($Int), "::MAX)?;")]
-                ///
-                /// assert_eq!(twenty_seven, three.saturating_pow(3));
-                /// assert_eq!(max, max.saturating_pow(3));
-                /// # Some(())
-                /// # }
-                /// ```
-                #[stable(feature = "nonzero_checked_ops", since = "1.64.0")]
-                #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")]
-                #[must_use = "this returns the result of the operation, \
-                              without modifying the original"]
-                #[inline]
-                pub const fn saturating_pow(self, other: u32) -> $Ty {
-                    // SAFETY:
-                    // - `saturating_pow` returns `u*::MAX`/`i*::MAX`/`i*::MIN` on overflow/underflow,
-                    //   all of which are non-zero
-                    // - `self` is non-zero
-                    // - the only way to get zero from an exponentiation without overflow is
-                    //   for base to be zero
-                    //
-                    // So the result cannot be zero.
-                    unsafe { $Ty::new_unchecked(self.get().saturating_pow(other)) }
-                }
+        /// Saturating negation. Computes `-self`,
+        #[doc = concat!("returning [`", stringify!($Ty), "::MAX`]")]
+        #[doc = concat!("if `self == ", stringify!($Ty), "::MIN`")]
+        /// instead of overflowing.
+        ///
+        /// # Example
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
+        #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
+        #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MIN)?;")]
+        #[doc = concat!("let min_plus_one = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MIN + 1)?;")]
+        #[doc = concat!("let max = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MAX)?;")]
+        ///
+        /// assert_eq!(pos_five.saturating_neg(), neg_five);
+        /// assert_eq!(min.saturating_neg(), max);
+        /// assert_eq!(max.saturating_neg(), min_plus_one);
+        /// # Some(())
+        /// # }
+        /// ```
+        #[inline]
+        #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+        #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+        pub const fn saturating_neg(self) -> $Ty {
+            if let Some(result) = self.checked_neg() {
+                return result;
             }
-        )+
-    }
+            $Ty::MAX
+        }
+
+        /// Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary
+        /// of the type.
+        ///
+        #[doc = concat!("See [`", stringify!($Int), "::wrapping_neg`]")]
+        /// for documentation on overflow behaviour.
+        ///
+        /// # Example
+        ///
+        /// ```
+        #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+        /// # fn main() { test().unwrap(); }
+        /// # fn test() -> Option<()> {
+        #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")]
+        #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")]
+        #[doc = concat!("let min = ", stringify!($Ty), "::new(",
+                        stringify!($Int), "::MIN)?;")]
+        ///
+        /// assert_eq!(pos_five.wrapping_neg(), neg_five);
+        /// assert_eq!(min.wrapping_neg(), min);
+        /// # Some(())
+        /// # }
+        /// ```
+        #[inline]
+        #[stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+        #[rustc_const_stable(feature = "nonzero_negation_ops", since = "1.71.0")]
+        pub const fn wrapping_neg(self) -> $Ty {
+            let result = self.get().wrapping_neg();
+            // SAFETY: negation of nonzero cannot yield zero values.
+            unsafe { $Ty::new_unchecked(result) }
+        }
+    };
 }
 
 // Use this when the generated code should differ between signed and unsigned types.
@@ -1212,187 +1367,74 @@ macro_rules! sign_dependent_expr {
     };
 }
 
-nonzero_unsigned_signed_operations! {
-    unsigned NonZeroU8(u8);
-    unsigned NonZeroU16(u16);
-    unsigned NonZeroU32(u32);
-    unsigned NonZeroU64(u64);
-    unsigned NonZeroU128(u128);
-    unsigned NonZeroUsize(usize);
-    signed NonZeroI8(i8);
-    signed NonZeroI16(i16);
-    signed NonZeroI32(i32);
-    signed NonZeroI64(i64);
-    signed NonZeroI128(i128);
-    signed NonZeroIsize(isize);
+nonzero_integer! {
+    Self = NonZeroU8,
+    Primitive = unsigned u8,
 }
 
-macro_rules! nonzero_unsigned_is_power_of_two {
-    ( $( $Ty: ident )+ ) => {
-        $(
-            impl $Ty {
-
-                /// Returns `true` if and only if `self == (1 << k)` for some `k`.
-                ///
-                /// On many architectures, this function can perform better than `is_power_of_two()`
-                /// on the underlying integer type, as special handling of zero can be avoided.
-                ///
-                /// # Examples
-                ///
-                /// Basic usage:
-                ///
-                /// ```
-                #[doc = concat!("let eight = std::num::", stringify!($Ty), "::new(8).unwrap();")]
-                /// assert!(eight.is_power_of_two());
-                #[doc = concat!("let ten = std::num::", stringify!($Ty), "::new(10).unwrap();")]
-                /// assert!(!ten.is_power_of_two());
-                /// ```
-                #[must_use]
-                #[stable(feature = "nonzero_is_power_of_two", since = "1.59.0")]
-                #[rustc_const_stable(feature = "nonzero_is_power_of_two", since = "1.59.0")]
-                #[inline]
-                pub const fn is_power_of_two(self) -> bool {
-                    // LLVM 11 normalizes `unchecked_sub(x, 1) & x == 0` to the implementation seen here.
-                    // On the basic x86-64 target, this saves 3 instructions for the zero check.
-                    // On x86_64 with BMI1, being nonzero lets it codegen to `BLSR`, which saves an instruction
-                    // compared to the `POPCNT` implementation on the underlying integer type.
+nonzero_integer! {
+    Self = NonZeroU16,
+    Primitive = unsigned u16,
+}
 
-                    intrinsics::ctpop(self.get()) < 2
-                }
+nonzero_integer! {
+    Self = NonZeroU32,
+    Primitive = unsigned u32,
+}
 
-            }
-        )+
-    }
+nonzero_integer! {
+    Self = NonZeroU64,
+    Primitive = unsigned u64,
 }
 
-nonzero_unsigned_is_power_of_two! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize }
+nonzero_integer! {
+    Self = NonZeroU128,
+    Primitive = unsigned u128,
+}
 
-macro_rules! nonzero_min_max_unsigned {
-    ( $( $Ty: ident($Int: ident); )+ ) => {
-        $(
-            impl $Ty {
-                /// The smallest value that can be represented by this non-zero
-                /// integer type, 1.
-                ///
-                /// # Examples
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                #[doc = concat!("assert_eq!(", stringify!($Ty), "::MIN.get(), 1", stringify!($Int), ");")]
-                /// ```
-                #[stable(feature = "nonzero_min_max", since = "1.70.0")]
-                pub const MIN: Self = Self::new(1).unwrap();
-
-                /// The largest value that can be represented by this non-zero
-                /// integer type,
-                #[doc = concat!("equal to [`", stringify!($Int), "::MAX`].")]
-                ///
-                /// # Examples
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                #[doc = concat!("assert_eq!(", stringify!($Ty), "::MAX.get(), ", stringify!($Int), "::MAX);")]
-                /// ```
-                #[stable(feature = "nonzero_min_max", since = "1.70.0")]
-                pub const MAX: Self = Self::new(<$Int>::MAX).unwrap();
-            }
-        )+
-    }
+nonzero_integer! {
+    Self = NonZeroUsize,
+    Primitive = unsigned usize,
 }
 
-macro_rules! nonzero_min_max_signed {
-    ( $( $Ty: ident($Int: ident); )+ ) => {
-        $(
-            impl $Ty {
-                /// The smallest value that can be represented by this non-zero
-                /// integer type,
-                #[doc = concat!("equal to [`", stringify!($Int), "::MIN`].")]
-                ///
-                /// Note: While most integer types are defined for every whole
-                /// number between `MIN` and `MAX`, signed non-zero integers are
-                /// a special case. They have a "gap" at 0.
-                ///
-                /// # Examples
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                #[doc = concat!("assert_eq!(", stringify!($Ty), "::MIN.get(), ", stringify!($Int), "::MIN);")]
-                /// ```
-                #[stable(feature = "nonzero_min_max", since = "1.70.0")]
-                pub const MIN: Self = Self::new(<$Int>::MIN).unwrap();
-
-                /// The largest value that can be represented by this non-zero
-                /// integer type,
-                #[doc = concat!("equal to [`", stringify!($Int), "::MAX`].")]
-                ///
-                /// Note: While most integer types are defined for every whole
-                /// number between `MIN` and `MAX`, signed non-zero integers are
-                /// a special case. They have a "gap" at 0.
-                ///
-                /// # Examples
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                #[doc = concat!("assert_eq!(", stringify!($Ty), "::MAX.get(), ", stringify!($Int), "::MAX);")]
-                /// ```
-                #[stable(feature = "nonzero_min_max", since = "1.70.0")]
-                pub const MAX: Self = Self::new(<$Int>::MAX).unwrap();
-            }
-        )+
-    }
+nonzero_integer! {
+    Self = NonZeroI8,
+    Primitive = signed i8,
+    UnsignedNonZero = NonZeroU8,
+    UnsignedPrimitive = u8,
 }
 
-nonzero_min_max_unsigned! {
-    NonZeroU8(u8);
-    NonZeroU16(u16);
-    NonZeroU32(u32);
-    NonZeroU64(u64);
-    NonZeroU128(u128);
-    NonZeroUsize(usize);
+nonzero_integer! {
+    Self = NonZeroI16,
+    Primitive = signed i16,
+    UnsignedNonZero = NonZeroU16,
+    UnsignedPrimitive = u16,
 }
 
-nonzero_min_max_signed! {
-    NonZeroI8(i8);
-    NonZeroI16(i16);
-    NonZeroI32(i32);
-    NonZeroI64(i64);
-    NonZeroI128(i128);
-    NonZeroIsize(isize);
+nonzero_integer! {
+    Self = NonZeroI32,
+    Primitive = signed i32,
+    UnsignedNonZero = NonZeroU32,
+    UnsignedPrimitive = u32,
 }
 
-macro_rules! nonzero_bits {
-    ( $( $Ty: ident($Int: ty); )+ ) => {
-        $(
-            impl $Ty {
-                /// The size of this non-zero integer type in bits.
-                ///
-                #[doc = concat!("This value is equal to [`", stringify!($Int), "::BITS`].")]
-                ///
-                /// # Examples
-                ///
-                /// ```
-                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
-                ///
-                #[doc = concat!("assert_eq!(", stringify!($Ty), "::BITS, ", stringify!($Int), "::BITS);")]
-                /// ```
-                #[stable(feature = "nonzero_bits", since = "1.67.0")]
-                pub const BITS: u32 = <$Int>::BITS;
-            }
-        )+
-    }
+nonzero_integer! {
+    Self = NonZeroI64,
+    Primitive = signed i64,
+    UnsignedNonZero = NonZeroU64,
+    UnsignedPrimitive = u64,
+}
+
+nonzero_integer! {
+    Self = NonZeroI128,
+    Primitive = signed i128,
+    UnsignedNonZero = NonZeroU128,
+    UnsignedPrimitive = u128,
 }
 
-nonzero_bits! {
-    NonZeroU8(u8);
-    NonZeroI8(i8);
-    NonZeroU16(u16);
-    NonZeroI16(i16);
-    NonZeroU32(u32);
-    NonZeroI32(i32);
-    NonZeroU64(u64);
-    NonZeroI64(i64);
-    NonZeroU128(u128);
-    NonZeroI128(i128);
-    NonZeroUsize(usize);
-    NonZeroIsize(isize);
+nonzero_integer! {
+    Self = NonZeroIsize,
+    Primitive = signed isize,
+    UnsignedNonZero = NonZeroUsize,
+    UnsignedPrimitive = usize,
 }
diff --git a/library/core/src/num/overflow_panic.rs b/library/core/src/num/overflow_panic.rs
new file mode 100644
index 00000000000..203037ffb43
--- /dev/null
+++ b/library/core/src/num/overflow_panic.rs
@@ -0,0 +1,51 @@
+//! Functions for panicking on overflow.
+//!
+//! In particular, these are used by the `strict_` methods on integers.
+
+#[cold]
+#[track_caller]
+pub const fn add() -> ! {
+    panic!("attempt to add with overflow")
+}
+
+#[cold]
+#[track_caller]
+pub const fn sub() -> ! {
+    panic!("attempt to subtract with overflow")
+}
+
+#[cold]
+#[track_caller]
+pub const fn mul() -> ! {
+    panic!("attempt to multiply with overflow")
+}
+
+#[cold]
+#[track_caller]
+pub const fn div() -> ! {
+    panic!("attempt to divide with overflow")
+}
+
+#[cold]
+#[track_caller]
+pub const fn rem() -> ! {
+    panic!("attempt to calculate the remainder with overflow")
+}
+
+#[cold]
+#[track_caller]
+pub const fn neg() -> ! {
+    panic!("attempt to negate with overflow")
+}
+
+#[cold]
+#[track_caller]
+pub const fn shr() -> ! {
+    panic!("attempt to shift right with overflow")
+}
+
+#[cold]
+#[track_caller]
+pub const fn shl() -> ! {
+    panic!("attempt to shift left with overflow")
+}
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 11a53aaf122..e70d043cb2c 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -3,7 +3,7 @@ macro_rules! uint_impl {
         Self = $SelfT:ty,
         ActualT = $ActualT:ident,
         SignedT = $SignedT:ident,
-        NonZeroT = $NonZeroT:ident,
+        NonZeroT = $NonZeroT:ty,
 
         // There are all for use *only* in doc comments.
         // As such, they're all passed as literals -- passing them as a string
@@ -459,9 +459,42 @@ macro_rules! uint_impl {
         #[inline]
         pub const fn checked_add(self, rhs: Self) -> Option<Self> {
             let (a, b) = self.overflowing_add(rhs);
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
         }
 
+        /// Strict integer addition. Computes `self + rhs`, panicking
+        /// if overflow occurred.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!((", stringify!($SelfT), "::MAX - 2).strict_add(1), ", stringify!($SelfT), "::MAX - 1);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = (", stringify!($SelfT), "::MAX - 2).strict_add(3);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_add(self, rhs: Self) -> Self {
+            let (a, b) = self.overflowing_add(rhs);
+            if unlikely!(b) { overflow_panic ::add()} else {a}
+         }
+
         /// Unchecked integer addition. Computes `self + rhs`, assuming overflow
         /// cannot occur.
         ///
@@ -507,9 +540,47 @@ macro_rules! uint_impl {
         #[inline]
         pub const fn checked_add_signed(self, rhs: $SignedT) -> Option<Self> {
             let (a, b) = self.overflowing_add_signed(rhs);
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
         }
 
+        /// Strict addition with a signed integer. Computes `self + rhs`,
+        /// panicking if overflow occurred.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".strict_add_signed(2), 3);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = 1", stringify!($SelfT), ".strict_add_signed(-2);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = (", stringify!($SelfT), "::MAX - 2).strict_add_signed(3);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_add_signed(self, rhs: $SignedT) -> Self {
+            let (a, b) = self.overflowing_add_signed(rhs);
+            if unlikely!(b) { overflow_panic ::add()} else {a}
+         }
+
         /// Checked integer subtraction. Computes `self - rhs`, returning
         /// `None` if overflow occurred.
         ///
@@ -528,9 +599,42 @@ macro_rules! uint_impl {
         #[inline]
         pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
             let (a, b) = self.overflowing_sub(rhs);
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
         }
 
+        /// Strict integer subtraction. Computes `self - rhs`, panicking if
+        /// overflow occurred.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(1", stringify!($SelfT), ".strict_sub(1), 0);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = 0", stringify!($SelfT), ".strict_sub(1);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_sub(self, rhs: Self) -> Self {
+            let (a, b) = self.overflowing_sub(rhs);
+            if unlikely!(b) { overflow_panic ::sub()} else {a}
+         }
+
         /// Unchecked integer subtraction. Computes `self - rhs`, assuming overflow
         /// cannot occur.
         ///
@@ -575,9 +679,42 @@ macro_rules! uint_impl {
         #[inline]
         pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
             let (a, b) = self.overflowing_mul(rhs);
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
         }
 
+        /// Strict integer multiplication. Computes `self * rhs`, panicking if
+        /// overflow occurred.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(5", stringify!($SelfT), ".strict_mul(1), 5);")]
+        /// ```
+        ///
+        /// ``` should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = ", stringify!($SelfT), "::MAX.strict_mul(2);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_mul(self, rhs: Self) -> Self {
+            let (a, b) = self.overflowing_mul(rhs);
+            if unlikely!(b) { overflow_panic ::mul()} else {a}
+         }
+
         /// Unchecked integer multiplication. Computes `self * rhs`, assuming overflow
         /// cannot occur.
         ///
@@ -630,6 +767,34 @@ macro_rules! uint_impl {
             }
         }
 
+        /// Strict integer division. Computes `self / rhs`.
+        /// Strict division on unsigned types is just normal division.
+        /// There's no way overflow could ever happen.
+        /// This function exists, so that all operations
+        /// are accounted for in the strict operations.
+        ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is zero.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".strict_div(10), 10);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline(always)]
+        #[track_caller]
+        pub const fn strict_div(self, rhs: Self) -> Self {
+            self / rhs
+        }
+
         /// Checked Euclidean division. Computes `self.div_euclid(rhs)`, returning `None`
         /// if `rhs == 0`.
         ///
@@ -654,6 +819,36 @@ macro_rules! uint_impl {
             }
         }
 
+        /// Strict Euclidean division. Computes `self.div_euclid(rhs)`.
+        /// Strict division on unsigned types is just normal division.
+        /// There's no way overflow could ever happen.
+        /// This function exists, so that all operations
+        /// are accounted for in the strict operations.
+        /// Since, for the positive integers, all common
+        /// definitions of division are equal, this
+        /// is exactly equal to `self.strict_div(rhs)`.
+        ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is zero.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".strict_div_euclid(10), 10);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline(always)]
+        #[track_caller]
+        pub const fn strict_div_euclid(self, rhs: Self) -> Self {
+            self / rhs
+        }
 
         /// Checked integer remainder. Computes `self % rhs`, returning `None`
         /// if `rhs == 0`.
@@ -681,6 +876,35 @@ macro_rules! uint_impl {
             }
         }
 
+        /// Strict integer remainder. Computes `self % rhs`.
+        /// Strict remainder calculation on unsigned types is
+        /// just the regular remainder calculation.
+        /// There's no way overflow could ever happen.
+        /// This function exists, so that all operations
+        /// are accounted for in the strict operations.
+        ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is zero.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".strict_rem(10), 0);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline(always)]
+        #[track_caller]
+        pub const fn strict_rem(self, rhs: Self) -> Self {
+            self % rhs
+        }
+
         /// Checked Euclidean modulo. Computes `self.rem_euclid(rhs)`, returning `None`
         /// if `rhs == 0`.
         ///
@@ -705,6 +929,38 @@ macro_rules! uint_impl {
             }
         }
 
+        /// Strict Euclidean modulo. Computes `self.rem_euclid(rhs)`.
+        /// Strict modulo calculation on unsigned types is
+        /// just the regular remainder calculation.
+        /// There's no way overflow could ever happen.
+        /// This function exists, so that all operations
+        /// are accounted for in the strict operations.
+        /// Since, for the positive integers, all common
+        /// definitions of division are equal, this
+        /// is exactly equal to `self.strict_rem(rhs)`.
+        ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is zero.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".strict_rem_euclid(10), 0);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline(always)]
+        #[track_caller]
+        pub const fn strict_rem_euclid(self, rhs: Self) -> Self {
+            self % rhs
+        }
+
         /// Returns the logarithm of the number with respect to an arbitrary base,
         /// rounded down.
         ///
@@ -842,6 +1098,7 @@ macro_rules! uint_impl {
                       without modifying the original"]
         #[inline]
         pub const fn checked_ilog2(self) -> Option<u32> {
+            // FIXME: Simply use `NonZero::new` once it is actually generic.
             if let Some(x) = <$NonZeroT>::new(self) {
                 Some(x.ilog2())
             } else {
@@ -864,6 +1121,7 @@ macro_rules! uint_impl {
                       without modifying the original"]
         #[inline]
         pub const fn checked_ilog10(self) -> Option<u32> {
+            // FIXME: Simply use `NonZero::new` once it is actually generic.
             if let Some(x) = <$NonZeroT>::new(self) {
                 Some(x.ilog10())
             } else {
@@ -891,7 +1149,42 @@ macro_rules! uint_impl {
         #[inline]
         pub const fn checked_neg(self) -> Option<Self> {
             let (a, b) = self.overflowing_neg();
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
+        }
+
+        /// Strict negation. Computes `-self`, panicking unless `self ==
+        /// 0`.
+        ///
+        /// Note that negating any positive integer will overflow.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(0", stringify!($SelfT), ".strict_neg(), 0);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = 1", stringify!($SelfT), ".strict_neg();")]
+        ///
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_neg(self) -> Self {
+            let (a, b) = self.overflowing_neg();
+            if unlikely!(b) { overflow_panic::neg() } else { a }
         }
 
         /// Checked shift left. Computes `self << rhs`, returning `None`
@@ -912,7 +1205,40 @@ macro_rules! uint_impl {
         #[inline]
         pub const fn checked_shl(self, rhs: u32) -> Option<Self> {
             let (a, b) = self.overflowing_shl(rhs);
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
+        }
+
+        /// Strict shift left. Computes `self << rhs`, panicking if `rhs` is larger
+        /// than or equal to the number of bits in `self`.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(0x1", stringify!($SelfT), ".strict_shl(4), 0x10);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = 0x10", stringify!($SelfT), ".strict_shl(129);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_shl(self, rhs: u32) -> Self {
+            let (a, b) = self.overflowing_shl(rhs);
+            if unlikely!(b) { overflow_panic::shl() } else { a }
         }
 
         /// Unchecked shift left. Computes `self << rhs`, assuming that
@@ -960,7 +1286,40 @@ macro_rules! uint_impl {
         #[inline]
         pub const fn checked_shr(self, rhs: u32) -> Option<Self> {
             let (a, b) = self.overflowing_shr(rhs);
-            if unlikely!(b) {None} else {Some(a)}
+            if unlikely!(b) { None } else { Some(a) }
+        }
+
+        /// Strict shift right. Computes `self >> rhs`, panicking `rhs` is
+        /// larger than or equal to the number of bits in `self`.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(0x10", stringify!($SelfT), ".strict_shr(4), 0x1);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = 0x10", stringify!($SelfT), ".strict_shr(129);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_shr(self, rhs: u32) -> Self {
+            let (a, b) = self.overflowing_shr(rhs);
+            if unlikely!(b) { overflow_panic::shr() } else { a }
         }
 
         /// Unchecked shift right. Computes `self >> rhs`, assuming that
@@ -1029,6 +1388,55 @@ macro_rules! uint_impl {
             acc.checked_mul(base)
         }
 
+        /// Strict exponentiation. Computes `self.pow(exp)`, panicking if
+        /// overflow occurred.
+        ///
+        /// # Panics
+        ///
+        /// ## Overflow behavior
+        ///
+        /// This function will always panic on overflow, regardless of whether overflow checks are enabled.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("assert_eq!(2", stringify!($SelfT), ".strict_pow(5), 32);")]
+        /// ```
+        ///
+        /// ```should_panic
+        /// #![feature(strict_overflow_ops)]
+        #[doc = concat!("let _ = ", stringify!($SelfT), "::MAX.strict_pow(2);")]
+        /// ```
+        #[unstable(feature = "strict_overflow_ops", issue = "118260")]
+        #[rustc_const_unstable(feature = "const_strict_overflow_ops", issue = "118260")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        #[track_caller]
+        pub const fn strict_pow(self, mut exp: u32) -> Self {
+            if exp == 0 {
+                return 1;
+            }
+            let mut base = self;
+            let mut acc: Self = 1;
+
+            while exp > 1 {
+                if (exp & 1) == 1 {
+                    acc = acc.strict_mul(base);
+                }
+                exp /= 2;
+                base = base.strict_mul(base);
+            }
+            // since exp!=0, finally the exp must be 1.
+            // Deal with the final bit of the exponent separately, since
+            // squaring the base afterwards is not necessary and may cause a
+            // needless overflow.
+            acc.strict_mul(base)
+        }
+
         /// Saturating integer addition. Computes `self + rhs`, saturating at
         /// the numeric bounds instead of overflowing.
         ///
diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs
index b419a738fbe..e809273c9ed 100644
--- a/library/core/src/ops/range.rs
+++ b/library/core/src/ops/range.rs
@@ -710,7 +710,6 @@ impl<T> Bound<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(bound_map)]
     /// use std::ops::Bound::*;
     ///
     /// let bound_string = Included("Hello, World!");
@@ -719,7 +718,6 @@ impl<T> Bound<T> {
     /// ```
     ///
     /// ```
-    /// #![feature(bound_map)]
     /// use std::ops::Bound;
     /// use Bound::*;
     ///
@@ -728,7 +726,7 @@ impl<T> Bound<T> {
     /// assert_eq!(unbounded_string.map(|s| s.len()), Unbounded);
     /// ```
     #[inline]
-    #[unstable(feature = "bound_map", issue = "86026")]
+    #[stable(feature = "bound_map", since = "CURRENT_RUSTC_VERSION")]
     pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Bound<U> {
         match self {
             Unbounded => Unbounded,
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index ff435349249..ce29352ba19 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -921,14 +921,14 @@ impl<T> Option<T> {
     /// let x: Option<&str> = None;
     /// assert_eq!(x.unwrap(), "air"); // fails
     /// ```
-    #[inline]
+    #[inline(always)]
     #[track_caller]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_option", issue = "67441")]
     pub const fn unwrap(self) -> T {
         match self {
             Some(val) => val,
-            None => panic("called `Option::unwrap()` on a `None` value"),
+            None => unwrap_failed(),
         }
     }
 
@@ -1970,6 +1970,14 @@ impl<T, E> Option<Result<T, E>> {
     }
 }
 
+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
+#[cfg_attr(feature = "panic_immediate_abort", inline)]
+#[cold]
+#[track_caller]
+const fn unwrap_failed() -> ! {
+    panic("called `Option::unwrap()` on a `None` value")
+}
+
 // This is a separate function to reduce the code size of .expect() itself.
 #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
 #[cfg_attr(feature = "panic_immediate_abort", inline)]
@@ -2147,6 +2155,7 @@ impl<T: PartialEq> PartialEq for Option<T> {
 ///
 /// Once that's fixed, `Option` should go back to deriving `PartialEq`, as
 /// it used to do before <https://github.com/rust-lang/rust/pull/103556>.
+/// The comment regarding this trait on the `newtype_index` macro should be removed if this is done.
 #[unstable(feature = "spec_option_partial_eq", issue = "none", reason = "exposed only for rustc")]
 #[doc(hidden)]
 pub trait SpecOptionPartialEq: Sized {
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index 267d9b44ad7..7dee30585e9 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -1634,9 +1634,8 @@ mod prim_ref {}
 /// function pointers of varying length. Note that this is a convenience notation to avoid
 /// repetitive documentation, not valid Rust syntax.
 ///
-/// Due to a temporary restriction in Rust's type system, these traits are only implemented on
-/// functions that take 12 arguments or less, with the `"Rust"` and `"C"` ABIs. In the future, this
-/// may change:
+/// The following traits are implemented for function pointers with any number of arguments and
+/// any ABI.
 ///
 /// * [`PartialEq`]
 /// * [`Eq`]
@@ -1645,11 +1644,6 @@ mod prim_ref {}
 /// * [`Hash`]
 /// * [`Pointer`]
 /// * [`Debug`]
-///
-/// The following traits are implemented for function pointers with any number of arguments and
-/// any ABI. These traits have implementations that are automatically generated by the compiler,
-/// so are not limited by missing language features:
-///
 /// * [`Clone`]
 /// * [`Copy`]
 /// * [`Send`]
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index eff1b9b59b1..1f448984e53 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -1061,7 +1061,7 @@ impl<T, E> Result<T, E> {
     /// let x: Result<u32, &str> = Err("emergency failure");
     /// x.unwrap(); // panics with `emergency failure`
     /// ```
-    #[inline]
+    #[inline(always)]
     #[track_caller]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn unwrap(self) -> T
diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs
index ce04a9f4089..5c4f0bf9b2b 100644
--- a/library/core/src/slice/ascii.rs
+++ b/library/core/src/slice/ascii.rs
@@ -5,6 +5,7 @@ use crate::fmt::{self, Write};
 use crate::iter;
 use crate::mem;
 use crate::ops;
+use core::ascii::EscapeDefault;
 
 #[cfg(not(test))]
 impl [u8] {
@@ -253,7 +254,45 @@ impl<'a> iter::FusedIterator for EscapeAscii<'a> {}
 #[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
 impl<'a> fmt::Display for EscapeAscii<'a> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.clone().try_for_each(|b| f.write_char(b as char))
+        // disassemble iterator, including front/back parts of flatmap in case it has been partially consumed
+        let (front, slice, back) = self.clone().inner.into_parts();
+        let front = front.unwrap_or(EscapeDefault::empty());
+        let mut bytes = slice.unwrap_or_default().as_slice();
+        let back = back.unwrap_or(EscapeDefault::empty());
+
+        // usually empty, so the formatter won't have to do any work
+        for byte in front {
+            f.write_char(byte as char)?;
+        }
+
+        fn needs_escape(b: u8) -> bool {
+            b > 0x7E || b < 0x20 || b == b'\\' || b == b'\'' || b == b'"'
+        }
+
+        while bytes.len() > 0 {
+            // fast path for the printable, non-escaped subset of ascii
+            let prefix = bytes.iter().take_while(|&&b| !needs_escape(b)).count();
+            // SAFETY: prefix length was derived by counting bytes in the same splice, so it's in-bounds
+            let (prefix, remainder) = unsafe { bytes.split_at_unchecked(prefix) };
+            // SAFETY: prefix is a valid utf8 sequence, as it's a subset of ASCII
+            let prefix = unsafe { crate::str::from_utf8_unchecked(prefix) };
+
+            f.write_str(prefix)?; // the fast part
+
+            bytes = remainder;
+
+            if let Some(&b) = bytes.first() {
+                // guaranteed to be non-empty, better to write it as a str
+                f.write_str(ascii::escape_default(b).as_str())?;
+                bytes = &bytes[1..];
+            }
+        }
+
+        // also usually empty
+        for byte in back {
+            f.write_char(byte as char)?;
+        }
+        Ok(())
     }
 }
 #[stable(feature = "inherent_ascii_escape", since = "1.60.0")]
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index 3d58afd26ea..cd9e18d1a2d 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -4,7 +4,6 @@
 mod macros;
 
 use crate::cmp;
-use crate::cmp::Ordering;
 use crate::fmt;
 use crate::intrinsics::assume;
 use crate::iter::{
@@ -12,7 +11,7 @@ use crate::iter::{
 };
 use crate::marker::PhantomData;
 use crate::mem::{self, SizedTypeProperties};
-use crate::num::NonZeroUsize;
+use crate::num::{NonZero, NonZeroUsize};
 use crate::ptr::{self, invalid, invalid_mut, NonNull};
 
 use super::{from_raw_parts, from_raw_parts_mut};
@@ -133,7 +132,7 @@ iterator! {struct Iter -> *const T, &'a T, const, {/* no mut */}, as_ref, {
     fn is_sorted_by<F>(self, mut compare: F) -> bool
     where
         Self: Sized,
-        F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
+        F: FnMut(&Self::Item, &Self::Item) -> bool,
     {
         self.as_slice().is_sorted_by(|a, b| compare(&a, &b))
     }
@@ -1305,12 +1304,12 @@ forward_iterator! { RSplitNMut: T, &'a mut [T] }
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 pub struct Windows<'a, T: 'a> {
     v: &'a [T],
-    size: NonZeroUsize,
+    size: NonZero<usize>,
 }
 
 impl<'a, T: 'a> Windows<'a, T> {
     #[inline]
-    pub(super) fn new(slice: &'a [T], size: NonZeroUsize) -> Self {
+    pub(super) fn new(slice: &'a [T], size: NonZero<usize>) -> Self {
         Self { v: slice, size }
     }
 }
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 5edc89e4cb5..c191877c434 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -296,7 +296,7 @@ impl<T> [T] {
         if let [.., last] = self { Some(last) } else { None }
     }
 
-    /// Returns a mutable pointer to the last item in the slice.
+    /// Returns a mutable reference to the last item in the slice.
     ///
     /// # Examples
     ///
@@ -316,13 +316,13 @@ impl<T> [T] {
         if let [.., last] = self { Some(last) } else { None }
     }
 
-    /// Returns the first `N` elements of the slice, or `None` if it has fewer than `N` elements.
+    /// Return an array reference to the first `N` items in the slice.
+    ///
+    /// If the slice is not at least `N` in length, this will return `None`.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_first_last_chunk)]
-    ///
     /// let u = [10, 40, 30];
     /// assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
     ///
@@ -332,27 +332,26 @@ impl<T> [T] {
     /// let w: &[i32] = &[];
     /// assert_eq!(Some(&[]), w.first_chunk::<0>());
     /// ```
-    #[unstable(feature = "slice_first_last_chunk", issue = "111774")]
-    #[rustc_const_unstable(feature = "slice_first_last_chunk", issue = "111774")]
     #[inline]
+    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
     pub const fn first_chunk<const N: usize>(&self) -> Option<&[T; N]> {
         if self.len() < N {
             None
         } else {
             // SAFETY: We explicitly check for the correct number of elements,
             //   and do not let the reference outlive the slice.
-            Some(unsafe { &*(self.as_ptr() as *const [T; N]) })
+            Some(unsafe { &*(self.as_ptr().cast::<[T; N]>()) })
         }
     }
 
-    /// Returns a mutable reference to the first `N` elements of the slice,
-    /// or `None` if it has fewer than `N` elements.
+    /// Return a mutable array reference to the first `N` items in the slice.
+    ///
+    /// If the slice is not at least `N` in length, this will return `None`.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_first_last_chunk)]
-    ///
     /// let x = &mut [0, 1, 2];
     ///
     /// if let Some(first) = x.first_chunk_mut::<2>() {
@@ -360,10 +359,12 @@ impl<T> [T] {
     ///     first[1] = 4;
     /// }
     /// assert_eq!(x, &[5, 4, 2]);
+    ///
+    /// assert_eq!(None, x.first_chunk_mut::<4>());
     /// ```
-    #[unstable(feature = "slice_first_last_chunk", issue = "111774")]
-    #[rustc_const_unstable(feature = "slice_first_last_chunk", issue = "111774")]
     #[inline]
+    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_slice_first_last_chunk", issue = "111774")]
     pub const fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]> {
         if self.len() < N {
             None
@@ -371,28 +372,29 @@ impl<T> [T] {
             // SAFETY: We explicitly check for the correct number of elements,
             //   do not let the reference outlive the slice,
             //   and require exclusive access to the entire slice to mutate the chunk.
-            Some(unsafe { &mut *(self.as_mut_ptr() as *mut [T; N]) })
+            Some(unsafe { &mut *(self.as_mut_ptr().cast::<[T; N]>()) })
         }
     }
 
-    /// Returns the first `N` elements of the slice and the remainder,
-    /// or `None` if it has fewer than `N` elements.
+    /// Return an array reference to the first `N` items in the slice and the remaining slice.
+    ///
+    /// If the slice is not at least `N` in length, this will return `None`.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_first_last_chunk)]
-    ///
     /// let x = &[0, 1, 2];
     ///
     /// if let Some((first, elements)) = x.split_first_chunk::<2>() {
     ///     assert_eq!(first, &[0, 1]);
     ///     assert_eq!(elements, &[2]);
     /// }
+    ///
+    /// assert_eq!(None, x.split_first_chunk::<4>());
     /// ```
-    #[unstable(feature = "slice_first_last_chunk", issue = "111774")]
-    #[rustc_const_unstable(feature = "slice_first_last_chunk", issue = "111774")]
     #[inline]
+    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
     pub const fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])> {
         if self.len() < N {
             None
@@ -402,18 +404,18 @@ impl<T> [T] {
 
             // SAFETY: We explicitly check for the correct number of elements,
             //   and do not let the references outlive the slice.
-            Some((unsafe { &*(first.as_ptr() as *const [T; N]) }, tail))
+            Some((unsafe { &*(first.as_ptr().cast::<[T; N]>()) }, tail))
         }
     }
 
-    /// Returns a mutable reference to the first `N` elements of the slice and the remainder,
-    /// or `None` if it has fewer than `N` elements.
+    /// Return a mutable array reference to the first `N` items in the slice and the remaining
+    /// slice.
+    ///
+    /// If the slice is not at least `N` in length, this will return `None`.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_first_last_chunk)]
-    ///
     /// let x = &mut [0, 1, 2];
     ///
     /// if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
@@ -422,10 +424,12 @@ impl<T> [T] {
     ///     elements[0] = 5;
     /// }
     /// assert_eq!(x, &[3, 4, 5]);
+    ///
+    /// assert_eq!(None, x.split_first_chunk_mut::<4>());
     /// ```
-    #[unstable(feature = "slice_first_last_chunk", issue = "111774")]
-    #[rustc_const_unstable(feature = "slice_first_last_chunk", issue = "111774")]
     #[inline]
+    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_slice_first_last_chunk", issue = "111774")]
     pub const fn split_first_chunk_mut<const N: usize>(
         &mut self,
     ) -> Option<(&mut [T; N], &mut [T])> {
@@ -438,29 +442,30 @@ impl<T> [T] {
             // SAFETY: We explicitly check for the correct number of elements,
             //   do not let the reference outlive the slice,
             //   and enforce exclusive mutability of the chunk by the split.
-            Some((unsafe { &mut *(first.as_mut_ptr() as *mut [T; N]) }, tail))
+            Some((unsafe { &mut *(first.as_mut_ptr().cast::<[T; N]>()) }, tail))
         }
     }
 
-    /// Returns the last `N` elements of the slice and the remainder,
-    /// or `None` if it has fewer than `N` elements.
+    /// Return an array reference to the last `N` items in the slice and the remaining slice.
+    ///
+    /// If the slice is not at least `N` in length, this will return `None`.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_first_last_chunk)]
-    ///
     /// let x = &[0, 1, 2];
     ///
-    /// if let Some((last, elements)) = x.split_last_chunk::<2>() {
-    ///     assert_eq!(last, &[1, 2]);
+    /// if let Some((elements, last)) = x.split_last_chunk::<2>() {
     ///     assert_eq!(elements, &[0]);
+    ///     assert_eq!(last, &[1, 2]);
     /// }
+    ///
+    /// assert_eq!(None, x.split_last_chunk::<4>());
     /// ```
-    #[unstable(feature = "slice_first_last_chunk", issue = "111774")]
-    #[rustc_const_unstable(feature = "slice_first_last_chunk", issue = "111774")]
     #[inline]
-    pub const fn split_last_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])> {
+    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    pub const fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])> {
         if self.len() < N {
             None
         } else {
@@ -469,32 +474,35 @@ impl<T> [T] {
 
             // SAFETY: We explicitly check for the correct number of elements,
             //   and do not let the references outlive the slice.
-            Some((unsafe { &*(last.as_ptr() as *const [T; N]) }, init))
+            Some((init, unsafe { &*(last.as_ptr().cast::<[T; N]>()) }))
         }
     }
 
-    /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
+    /// Return a mutable array reference to the last `N` items in the slice and the remaining
+    /// slice.
+    ///
+    /// If the slice is not at least `N` in length, this will return `None`.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_first_last_chunk)]
-    ///
     /// let x = &mut [0, 1, 2];
     ///
-    /// if let Some((last, elements)) = x.split_last_chunk_mut::<2>() {
+    /// if let Some((elements, last)) = x.split_last_chunk_mut::<2>() {
     ///     last[0] = 3;
     ///     last[1] = 4;
     ///     elements[0] = 5;
     /// }
     /// assert_eq!(x, &[5, 3, 4]);
+    ///
+    /// assert_eq!(None, x.split_last_chunk_mut::<4>());
     /// ```
-    #[unstable(feature = "slice_first_last_chunk", issue = "111774")]
-    #[rustc_const_unstable(feature = "slice_first_last_chunk", issue = "111774")]
     #[inline]
+    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_slice_first_last_chunk", issue = "111774")]
     pub const fn split_last_chunk_mut<const N: usize>(
         &mut self,
-    ) -> Option<(&mut [T; N], &mut [T])> {
+    ) -> Option<(&mut [T], &mut [T; N])> {
         if self.len() < N {
             None
         } else {
@@ -504,17 +512,17 @@ impl<T> [T] {
             // SAFETY: We explicitly check for the correct number of elements,
             //   do not let the reference outlive the slice,
             //   and enforce exclusive mutability of the chunk by the split.
-            Some((unsafe { &mut *(last.as_mut_ptr() as *mut [T; N]) }, init))
+            Some((init, unsafe { &mut *(last.as_mut_ptr().cast::<[T; N]>()) }))
         }
     }
 
-    /// Returns the last element of the slice, or `None` if it is empty.
+    /// Return an array reference to the last `N` items in the slice.
+    ///
+    /// If the slice is not at least `N` in length, this will return `None`.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_first_last_chunk)]
-    ///
     /// let u = [10, 40, 30];
     /// assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
     ///
@@ -524,9 +532,9 @@ impl<T> [T] {
     /// let w: &[i32] = &[];
     /// assert_eq!(Some(&[]), w.last_chunk::<0>());
     /// ```
-    #[unstable(feature = "slice_first_last_chunk", issue = "111774")]
-    #[rustc_const_unstable(feature = "slice_first_last_chunk", issue = "111774")]
     #[inline]
+    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_slice_first_last_chunk", issue = "111774")]
     pub const fn last_chunk<const N: usize>(&self) -> Option<&[T; N]> {
         if self.len() < N {
             None
@@ -537,17 +545,17 @@ impl<T> [T] {
 
             // SAFETY: We explicitly check for the correct number of elements,
             //   and do not let the references outlive the slice.
-            Some(unsafe { &*(last.as_ptr() as *const [T; N]) })
+            Some(unsafe { &*(last.as_ptr().cast::<[T; N]>()) })
         }
     }
 
-    /// Returns a mutable pointer to the last item in the slice.
+    /// Return a mutable array reference to the last `N` items in the slice.
+    ///
+    /// If the slice is not at least `N` in length, this will return `None`.
     ///
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_first_last_chunk)]
-    ///
     /// let x = &mut [0, 1, 2];
     ///
     /// if let Some(last) = x.last_chunk_mut::<2>() {
@@ -555,10 +563,12 @@ impl<T> [T] {
     ///     last[1] = 20;
     /// }
     /// assert_eq!(x, &[0, 10, 20]);
+    ///
+    /// assert_eq!(None, x.last_chunk_mut::<4>());
     /// ```
-    #[unstable(feature = "slice_first_last_chunk", issue = "111774")]
-    #[rustc_const_unstable(feature = "slice_first_last_chunk", issue = "111774")]
     #[inline]
+    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_unstable(feature = "const_slice_first_last_chunk", issue = "111774")]
     pub const fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]> {
         if self.len() < N {
             None
@@ -570,7 +580,7 @@ impl<T> [T] {
             // SAFETY: We explicitly check for the correct number of elements,
             //   do not let the reference outlive the slice,
             //   and require exclusive access to the entire slice to mutate the chunk.
-            Some(unsafe { &mut *(last.as_mut_ptr() as *mut [T; N]) })
+            Some(unsafe { &mut *(last.as_mut_ptr().cast::<[T; N]>()) })
         }
     }
 
@@ -1859,7 +1869,6 @@ impl<T> [T] {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_slice_split_at_not_mut", since = "1.71.0")]
-    #[rustc_allow_const_fn_unstable(slice_split_at_unchecked)]
     #[inline]
     #[track_caller]
     #[must_use]
@@ -1946,7 +1955,10 @@ impl<T> [T] {
     /// }
     /// ```
     #[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")]
-    #[rustc_const_unstable(feature = "slice_split_at_unchecked", issue = "76014")]
+    #[rustc_const_stable(
+        feature = "const_slice_split_at_unchecked",
+        since = "CURRENT_RUSTC_VERSION"
+    )]
     #[inline]
     #[must_use]
     pub const unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) {
@@ -2019,164 +2031,6 @@ impl<T> [T] {
         unsafe { (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid)) }
     }
 
-    /// Divides one slice into an array and a remainder slice at an index.
-    ///
-    /// The array will contain all indices from `[0, N)` (excluding
-    /// the index `N` itself) and the slice will contain all
-    /// indices from `[N, len)` (excluding the index `len` itself).
-    ///
-    /// # Panics
-    ///
-    /// Panics if `N > len`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(split_array)]
-    ///
-    /// let v = &[1, 2, 3, 4, 5, 6][..];
-    ///
-    /// {
-    ///    let (left, right) = v.split_array_ref::<0>();
-    ///    assert_eq!(left, &[]);
-    ///    assert_eq!(right, [1, 2, 3, 4, 5, 6]);
-    /// }
-    ///
-    /// {
-    ///     let (left, right) = v.split_array_ref::<2>();
-    ///     assert_eq!(left, &[1, 2]);
-    ///     assert_eq!(right, [3, 4, 5, 6]);
-    /// }
-    ///
-    /// {
-    ///     let (left, right) = v.split_array_ref::<6>();
-    ///     assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
-    ///     assert_eq!(right, []);
-    /// }
-    /// ```
-    #[unstable(feature = "split_array", reason = "new API", issue = "90091")]
-    #[inline]
-    #[track_caller]
-    #[must_use]
-    pub fn split_array_ref<const N: usize>(&self) -> (&[T; N], &[T]) {
-        let (a, b) = self.split_at(N);
-        // SAFETY: a points to [T; N]? Yes it's [T] of length N (checked by split_at)
-        unsafe { (&*(a.as_ptr() as *const [T; N]), b) }
-    }
-
-    /// Divides one mutable slice into an array and a remainder slice at an index.
-    ///
-    /// The array will contain all indices from `[0, N)` (excluding
-    /// the index `N` itself) and the slice will contain all
-    /// indices from `[N, len)` (excluding the index `len` itself).
-    ///
-    /// # Panics
-    ///
-    /// Panics if `N > len`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(split_array)]
-    ///
-    /// let mut v = &mut [1, 0, 3, 0, 5, 6][..];
-    /// let (left, right) = v.split_array_mut::<2>();
-    /// assert_eq!(left, &mut [1, 0]);
-    /// assert_eq!(right, [3, 0, 5, 6]);
-    /// left[1] = 2;
-    /// right[1] = 4;
-    /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
-    /// ```
-    #[unstable(feature = "split_array", reason = "new API", issue = "90091")]
-    #[inline]
-    #[track_caller]
-    #[must_use]
-    pub fn split_array_mut<const N: usize>(&mut self) -> (&mut [T; N], &mut [T]) {
-        let (a, b) = self.split_at_mut(N);
-        // SAFETY: a points to [T; N]? Yes it's [T] of length N (checked by split_at_mut)
-        unsafe { (&mut *(a.as_mut_ptr() as *mut [T; N]), b) }
-    }
-
-    /// Divides one slice into an array and a remainder slice at an index from
-    /// the end.
-    ///
-    /// The slice will contain all indices from `[0, len - N)` (excluding
-    /// the index `len - N` itself) and the array will contain all
-    /// indices from `[len - N, len)` (excluding the index `len` itself).
-    ///
-    /// # Panics
-    ///
-    /// Panics if `N > len`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(split_array)]
-    ///
-    /// let v = &[1, 2, 3, 4, 5, 6][..];
-    ///
-    /// {
-    ///    let (left, right) = v.rsplit_array_ref::<0>();
-    ///    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
-    ///    assert_eq!(right, &[]);
-    /// }
-    ///
-    /// {
-    ///     let (left, right) = v.rsplit_array_ref::<2>();
-    ///     assert_eq!(left, [1, 2, 3, 4]);
-    ///     assert_eq!(right, &[5, 6]);
-    /// }
-    ///
-    /// {
-    ///     let (left, right) = v.rsplit_array_ref::<6>();
-    ///     assert_eq!(left, []);
-    ///     assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
-    /// }
-    /// ```
-    #[unstable(feature = "split_array", reason = "new API", issue = "90091")]
-    #[inline]
-    #[must_use]
-    pub fn rsplit_array_ref<const N: usize>(&self) -> (&[T], &[T; N]) {
-        assert!(N <= self.len());
-        let (a, b) = self.split_at(self.len() - N);
-        // SAFETY: b points to [T; N]? Yes it's [T] of length N (checked by split_at)
-        unsafe { (a, &*(b.as_ptr() as *const [T; N])) }
-    }
-
-    /// Divides one mutable slice into an array and a remainder slice at an
-    /// index from the end.
-    ///
-    /// The slice will contain all indices from `[0, len - N)` (excluding
-    /// the index `N` itself) and the array will contain all
-    /// indices from `[len - N, len)` (excluding the index `len` itself).
-    ///
-    /// # Panics
-    ///
-    /// Panics if `N > len`.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(split_array)]
-    ///
-    /// let mut v = &mut [1, 0, 3, 0, 5, 6][..];
-    /// let (left, right) = v.rsplit_array_mut::<4>();
-    /// assert_eq!(left, [1, 0]);
-    /// assert_eq!(right, &mut [3, 0, 5, 6]);
-    /// left[1] = 2;
-    /// right[1] = 4;
-    /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
-    /// ```
-    #[unstable(feature = "split_array", reason = "new API", issue = "90091")]
-    #[inline]
-    #[must_use]
-    pub fn rsplit_array_mut<const N: usize>(&mut self) -> (&mut [T], &mut [T; N]) {
-        assert!(N <= self.len());
-        let (a, b) = self.split_at_mut(self.len() - N);
-        // SAFETY: b points to [T; N]? Yes it's [T] of length N (checked by split_at_mut)
-        unsafe { (a, &mut *(b.as_mut_ptr() as *mut [T; N])) }
-    }
-
     /// Returns an iterator over subslices separated by elements that match
     /// `pred`. The matched element is not contained in the subslices.
     ///
@@ -4103,23 +3957,36 @@ impl<T> [T] {
     where
         T: PartialOrd,
     {
-        self.is_sorted_by(|a, b| a.partial_cmp(b))
+        self.is_sorted_by(|a, b| a <= b)
     }
 
     /// Checks if the elements of this slice are sorted using the given comparator function.
     ///
     /// Instead of using `PartialOrd::partial_cmp`, this function uses the given `compare`
-    /// function to determine the ordering of two elements. Apart from that, it's equivalent to
-    /// [`is_sorted`]; see its documentation for more information.
+    /// function to determine whether two elements are to be considered in sorted order.
     ///
-    /// [`is_sorted`]: slice::is_sorted
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(is_sorted)]
+    ///
+    /// assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
+    /// assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));
+    ///
+    /// assert!([0].is_sorted_by(|a, b| true));
+    /// assert!([0].is_sorted_by(|a, b| false));
+    ///
+    /// let empty: [i32; 0] = [];
+    /// assert!(empty.is_sorted_by(|a, b| false));
+    /// assert!(empty.is_sorted_by(|a, b| true));
+    /// ```
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
     #[must_use]
     pub fn is_sorted_by<'a, F>(&'a self, mut compare: F) -> bool
     where
-        F: FnMut(&'a T, &'a T) -> Option<Ordering>,
+        F: FnMut(&'a T, &'a T) -> bool,
     {
-        self.array_windows().all(|[a, b]| compare(a, b).map_or(false, Ordering::is_le))
+        self.array_windows().all(|[a, b]| compare(a, b))
     }
 
     /// Checks if the elements of this slice are sorted using the given key extraction function.
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 5f1f41e6865..ad8c70c6a3c 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -138,7 +138,7 @@
 //!
 //! In general, *all* atomic accesses on read-only memory are Undefined Behavior. For instance, attempting
 //! to do a `compare_exchange` that will definitely fail (making it conceptually a read-only
-//! operation) can still cause a page fault if the underlying memory page is mapped read-only. Since
+//! operation) can still cause a segmentation fault if the underlying memory page is mapped read-only. Since
 //! atomic `load`s might be implemented using compare-exchange operations, even a `load` can fault
 //! on read-only memory.
 //!
@@ -181,12 +181,13 @@
 //!     let spinlock = Arc::new(AtomicUsize::new(1));
 //!
 //!     let spinlock_clone = Arc::clone(&spinlock);
+//!
 //!     let thread = thread::spawn(move|| {
-//!         spinlock_clone.store(0, Ordering::SeqCst);
+//!         spinlock_clone.store(0, Ordering::Release);
 //!     });
 //!
 //!     // Wait for the other thread to release the lock
-//!     while spinlock.load(Ordering::SeqCst) != 0 {
+//!     while spinlock.load(Ordering::Acquire) != 0 {
 //!         hint::spin_loop();
 //!     }
 //!
@@ -203,7 +204,11 @@
 //!
 //! static GLOBAL_THREAD_COUNT: AtomicUsize = AtomicUsize::new(0);
 //!
-//! let old_thread_count = GLOBAL_THREAD_COUNT.fetch_add(1, Ordering::SeqCst);
+//! // Note that Relaxed ordering doesn't synchronize anything
+//! // except the global thread counter itself.
+//! let old_thread_count = GLOBAL_THREAD_COUNT.fetch_add(1, Ordering::Relaxed);
+//! // Note that this number may not be true at the moment of printing
+//! // because some other thread may have changed static value already.
 //! println!("live threads: {}", old_thread_count + 1);
 //! ```