about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/num/nonzero.rs109
1 files changed, 101 insertions, 8 deletions
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index bda691b16d4..2a81146601b 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -1,6 +1,9 @@
 //! Definitions of integer that is known not to equal zero.
 
+use crate::cmp::Ordering;
 use crate::fmt;
+use crate::hash::{Hash, Hasher};
+use crate::marker::StructuralPartialEq;
 use crate::ops::{BitOr, BitOrAssign, Div, Neg, Rem};
 use crate::str::FromStr;
 
@@ -31,13 +34,6 @@ 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(
@@ -71,6 +67,13 @@ impl_zeroable_primitive!(NonZeroI64(i64));
 impl_zeroable_primitive!(NonZeroI128(i128));
 impl_zeroable_primitive!(NonZeroIsize(isize));
 
+#[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_nonzero_fmt {
     ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
         $(
@@ -128,7 +131,7 @@ macro_rules! nonzero_integer {
         ///
         /// [null pointer optimization]: crate::option#representation
         #[$stability]
-        #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+        #[derive(Copy, Eq)]
         #[repr(transparent)]
         #[rustc_layout_scalar_valid_range_start(1)]
         #[rustc_nonnull_optimization_guaranteed]
@@ -494,6 +497,96 @@ macro_rules! nonzero_integer {
             }
         }
 
+        #[$stability]
+        impl Clone for $Ty {
+            #[inline]
+            fn clone(&self) -> Self {
+                // SAFETY: The contained value is non-zero.
+                unsafe { Self(self.0) }
+            }
+        }
+
+        #[$stability]
+        impl PartialEq for $Ty {
+            #[inline]
+            fn eq(&self, other: &Self) -> bool {
+                self.0 == other.0
+            }
+
+            #[inline]
+            fn ne(&self, other: &Self) -> bool {
+                self.0 != other.0
+            }
+        }
+
+        #[unstable(feature = "structural_match", issue = "31434")]
+        impl StructuralPartialEq for $Ty {}
+
+        #[$stability]
+        impl PartialOrd for $Ty {
+            #[inline]
+            fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+                self.0.partial_cmp(&other.0)
+            }
+
+            #[inline]
+            fn lt(&self, other: &Self) -> bool {
+                self.0 < other.0
+            }
+
+            #[inline]
+            fn le(&self, other: &Self) -> bool {
+                self.0 <= other.0
+            }
+
+            #[inline]
+            fn gt(&self, other: &Self) -> bool {
+                self.0 > other.0
+            }
+
+            #[inline]
+            fn ge(&self, other: &Self) -> bool {
+                self.0 >= other.0
+            }
+        }
+
+        #[$stability]
+        impl Ord for $Ty {
+            #[inline]
+            fn cmp(&self, other: &Self) -> Ordering {
+                self.0.cmp(&other.0)
+            }
+
+            #[inline]
+            fn max(self, other: Self) -> Self {
+                // SAFETY: The maximum of two non-zero values is still non-zero.
+                unsafe { Self(self.0.max(other.0)) }
+            }
+
+            #[inline]
+            fn min(self, other: Self) -> Self {
+                // SAFETY: The minimum of two non-zero values is still non-zero.
+                unsafe { Self(self.0.min(other.0)) }
+            }
+
+            #[inline]
+            fn clamp(self, min: Self, max: Self) -> Self {
+                // SAFETY: A non-zero value clamped between two non-zero values is still non-zero.
+                unsafe { Self(self.0.clamp(min.0, max.0)) }
+            }
+        }
+
+        #[$stability]
+        impl Hash for $Ty {
+            #[inline]
+            fn hash<H>(&self, state: &mut H)
+            where
+                H: Hasher,
+            {
+                self.0.hash(state)
+            }
+        }
+
         #[stable(feature = "from_nonzero", since = "1.31.0")]
         impl From<$Ty> for $Int {
             #[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")]