@@ -26,167 +26,167 @@ macro_rules! nonzero_integer {
2626 (
2727 #[ $stability: meta] #[ $const_new_unchecked_stability: meta] $Ty: ident( $Int: ty) ;
2828 ) => {
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.
3070 ///
31- /// This enables some memory layout optimization.
32- #[ doc = concat!( "For example, `Option<" , stringify!( $Ty) , ">` is the same size as `" , stringify!( $Int) , "`:" ) ]
71+ /// # Safety
3372 ///
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.
5974 #[ $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)
10186 }
87+ }
10288
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
121100 }
122-
123101 }
124102
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 ) ;
133119 }
120+ self . 0
134121 }
135122
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( )
145133 }
134+ }
146135
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( ) ) }
157144 }
145+ }
158146
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) }
169156 }
157+ }
170158
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( ) ) }
177168 }
169+ }
178170
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;
185176 }
177+ }
186178
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;
189184 }
185+ }
186+
187+ impl_nonzero_fmt! {
188+ #[ $stability] ( Debug , Display , Binary , Octal , LowerHex , UpperHex ) for $Ty
189+ }
190190 } ;
191191}
192192
0 commit comments