@@ -35,7 +35,7 @@ mod private {
3535pub trait ZeroablePrimitive : Sized + Copy + private:: Sealed { }
3636
3737macro_rules! impl_zeroable_primitive {
38- ( $NonZero : ident ( $ primitive: ty ) ) => {
38+ ( $primitive: ty) => {
3939 #[ unstable(
4040 feature = "nonzero_internals" ,
4141 reason = "implementation detail which may disappear or be replaced at any time" ,
@@ -52,18 +52,18 @@ macro_rules! impl_zeroable_primitive {
5252 } ;
5353}
5454
55- impl_zeroable_primitive ! ( NonZeroU8 ( u8 ) ) ;
56- impl_zeroable_primitive ! ( NonZeroU16 ( u16 ) ) ;
57- impl_zeroable_primitive ! ( NonZeroU32 ( u32 ) ) ;
58- impl_zeroable_primitive ! ( NonZeroU64 ( u64 ) ) ;
59- impl_zeroable_primitive ! ( NonZeroU128 ( u128 ) ) ;
60- impl_zeroable_primitive ! ( NonZeroUsize ( usize ) ) ;
61- impl_zeroable_primitive ! ( NonZeroI8 ( i8 ) ) ;
62- impl_zeroable_primitive ! ( NonZeroI16 ( i16 ) ) ;
63- impl_zeroable_primitive ! ( NonZeroI32 ( i32 ) ) ;
64- impl_zeroable_primitive ! ( NonZeroI64 ( i64 ) ) ;
65- impl_zeroable_primitive ! ( NonZeroI128 ( i128 ) ) ;
66- impl_zeroable_primitive ! ( NonZeroIsize ( isize ) ) ;
55+ impl_zeroable_primitive ! ( u8 ) ;
56+ impl_zeroable_primitive ! ( u16 ) ;
57+ impl_zeroable_primitive ! ( u32 ) ;
58+ impl_zeroable_primitive ! ( u64 ) ;
59+ impl_zeroable_primitive ! ( u128 ) ;
60+ impl_zeroable_primitive ! ( usize ) ;
61+ impl_zeroable_primitive ! ( i8 ) ;
62+ impl_zeroable_primitive ! ( i16 ) ;
63+ impl_zeroable_primitive ! ( i32 ) ;
64+ impl_zeroable_primitive ! ( i64 ) ;
65+ impl_zeroable_primitive ! ( i128 ) ;
66+ impl_zeroable_primitive ! ( isize ) ;
6767
6868/// A value that is known not to equal zero.
6969///
@@ -83,6 +83,90 @@ impl_zeroable_primitive!(NonZeroIsize(isize));
8383#[ rustc_diagnostic_item = "NonZero" ]
8484pub struct NonZero < T : ZeroablePrimitive > ( T ) ;
8585
86+ impl < T > NonZero < T >
87+ where
88+ T : ZeroablePrimitive ,
89+ {
90+ /// Creates a non-zero if the given value is not zero.
91+ #[ stable( feature = "nonzero" , since = "1.28.0" ) ]
92+ #[ rustc_const_stable( feature = "const_nonzero_int_methods" , since = "1.47.0" ) ]
93+ #[ rustc_allow_const_fn_unstable( const_refs_to_cell) ]
94+ #[ must_use]
95+ #[ inline]
96+ pub const fn new ( n : T ) -> Option < Self > {
97+ // SAFETY: Memory layout optimization guarantees that `Option<NonZero<T>>` has
98+ // the same layout and size as `T`, with `0` representing `None`.
99+ unsafe { crate :: mem:: transmute_copy ( & n) }
100+ }
101+
102+ /// Creates a non-zero without checking whether the value is non-zero.
103+ /// This results in undefined behaviour if the value is zero.
104+ ///
105+ /// # Safety
106+ ///
107+ /// The value must not be zero.
108+ #[ stable( feature = "nonzero" , since = "1.28.0" ) ]
109+ #[ rustc_const_stable( feature = "nonzero" , since = "1.28.0" ) ]
110+ #[ must_use]
111+ #[ inline]
112+ pub const unsafe fn new_unchecked ( n : T ) -> Self {
113+ match Self :: new ( n) {
114+ Some ( n) => n,
115+ None => {
116+ // SAFETY: The caller guarantees that `n` is non-zero, so this is unreachable.
117+ unsafe {
118+ crate :: intrinsics:: assert_unsafe_precondition!(
119+ "NonZero::new_unchecked requires the argument to be non-zero" ,
120+ ( ) => false
121+ ) ;
122+
123+ crate :: hint:: unreachable_unchecked ( )
124+ }
125+ }
126+ }
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: Memory layout optimization guarantees that `Option<NonZero<T>>` has
136+ // the same layout and size as `T`, with `0` representing `None`.
137+ let opt_n = unsafe { & mut * ( n as * mut T as * mut Option < Self > ) } ;
138+
139+ opt_n. as_mut ( )
140+ }
141+
142+ /// Converts a mutable reference to a non-zero mutable reference
143+ /// without checking whether the referenced value is non-zero.
144+ /// This results in undefined behavior if the referenced value is zero.
145+ ///
146+ /// # Safety
147+ ///
148+ /// The referenced value must not be zero.
149+ #[ unstable( feature = "nonzero_from_mut" , issue = "106290" ) ]
150+ #[ must_use]
151+ #[ inline]
152+ pub unsafe fn from_mut_unchecked ( n : & mut T ) -> & mut Self {
153+ match Self :: from_mut ( n) {
154+ Some ( n) => n,
155+ None => {
156+ // SAFETY: The caller guarantees that `n` references a value that is non-zero, so this is unreachable.
157+ unsafe {
158+ crate :: intrinsics:: assert_unsafe_precondition!(
159+ "NonZero::from_mut_unchecked requires the argument to dereference as non-zero" ,
160+ ( ) => false
161+ ) ;
162+
163+ crate :: hint:: unreachable_unchecked ( )
164+ }
165+ }
166+ }
167+ }
168+ }
169+
86170macro_rules! impl_nonzero_fmt {
87171 ( #[ $stability: meta] ( $( $Trait: ident ) ,+ ) for $Ty: ident ) => {
88172 $(
@@ -100,7 +184,6 @@ macro_rules! impl_nonzero_fmt {
100184macro_rules! nonzero_integer {
101185 (
102186 #[ $stability: meta]
103- #[ $const_new_unchecked_stability: meta]
104187 Self = $Ty: ident,
105188 Primitive = $signedness: ident $Int: ident,
106189 $( UnsignedNonZero = $UnsignedNonZero: ident, ) ?
@@ -143,74 +226,6 @@ macro_rules! nonzero_integer {
143226 pub type $Ty = NonZero <$Int>;
144227
145228 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-
214229 /// Returns the value as a primitive type.
215230 #[ $stability]
216231 #[ inline]
@@ -724,7 +739,6 @@ macro_rules! nonzero_integer {
724739 ( Self = $Ty: ident, Primitive = unsigned $Int: ident $( , ) ?) => {
725740 nonzero_integer! {
726741 #[ stable( feature = "nonzero" , since = "1.28.0" ) ]
727- #[ rustc_const_stable( feature = "nonzero" , since = "1.28.0" ) ]
728742 Self = $Ty,
729743 Primitive = unsigned $Int,
730744 UnsignedPrimitive = $Int,
@@ -735,7 +749,6 @@ macro_rules! nonzero_integer {
735749 ( Self = $Ty: ident, Primitive = signed $Int: ident, $( $rest: tt) * ) => {
736750 nonzero_integer! {
737751 #[ stable( feature = "signed_nonzero" , since = "1.34.0" ) ]
738- #[ rustc_const_stable( feature = "signed_nonzero" , since = "1.34.0" ) ]
739752 Self = $Ty,
740753 Primitive = signed $Int,
741754 $( $rest) *
0 commit comments