@@ -35,7 +35,7 @@ mod private {
35
35
pub trait ZeroablePrimitive : Sized + Copy + private:: Sealed { }
36
36
37
37
macro_rules! impl_zeroable_primitive {
38
- ( $NonZero : ident ( $ primitive: ty ) ) => {
38
+ ( $primitive: ty) => {
39
39
#[ unstable(
40
40
feature = "nonzero_internals" ,
41
41
reason = "implementation detail which may disappear or be replaced at any time" ,
@@ -52,18 +52,18 @@ macro_rules! impl_zeroable_primitive {
52
52
} ;
53
53
}
54
54
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 ) ;
67
67
68
68
/// A value that is known not to equal zero.
69
69
///
@@ -83,6 +83,90 @@ impl_zeroable_primitive!(NonZeroIsize(isize));
83
83
#[ rustc_diagnostic_item = "NonZero" ]
84
84
pub struct NonZero < T : ZeroablePrimitive > ( T ) ;
85
85
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
+
86
170
macro_rules! impl_nonzero_fmt {
87
171
( #[ $stability: meta] ( $( $Trait: ident ) ,+ ) for $Ty: ident ) => {
88
172
$(
@@ -100,7 +184,6 @@ macro_rules! impl_nonzero_fmt {
100
184
macro_rules! nonzero_integer {
101
185
(
102
186
#[ $stability: meta]
103
- #[ $const_new_unchecked_stability: meta]
104
187
Self = $Ty: ident,
105
188
Primitive = $signedness: ident $Int: ident,
106
189
$( UnsignedNonZero = $UnsignedNonZero: ident, ) ?
@@ -143,74 +226,6 @@ macro_rules! nonzero_integer {
143
226
pub type $Ty = NonZero <$Int>;
144
227
145
228
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
-
214
229
/// Returns the value as a primitive type.
215
230
#[ $stability]
216
231
#[ inline]
@@ -724,7 +739,6 @@ macro_rules! nonzero_integer {
724
739
( Self = $Ty: ident, Primitive = unsigned $Int: ident $( , ) ?) => {
725
740
nonzero_integer! {
726
741
#[ stable( feature = "nonzero" , since = "1.28.0" ) ]
727
- #[ rustc_const_stable( feature = "nonzero" , since = "1.28.0" ) ]
728
742
Self = $Ty,
729
743
Primitive = unsigned $Int,
730
744
UnsignedPrimitive = $Int,
@@ -735,7 +749,6 @@ macro_rules! nonzero_integer {
735
749
( Self = $Ty: ident, Primitive = signed $Int: ident, $( $rest: tt) * ) => {
736
750
nonzero_integer! {
737
751
#[ stable( feature = "signed_nonzero" , since = "1.34.0" ) ]
738
- #[ rustc_const_stable( feature = "signed_nonzero" , since = "1.34.0" ) ]
739
752
Self = $Ty,
740
753
Primitive = signed $Int,
741
754
$( $rest) *
0 commit comments