11//! Definitions of integer that is known not to equal zero.
22
3- use crate :: cmp:: Ordering ;
3+ use crate :: cmp:: { Ordering , PartialEq } ;
44use crate :: fmt;
55use crate :: hash:: { Hash , Hasher } ;
66#[ cfg( bootstrap) ]
@@ -32,7 +32,10 @@ mod private {
3232 issue = "none"
3333) ]
3434#[ const_trait]
35- pub trait ZeroablePrimitive : Sized + Copy + private:: Sealed { }
35+ pub trait ZeroablePrimitive : Sized + Copy + private:: Sealed {
36+ #[ doc( hidden) ]
37+ const ZERO : Self ;
38+ }
3639
3740macro_rules! impl_zeroable_primitive {
3841 ( $primitive: ty) => {
@@ -48,7 +51,9 @@ macro_rules! impl_zeroable_primitive {
4851 reason = "implementation detail which may disappear or be replaced at any time" ,
4952 issue = "none"
5053 ) ]
51- impl const ZeroablePrimitive for $primitive { }
54+ impl const ZeroablePrimitive for $primitive {
55+ const ZERO : Self = 0 ;
56+ }
5257 } ;
5358}
5459
@@ -83,6 +88,79 @@ impl_zeroable_primitive!(isize);
8388#[ rustc_diagnostic_item = "NonZero" ]
8489pub struct NonZero < T : ZeroablePrimitive > ( T ) ;
8590
91+ impl < T > NonZero < T >
92+ where
93+ T : ZeroablePrimitive + PartialEq ,
94+ {
95+ /// Creates a non-zero if the given value is not zero.
96+ #[ stable( feature = "nonzero" , since = "1.28.0" ) ]
97+ #[ rustc_const_stable( feature = "const_nonzero_int_methods" , since = "1.47.0" ) ]
98+ #[ must_use]
99+ #[ inline]
100+ pub const fn new ( n : T ) -> Option < Self > {
101+ if n == T :: ZERO {
102+ return None ;
103+ }
104+
105+ // SAFETY: We just checked that there's no `0`.
106+ Some ( unsafe { Self ( n) } )
107+ }
108+
109+ /// Creates a non-zero without checking whether the value is non-zero.
110+ /// This results in undefined behaviour if the value is zero.
111+ ///
112+ /// # Safety
113+ ///
114+ /// The value must not be zero.
115+ #[ stable( feature = "nonzero" , since = "1.28.0" ) ]
116+ #[ rustc_const_stable( feature = "nonzero" , since = "1.28.0" ) ]
117+ #[ must_use]
118+ #[ inline]
119+ pub const unsafe fn new_unchecked ( n : T ) -> Self {
120+ crate :: panic:: debug_assert_nounwind!(
121+ n != T :: ZERO ,
122+ "NonZero::new_unchecked requires a non-zero argument" ,
123+ ) ;
124+
125+ // SAFETY: This is guaranteed to be safe by the caller.
126+ unsafe { Self ( n) }
127+ }
128+
129+ /// Converts a reference to a non-zero mutable reference
130+ /// if the referenced value is not zero.
131+ #[ unstable( feature = "nonzero_from_mut" , issue = "106290" ) ]
132+ #[ must_use]
133+ #[ inline]
134+ pub fn from_mut ( n : & mut T ) -> Option < & mut Self > {
135+ // SAFETY: Self is `repr(transparent)`, and the value is non-zero.
136+ // As long as the returned reference is alive,
137+ // the user cannot `*n = 0` directly.
138+ ( * n != T :: ZERO ) . then ( || unsafe { & mut * ( n as * mut T as * mut Self ) } )
139+ }
140+
141+ /// Converts a mutable reference to a non-zero mutable reference
142+ /// without checking whether the referenced value is non-zero.
143+ /// This results in undefined behavior if the referenced value is zero.
144+ ///
145+ /// # Safety
146+ ///
147+ /// The referenced value must not be zero.
148+ #[ unstable( feature = "nonzero_from_mut" , issue = "106290" ) ]
149+ #[ must_use]
150+ #[ inline]
151+ pub unsafe fn from_mut_unchecked ( n : & mut T ) -> & mut Self {
152+ // SAFETY: Self is repr(transparent), and the value is assumed to be non-zero.
153+ unsafe {
154+ let n_alias = & mut * n;
155+ core:: intrinsics:: assert_unsafe_precondition!(
156+ "NonZero::from_mut_unchecked requires the argument to dereference as non-zero" ,
157+ [ T : ZeroablePrimitive + PartialEq ] ( n_alias: & mut T ) => * n_alias != T :: ZERO
158+ ) ;
159+ & mut * ( n as * mut T as * mut Self )
160+ }
161+ }
162+ }
163+
86164macro_rules! impl_nonzero_fmt {
87165 ( #[ $stability: meta] ( $( $Trait: ident ) ,+ ) for $Ty: ident ) => {
88166 $(
@@ -100,7 +178,6 @@ macro_rules! impl_nonzero_fmt {
100178macro_rules! nonzero_integer {
101179 (
102180 #[ $stability: meta]
103- #[ $const_new_unchecked_stability: meta]
104181 Self = $Ty: ident,
105182 Primitive = $signedness: ident $Int: ident,
106183 $( UnsignedNonZero = $UnsignedNonZero: ident, ) ?
@@ -143,74 +220,6 @@ macro_rules! nonzero_integer {
143220 pub type $Ty = NonZero <$Int>;
144221
145222 impl $Ty {
146- /// Creates a non-zero without checking whether the value is non-zero.
147- /// This results in undefined behaviour if the value is zero.
148- ///
149- /// # Safety
150- ///
151- /// The value must not be zero.
152- #[ $stability]
153- #[ $const_new_unchecked_stability]
154- #[ must_use]
155- #[ inline]
156- pub const unsafe fn new_unchecked( n: $Int) -> Self {
157- crate :: panic:: debug_assert_nounwind!(
158- n != 0 ,
159- concat!( stringify!( $Ty) , "::new_unchecked requires a non-zero argument" )
160- ) ;
161- // SAFETY: this is guaranteed to be safe by the caller.
162- unsafe {
163- Self ( n)
164- }
165- }
166-
167- /// Creates a non-zero if the given value is not zero.
168- #[ $stability]
169- #[ rustc_const_stable( feature = "const_nonzero_int_methods" , since = "1.47.0" ) ]
170- #[ must_use]
171- #[ inline]
172- pub const fn new( n: $Int) -> Option <Self > {
173- if n != 0 {
174- // SAFETY: we just checked that there's no `0`
175- Some ( unsafe { Self ( n) } )
176- } else {
177- None
178- }
179- }
180-
181- /// Converts a primitive mutable reference to a non-zero mutable reference
182- /// without checking whether the referenced value is non-zero.
183- /// This results in undefined behavior if `*n` is zero.
184- ///
185- /// # Safety
186- /// The referenced value must not be currently zero.
187- #[ unstable( feature = "nonzero_from_mut" , issue = "106290" ) ]
188- #[ must_use]
189- #[ inline]
190- pub unsafe fn from_mut_unchecked( n: & mut $Int) -> & mut Self {
191- // SAFETY: Self is repr(transparent), and the value is assumed to be non-zero.
192- unsafe {
193- let n_alias = & mut * n;
194- core:: intrinsics:: assert_unsafe_precondition!(
195- concat!( stringify!( $Ty) , "::from_mut_unchecked requires the argument to dereference as non-zero" ) ,
196- ( n_alias: & mut $Int) => * n_alias != 0
197- ) ;
198- & mut * ( n as * mut $Int as * mut Self )
199- }
200- }
201-
202- /// Converts a primitive mutable reference to a non-zero mutable reference
203- /// if the referenced integer is not zero.
204- #[ unstable( feature = "nonzero_from_mut" , issue = "106290" ) ]
205- #[ must_use]
206- #[ inline]
207- pub fn from_mut( n: & mut $Int) -> Option <& mut Self > {
208- // SAFETY: Self is repr(transparent), and the value is non-zero.
209- // As long as the returned reference is alive,
210- // the user cannot `*n = 0` directly.
211- ( * n != 0 ) . then( || unsafe { & mut * ( n as * mut $Int as * mut Self ) } )
212- }
213-
214223 /// Returns the value as a primitive type.
215224 #[ $stability]
216225 #[ inline]
@@ -724,7 +733,6 @@ macro_rules! nonzero_integer {
724733 ( Self = $Ty: ident, Primitive = unsigned $Int: ident $( , ) ?) => {
725734 nonzero_integer! {
726735 #[ stable( feature = "nonzero" , since = "1.28.0" ) ]
727- #[ rustc_const_stable( feature = "nonzero" , since = "1.28.0" ) ]
728736 Self = $Ty,
729737 Primitive = unsigned $Int,
730738 UnsignedPrimitive = $Int,
@@ -735,7 +743,6 @@ macro_rules! nonzero_integer {
735743 ( Self = $Ty: ident, Primitive = signed $Int: ident, $( $rest: tt) * ) => {
736744 nonzero_integer! {
737745 #[ stable( feature = "signed_nonzero" , since = "1.34.0" ) ]
738- #[ rustc_const_stable( feature = "signed_nonzero" , since = "1.34.0" ) ]
739746 Self = $Ty,
740747 Primitive = signed $Int,
741748 $( $rest) *
0 commit comments