33use crate :: cmp:: Ordering ;
44use crate :: fmt;
55use crate :: hash:: { Hash , Hasher } ;
6+ #[ cfg( bootstrap) ]
7+ use crate :: marker:: StructuralEq ;
68use crate :: marker:: StructuralPartialEq ;
79use crate :: ops:: { BitOr , BitOrAssign , Div , Neg , Rem } ;
810use crate :: str:: FromStr ;
@@ -30,9 +32,7 @@ mod private {
3032 issue = "none"
3133) ]
3234#[ const_trait]
33- pub trait ZeroablePrimitive : Sized + Copy + private:: Sealed {
34- type NonZero ;
35- }
35+ pub trait ZeroablePrimitive : Sized + Copy + private:: Sealed { }
3636
3737macro_rules! impl_zeroable_primitive {
3838 ( $NonZero: ident ( $primitive: ty ) ) => {
@@ -48,9 +48,7 @@ macro_rules! impl_zeroable_primitive {
4848 reason = "implementation detail which may disappear or be replaced at any time" ,
4949 issue = "none"
5050 ) ]
51- impl const ZeroablePrimitive for $primitive {
52- type NonZero = $NonZero;
53- }
51+ impl const ZeroablePrimitive for $primitive { }
5452 } ;
5553}
5654
@@ -67,12 +65,23 @@ impl_zeroable_primitive!(NonZeroI64(i64));
6765impl_zeroable_primitive ! ( NonZeroI128 ( i128 ) ) ;
6866impl_zeroable_primitive ! ( NonZeroIsize ( isize ) ) ;
6967
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 ;
68+ /// A value that is known not to equal zero.
69+ ///
70+ /// This enables some memory layout optimization.
71+ /// For example, `Option<NonZero<u32>>` is the same size as `u32`:
72+ ///
73+ /// ```
74+ /// #![feature(generic_nonzero)]
75+ /// use core::mem::size_of;
76+ ///
77+ /// assert_eq!(size_of::<Option<core::num::NonZero<u32>>>(), size_of::<u32>());
78+ /// ```
79+ #[ unstable( feature = "generic_nonzero" , issue = "120257" ) ]
80+ #[ repr( transparent) ]
81+ #[ rustc_layout_scalar_valid_range_start( 1 ) ]
82+ #[ rustc_nonnull_optimization_guaranteed]
83+ #[ rustc_diagnostic_item = "NonZero" ]
84+ pub struct NonZero < T : ZeroablePrimitive > ( T ) ;
7685
7786macro_rules! impl_nonzero_fmt {
7887 ( #[ $stability: meta] ( $( $Trait: ident ) ,+ ) for $Ty: ident ) => {
@@ -131,12 +140,7 @@ macro_rules! nonzero_integer {
131140 ///
132141 /// [null pointer optimization]: crate::option#representation
133142 #[ $stability]
134- #[ derive( Copy , Eq ) ]
135- #[ repr( transparent) ]
136- #[ rustc_layout_scalar_valid_range_start( 1 ) ]
137- #[ rustc_nonnull_optimization_guaranteed]
138- #[ rustc_diagnostic_item = stringify!( $Ty) ]
139- pub struct $Ty( $Int) ;
143+ pub type $Ty = NonZero <$Int>;
140144
141145 impl $Ty {
142146 /// Creates a non-zero without checking whether the value is non-zero.
@@ -543,6 +547,9 @@ macro_rules! nonzero_integer {
543547 }
544548 }
545549
550+ #[ $stability]
551+ impl Copy for $Ty { }
552+
546553 #[ $stability]
547554 impl PartialEq for $Ty {
548555 #[ inline]
@@ -559,6 +566,13 @@ macro_rules! nonzero_integer {
559566 #[ unstable( feature = "structural_match" , issue = "31434" ) ]
560567 impl StructuralPartialEq for $Ty { }
561568
569+ #[ $stability]
570+ impl Eq for $Ty { }
571+
572+ #[ unstable( feature = "structural_match" , issue = "31434" ) ]
573+ #[ cfg( bootstrap) ]
574+ impl StructuralEq for $Ty { }
575+
562576 #[ $stability]
563577 impl PartialOrd for $Ty {
564578 #[ inline]
0 commit comments