@@ -8,7 +8,9 @@ use crate::ops::{BitOr, BitOrAssign, Div, DivAssign, Neg, Rem, RemAssign};
8
8
use crate :: panic:: { RefUnwindSafe , UnwindSafe } ;
9
9
use crate :: str:: FromStr ;
10
10
use crate :: { fmt, intrinsics, ptr, ub_checks} ;
11
-
11
+ use safety:: { ensures, requires} ;
12
+ #[ cfg( kani) ]
13
+ use crate :: kani;
12
14
/// A marker trait for primitive types which can be zero.
13
15
///
14
16
/// This is an implementation detail for <code>[NonZero]\<T></code> which may disappear or be replaced at any time.
@@ -364,6 +366,27 @@ where
364
366
#[ rustc_const_stable( feature = "nonzero" , since = "1.28.0" ) ]
365
367
#[ must_use]
366
368
#[ inline]
369
+ // #[rustc_allow_const_fn_unstable(const_refs_to_cell)] enables byte-level
370
+ // comparisons within const functions. This is needed here to validate the
371
+ // contents of `T` by converting a pointer to a `u8` slice for our `requires`
372
+ // and `ensures` checks.
373
+ #[ rustc_allow_const_fn_unstable( const_refs_to_cell) ]
374
+ #[ requires( {
375
+ let size = core:: mem:: size_of:: <T >( ) ;
376
+ let ptr = & n as * const T as * const u8 ;
377
+ let slice = unsafe { core:: slice:: from_raw_parts( ptr, size) } ;
378
+ !slice. iter( ) . all( |& byte| byte == 0 )
379
+ } ) ]
380
+ #[ ensures( |result: & Self |{
381
+ let size = core:: mem:: size_of:: <T >( ) ;
382
+ let n_ptr: * const T = & n;
383
+ let result_inner: T = result. get( ) ;
384
+ let result_ptr: * const T = & result_inner;
385
+ let n_slice = unsafe { core:: slice:: from_raw_parts( n_ptr as * const u8 , size) } ;
386
+ let result_slice = unsafe { core:: slice:: from_raw_parts( result_ptr as * const u8 , size) } ;
387
+
388
+ n_slice == result_slice
389
+ } ) ]
367
390
pub const unsafe fn new_unchecked ( n : T ) -> Self {
368
391
match Self :: new ( n) {
369
392
Some ( n) => n,
@@ -2159,3 +2182,36 @@ nonzero_integer! {
2159
2182
swapped = "0x5634129078563412" ,
2160
2183
reversed = "0x6a2c48091e6a2c48" ,
2161
2184
}
2185
+
2186
+ #[ unstable( feature="kani" , issue="none" ) ]
2187
+ #[ cfg( kani) ]
2188
+ mod verify {
2189
+ use super :: * ;
2190
+
2191
+ macro_rules! nonzero_check {
2192
+ ( $t: ty, $nonzero_type: ty, $nonzero_check_new_unchecked_for: ident) => {
2193
+ #[ kani:: proof_for_contract( NonZero :: new_unchecked) ]
2194
+ pub fn $nonzero_check_new_unchecked_for( ) {
2195
+ let x: $t = kani:: any( ) ; // Generates a symbolic value of the provided type
2196
+
2197
+ unsafe {
2198
+ <$nonzero_type>:: new_unchecked( x) ; // Calls NonZero::new_unchecked for the specified NonZero type
2199
+ }
2200
+ }
2201
+ } ;
2202
+ }
2203
+
2204
+ // Use the macro to generate different versions of the function for multiple types
2205
+ nonzero_check ! ( i8 , core:: num:: NonZeroI8 , nonzero_check_new_unchecked_for_i8) ;
2206
+ nonzero_check ! ( i16 , core:: num:: NonZeroI16 , nonzero_check_new_unchecked_for_16) ;
2207
+ nonzero_check ! ( i32 , core:: num:: NonZeroI32 , nonzero_check_new_unchecked_for_32) ;
2208
+ nonzero_check ! ( i64 , core:: num:: NonZeroI64 , nonzero_check_new_unchecked_for_64) ;
2209
+ nonzero_check ! ( i128 , core:: num:: NonZeroI128 , nonzero_check_new_unchecked_for_128) ;
2210
+ nonzero_check ! ( isize , core:: num:: NonZeroIsize , nonzero_check_new_unchecked_for_isize) ;
2211
+ nonzero_check ! ( u8 , core:: num:: NonZeroU8 , nonzero_check_new_unchecked_for_u8) ;
2212
+ nonzero_check ! ( u16 , core:: num:: NonZeroU16 , nonzero_check_new_unchecked_for_u16) ;
2213
+ nonzero_check ! ( u32 , core:: num:: NonZeroU32 , nonzero_check_new_unchecked_for_u32) ;
2214
+ nonzero_check ! ( u64 , core:: num:: NonZeroU64 , nonzero_check_new_unchecked_for_u64) ;
2215
+ nonzero_check ! ( u128 , core:: num:: NonZeroU128 , nonzero_check_new_unchecked_for_u128) ;
2216
+ nonzero_check ! ( usize , core:: num:: NonZeroUsize , nonzero_check_new_unchecked_for_usize) ;
2217
+ }
0 commit comments