@@ -26,167 +26,167 @@ macro_rules! nonzero_integer {
26
26
(
27
27
#[ $stability: meta] #[ $const_new_unchecked_stability: meta] $Ty: ident( $Int: ty) ;
28
28
) => {
29
- /// An integer that is known not to equal zero.
29
+ /// An integer that is known not to equal zero.
30
+ ///
31
+ /// This enables some memory layout optimization.
32
+ #[ doc = concat!( "For example, `Option<" , stringify!( $Ty) , ">` is the same size as `" , stringify!( $Int) , "`:" ) ]
33
+ ///
34
+ /// ```rust
35
+ /// use std::mem::size_of;
36
+ #[ doc = concat!( "assert_eq!(size_of::<Option<core::num::" , stringify!( $Ty) , ">>(), size_of::<" , stringify!( $Int) , ">());" ) ]
37
+ /// ```
38
+ ///
39
+ /// # Layout
40
+ ///
41
+ #[ doc = concat!( "`" , stringify!( $Ty) , "` is guaranteed to have the same layout and bit validity as `" , stringify!( $Int) , "`" ) ]
42
+ /// with the exception that `0` is not a valid instance.
43
+ #[ doc = concat!( "`Option<" , stringify!( $Ty) , ">` is guaranteed to be compatible with `" , stringify!( $Int) , "`," ) ]
44
+ /// including in FFI.
45
+ ///
46
+ /// Thanks to the [null pointer optimization],
47
+ #[ doc = concat!( "`" , stringify!( $Ty) , "` and `Option<" , stringify!( $Ty) , ">`" ) ]
48
+ /// are guaranteed to have the same size and alignment:
49
+ ///
50
+ /// ```
51
+ /// # use std::mem::{size_of, align_of};
52
+ #[ doc = concat!( "use std::num::" , stringify!( $Ty) , ";" ) ]
53
+ ///
54
+ #[ doc = concat!( "assert_eq!(size_of::<" , stringify!( $Ty) , ">(), size_of::<Option<" , stringify!( $Ty) , ">>());" ) ]
55
+ #[ doc = concat!( "assert_eq!(align_of::<" , stringify!( $Ty) , ">(), align_of::<Option<" , stringify!( $Ty) , ">>());" ) ]
56
+ /// ```
57
+ ///
58
+ /// [null pointer optimization]: crate::option#representation
59
+ #[ $stability]
60
+ #[ derive( Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
61
+ #[ repr( transparent) ]
62
+ #[ rustc_layout_scalar_valid_range_start( 1 ) ]
63
+ #[ rustc_nonnull_optimization_guaranteed]
64
+ #[ rustc_diagnostic_item = stringify!( $Ty) ]
65
+ pub struct $Ty( $Int) ;
66
+
67
+ impl $Ty {
68
+ /// Creates a non-zero without checking whether the value is non-zero.
69
+ /// This results in undefined behaviour if the value is zero.
30
70
///
31
- /// This enables some memory layout optimization.
32
- #[ doc = concat!( "For example, `Option<" , stringify!( $Ty) , ">` is the same size as `" , stringify!( $Int) , "`:" ) ]
71
+ /// # Safety
33
72
///
34
- /// ```rust
35
- /// use std::mem::size_of;
36
- #[ doc = concat!( "assert_eq!(size_of::<Option<core::num::" , stringify!( $Ty) , ">>(), size_of::<" , stringify!( $Int) , ">());" ) ]
37
- /// ```
38
- ///
39
- /// # Layout
40
- ///
41
- #[ doc = concat!( "`" , stringify!( $Ty) , "` is guaranteed to have the same layout and bit validity as `" , stringify!( $Int) , "`" ) ]
42
- /// with the exception that `0` is not a valid instance.
43
- #[ doc = concat!( "`Option<" , stringify!( $Ty) , ">` is guaranteed to be compatible with `" , stringify!( $Int) , "`," ) ]
44
- /// including in FFI.
45
- ///
46
- /// Thanks to the [null pointer optimization],
47
- #[ doc = concat!( "`" , stringify!( $Ty) , "` and `Option<" , stringify!( $Ty) , ">`" ) ]
48
- /// are guaranteed to have the same size and alignment:
49
- ///
50
- /// ```
51
- /// # use std::mem::{size_of, align_of};
52
- #[ doc = concat!( "use std::num::" , stringify!( $Ty) , ";" ) ]
53
- ///
54
- #[ doc = concat!( "assert_eq!(size_of::<" , stringify!( $Ty) , ">(), size_of::<Option<" , stringify!( $Ty) , ">>());" ) ]
55
- #[ doc = concat!( "assert_eq!(align_of::<" , stringify!( $Ty) , ">(), align_of::<Option<" , stringify!( $Ty) , ">>());" ) ]
56
- /// ```
57
- ///
58
- /// [null pointer optimization]: crate::option#representation
73
+ /// The value must not be zero.
59
74
#[ $stability]
60
- #[ derive( Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
61
- #[ repr( transparent) ]
62
- #[ rustc_layout_scalar_valid_range_start( 1 ) ]
63
- #[ rustc_nonnull_optimization_guaranteed]
64
- #[ rustc_diagnostic_item = stringify!( $Ty) ]
65
- pub struct $Ty( $Int) ;
66
-
67
- impl $Ty {
68
- /// Creates a non-zero without checking whether the value is non-zero.
69
- /// This results in undefined behaviour if the value is zero.
70
- ///
71
- /// # Safety
72
- ///
73
- /// The value must not be zero.
74
- #[ $stability]
75
- #[ $const_new_unchecked_stability]
76
- #[ must_use]
77
- #[ inline]
78
- pub const unsafe fn new_unchecked( n: $Int) -> Self {
79
- crate :: panic:: debug_assert_nounwind!(
80
- n != 0 ,
81
- concat!( stringify!( $Ty) , "::new_unchecked requires a non-zero argument" )
82
- ) ;
83
- // SAFETY: this is guaranteed to be safe by the caller.
84
- unsafe {
85
- Self ( n)
86
- }
87
- }
88
-
89
- /// Creates a non-zero if the given value is not zero.
90
- #[ $stability]
91
- #[ rustc_const_stable( feature = "const_nonzero_int_methods" , since = "1.47.0" ) ]
92
- #[ must_use]
93
- #[ inline]
94
- pub const fn new( n: $Int) -> Option <Self > {
95
- if n != 0 {
96
- // SAFETY: we just checked that there's no `0`
97
- Some ( unsafe { Self ( n) } )
98
- } else {
99
- None
100
- }
75
+ #[ $const_new_unchecked_stability]
76
+ #[ must_use]
77
+ #[ inline]
78
+ pub const unsafe fn new_unchecked( n: $Int) -> Self {
79
+ crate :: panic:: debug_assert_nounwind!(
80
+ n != 0 ,
81
+ concat!( stringify!( $Ty) , "::new_unchecked requires a non-zero argument" )
82
+ ) ;
83
+ // SAFETY: this is guaranteed to be safe by the caller.
84
+ unsafe {
85
+ Self ( n)
101
86
}
87
+ }
102
88
103
- /// Returns the value as a primitive type.
104
- #[ $stability]
105
- #[ inline]
106
- #[ rustc_const_stable( feature = "const_nonzero_get" , since = "1.34.0" ) ]
107
- pub const fn get( self ) -> $Int {
108
- // FIXME: Remove this after LLVM supports `!range` metadata for function
109
- // arguments https://github.com/llvm/llvm-project/issues/76628
110
- //
111
- // Rustc can set range metadata only if it loads `self` from
112
- // memory somewhere. If the value of `self` was from by-value argument
113
- // of some not-inlined function, LLVM don't have range metadata
114
- // to understand that the value cannot be zero.
115
-
116
- // SAFETY: It is an invariant of this type.
117
- unsafe {
118
- intrinsics:: assume( self . 0 != 0 ) ;
119
- }
120
- self . 0
89
+ /// Creates a non-zero if the given value is not zero.
90
+ #[ $stability]
91
+ #[ rustc_const_stable( feature = "const_nonzero_int_methods" , since = "1.47.0" ) ]
92
+ #[ must_use]
93
+ #[ inline]
94
+ pub const fn new( n: $Int) -> Option <Self > {
95
+ if n != 0 {
96
+ // SAFETY: we just checked that there's no `0`
97
+ Some ( unsafe { Self ( n) } )
98
+ } else {
99
+ None
121
100
}
122
-
123
101
}
124
102
125
- #[ stable( feature = "from_nonzero" , since = "1.31.0" ) ]
126
- impl From <$Ty> for $Int {
127
- #[ doc = concat!( "Converts a `" , stringify!( $Ty) , "` into an `" , stringify!( $Int) , "`" ) ]
128
- #[ inline]
129
- fn from( nonzero: $Ty) -> Self {
130
- // Call nonzero to keep information range information
131
- // from get method.
132
- nonzero. get( )
103
+ /// Returns the value as a primitive type.
104
+ #[ $stability]
105
+ #[ inline]
106
+ #[ rustc_const_stable( feature = "const_nonzero_get" , since = "1.34.0" ) ]
107
+ pub const fn get( self ) -> $Int {
108
+ // FIXME: Remove this after LLVM supports `!range` metadata for function
109
+ // arguments https://github.com/llvm/llvm-project/issues/76628
110
+ //
111
+ // Rustc can set range metadata only if it loads `self` from
112
+ // memory somewhere. If the value of `self` was from by-value argument
113
+ // of some not-inlined function, LLVM don't have range metadata
114
+ // to understand that the value cannot be zero.
115
+
116
+ // SAFETY: It is an invariant of this type.
117
+ unsafe {
118
+ intrinsics:: assume( self . 0 != 0 ) ;
133
119
}
120
+ self . 0
134
121
}
135
122
136
- #[ stable( feature = "nonzero_bitor" , since = "1.45.0" ) ]
137
- impl BitOr for $Ty {
138
- type Output = Self ;
139
- #[ inline]
140
- fn bitor( self , rhs: Self ) -> Self :: Output {
141
- // SAFETY: since `self` and `rhs` are both nonzero, the
142
- // result of the bitwise-or will be nonzero.
143
- unsafe { $Ty:: new_unchecked( self . get( ) | rhs. get( ) ) }
144
- }
123
+ }
124
+
125
+ #[ stable( feature = "from_nonzero" , since = "1.31.0" ) ]
126
+ impl From <$Ty> for $Int {
127
+ #[ doc = concat!( "Converts a `" , stringify!( $Ty) , "` into an `" , stringify!( $Int) , "`" ) ]
128
+ #[ inline]
129
+ fn from( nonzero: $Ty) -> Self {
130
+ // Call nonzero to keep information range information
131
+ // from get method.
132
+ nonzero. get( )
145
133
}
134
+ }
146
135
147
- #[ stable( feature = "nonzero_bitor" , since = "1.45.0" ) ]
148
- impl BitOr <$Int> for $Ty {
149
- type Output = Self ;
150
- #[ inline]
151
- fn bitor( self , rhs: $Int) -> Self :: Output {
152
- // SAFETY: since `self` is nonzero, the result of the
153
- // bitwise-or will be nonzero regardless of the value of
154
- // `rhs`.
155
- unsafe { $Ty:: new_unchecked( self . get( ) | rhs) }
156
- }
136
+ #[ stable( feature = "nonzero_bitor" , since = "1.45.0" ) ]
137
+ impl BitOr for $Ty {
138
+ type Output = Self ;
139
+ #[ inline]
140
+ fn bitor( self , rhs: Self ) -> Self :: Output {
141
+ // SAFETY: since `self` and `rhs` are both nonzero, the
142
+ // result of the bitwise-or will be nonzero.
143
+ unsafe { $Ty:: new_unchecked( self . get( ) | rhs. get( ) ) }
157
144
}
145
+ }
158
146
159
- #[ stable( feature = "nonzero_bitor" , since = "1.45.0" ) ]
160
- impl BitOr <$Ty> for $Int {
161
- type Output = $Ty;
162
- #[ inline]
163
- fn bitor( self , rhs: $Ty) -> Self :: Output {
164
- // SAFETY: since `rhs` is nonzero, the result of the
165
- // bitwise-or will be nonzero regardless of the value of
166
- // `self`.
167
- unsafe { $Ty:: new_unchecked( self | rhs. get( ) ) }
168
- }
147
+ #[ stable( feature = "nonzero_bitor" , since = "1.45.0" ) ]
148
+ impl BitOr <$Int> for $Ty {
149
+ type Output = Self ;
150
+ #[ inline]
151
+ fn bitor( self , rhs: $Int) -> Self :: Output {
152
+ // SAFETY: since `self` is nonzero, the result of the
153
+ // bitwise-or will be nonzero regardless of the value of
154
+ // `rhs`.
155
+ unsafe { $Ty:: new_unchecked( self . get( ) | rhs) }
169
156
}
157
+ }
170
158
171
- #[ stable( feature = "nonzero_bitor" , since = "1.45.0" ) ]
172
- impl BitOrAssign for $Ty {
173
- #[ inline]
174
- fn bitor_assign( & mut self , rhs: Self ) {
175
- * self = * self | rhs;
176
- }
159
+ #[ stable( feature = "nonzero_bitor" , since = "1.45.0" ) ]
160
+ impl BitOr <$Ty> for $Int {
161
+ type Output = $Ty;
162
+ #[ inline]
163
+ fn bitor( self , rhs: $Ty) -> Self :: Output {
164
+ // SAFETY: since `rhs` is nonzero, the result of the
165
+ // bitwise-or will be nonzero regardless of the value of
166
+ // `self`.
167
+ unsafe { $Ty:: new_unchecked( self | rhs. get( ) ) }
177
168
}
169
+ }
178
170
179
- #[ stable( feature = "nonzero_bitor" , since = "1.45.0" ) ]
180
- impl BitOrAssign <$Int> for $Ty {
181
- #[ inline]
182
- fn bitor_assign( & mut self , rhs: $Int) {
183
- * self = * self | rhs;
184
- }
171
+ #[ stable( feature = "nonzero_bitor" , since = "1.45.0" ) ]
172
+ impl BitOrAssign for $Ty {
173
+ #[ inline]
174
+ fn bitor_assign( & mut self , rhs: Self ) {
175
+ * self = * self | rhs;
185
176
}
177
+ }
186
178
187
- impl_nonzero_fmt! {
188
- #[ $stability] ( Debug , Display , Binary , Octal , LowerHex , UpperHex ) for $Ty
179
+ #[ stable( feature = "nonzero_bitor" , since = "1.45.0" ) ]
180
+ impl BitOrAssign <$Int> for $Ty {
181
+ #[ inline]
182
+ fn bitor_assign( & mut self , rhs: $Int) {
183
+ * self = * self | rhs;
189
184
}
185
+ }
186
+
187
+ impl_nonzero_fmt! {
188
+ #[ $stability] ( Debug , Display , Binary , Octal , LowerHex , UpperHex ) for $Ty
189
+ }
190
190
} ;
191
191
}
192
192
0 commit comments