33use crate :: cmp:: Ordering ;
44use crate :: fmt;
55use crate :: hash:: { Hash , Hasher } ;
6- use crate :: marker:: StructuralPartialEq ;
6+ use crate :: marker:: { StructuralEq , StructuralPartialEq } ;
77use crate :: ops:: { BitOr , BitOrAssign , Div , Neg , Rem } ;
88use crate :: str:: FromStr ;
99
@@ -67,24 +67,40 @@ impl_zeroable_primitive!(NonZeroI64(i64));
6767impl_zeroable_primitive ! ( NonZeroI128 ( i128 ) ) ;
6868impl_zeroable_primitive ! ( NonZeroIsize ( isize ) ) ;
6969
70- #[ unstable(
71- feature = "nonzero_internals" ,
72- reason = "implementation detail which may disappear or be replaced at any time" ,
73- issue = "none"
74- ) ]
75- pub ( crate ) type NonZero < T > = <T as ZeroablePrimitive >:: NonZero ;
70+ /// A value that is known not to equal zero.
71+ ///
72+ /// This enables some memory layout optimization.
73+ /// For example, `Option<NonZero<u32>>` is the same size as `u32`:
74+ ///
75+ /// ```rust
76+ /// #![feature(generic_nonzero)]
77+ ///
78+ /// use core::mem::size_of;
79+ /// assert_eq!(size_of::<Option<core::num::NonZero<u32>>>(), size_of::<u32>());
80+ /// ```
81+ #[ unstable( feature = "generic_nonzero" , issue = "82363" ) ]
82+ #[ repr( transparent) ]
83+ #[ rustc_layout_scalar_valid_range_start( 1 ) ]
84+ #[ rustc_nonnull_optimization_guaranteed]
85+ #[ rustc_diagnostic_item = "NonZero" ]
86+ pub struct NonZero < T : ZeroablePrimitive > ( T ) ;
7687
7788macro_rules! impl_nonzero_traits {
7889 ( #[ $stability: meta] $Ty: ty) => {
7990 #[ $stability]
8091 impl Clone for $Ty {
8192 #[ inline]
8293 fn clone( & self ) -> Self {
94+ let value = self . 0 ;
95+
8396 // SAFETY: The contained value is non-zero.
84- unsafe { Self ( self . 0 ) }
97+ unsafe { Self ( value ) }
8598 }
8699 }
87100
101+ #[ $stability]
102+ impl Copy for $Ty { }
103+
88104 #[ $stability]
89105 impl PartialEq for $Ty {
90106 #[ inline]
@@ -101,6 +117,12 @@ macro_rules! impl_nonzero_traits {
101117 #[ unstable( feature = "structural_match" , issue = "31434" ) ]
102118 impl StructuralPartialEq for $Ty { }
103119
120+ #[ $stability]
121+ impl Eq for $Ty { }
122+
123+ #[ unstable( feature = "structural_match" , issue = "31434" ) ]
124+ impl StructuralEq for $Ty { }
125+
104126 #[ $stability]
105127 impl PartialOrd for $Ty {
106128 #[ inline]
@@ -225,12 +247,7 @@ macro_rules! nonzero_integer {
225247 ///
226248 /// [null pointer optimization]: crate::option#representation
227249 #[ $stability]
228- #[ derive( Copy , Eq ) ]
229- #[ repr( transparent) ]
230- #[ rustc_layout_scalar_valid_range_start( 1 ) ]
231- #[ rustc_nonnull_optimization_guaranteed]
232- #[ rustc_diagnostic_item = stringify!( $Ty) ]
233- pub struct $Ty( $Int) ;
250+ pub type $Ty = NonZero <$Int>;
234251
235252 impl_nonzero_traits!( #[ $stability] $Ty) ;
236253
0 commit comments