1
1
//! Definitions of integer that is known not to equal zero.
2
2
3
- use crate :: cmp:: Ordering ;
3
+ use crate :: cmp:: { Ordering , PartialEq } ;
4
4
use crate :: fmt;
5
5
use crate :: hash:: { Hash , Hasher } ;
6
6
#[ cfg( bootstrap) ]
@@ -32,7 +32,10 @@ mod private {
32
32
issue = "none"
33
33
) ]
34
34
#[ 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
+ }
36
39
37
40
macro_rules! impl_zeroable_primitive {
38
41
( $primitive: ty) => {
@@ -48,7 +51,9 @@ macro_rules! impl_zeroable_primitive {
48
51
reason = "implementation detail which may disappear or be replaced at any time" ,
49
52
issue = "none"
50
53
) ]
51
- impl const ZeroablePrimitive for $primitive { }
54
+ impl const ZeroablePrimitive for $primitive {
55
+ const ZERO : Self = 0 ;
56
+ }
52
57
} ;
53
58
}
54
59
@@ -83,6 +88,79 @@ impl_zeroable_primitive!(isize);
83
88
#[ rustc_diagnostic_item = "NonZero" ]
84
89
pub struct NonZero < T : ZeroablePrimitive > ( T ) ;
85
90
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
+
86
164
macro_rules! impl_nonzero_fmt {
87
165
( #[ $stability: meta] ( $( $Trait: ident ) ,+ ) for $Ty: ident ) => {
88
166
$(
@@ -100,7 +178,6 @@ macro_rules! impl_nonzero_fmt {
100
178
macro_rules! nonzero_integer {
101
179
(
102
180
#[ $stability: meta]
103
- #[ $const_new_unchecked_stability: meta]
104
181
Self = $Ty: ident,
105
182
Primitive = $signedness: ident $Int: ident,
106
183
$( UnsignedNonZero = $UnsignedNonZero: ident, ) ?
@@ -143,74 +220,6 @@ macro_rules! nonzero_integer {
143
220
pub type $Ty = NonZero <$Int>;
144
221
145
222
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
223
/// Returns the value as a primitive type.
215
224
#[ $stability]
216
225
#[ inline]
@@ -724,7 +733,6 @@ macro_rules! nonzero_integer {
724
733
( Self = $Ty: ident, Primitive = unsigned $Int: ident $( , ) ?) => {
725
734
nonzero_integer! {
726
735
#[ stable( feature = "nonzero" , since = "1.28.0" ) ]
727
- #[ rustc_const_stable( feature = "nonzero" , since = "1.28.0" ) ]
728
736
Self = $Ty,
729
737
Primitive = unsigned $Int,
730
738
UnsignedPrimitive = $Int,
@@ -735,7 +743,6 @@ macro_rules! nonzero_integer {
735
743
( Self = $Ty: ident, Primitive = signed $Int: ident, $( $rest: tt) * ) => {
736
744
nonzero_integer! {
737
745
#[ stable( feature = "signed_nonzero" , since = "1.34.0" ) ]
738
- #[ rustc_const_stable( feature = "signed_nonzero" , since = "1.34.0" ) ]
739
746
Self = $Ty,
740
747
Primitive = signed $Int,
741
748
$( $rest) *
0 commit comments