@@ -8,7 +8,9 @@ use crate::ops::{BitOr, BitOrAssign, Div, DivAssign, Neg, Rem, RemAssign};
88use crate :: panic:: { RefUnwindSafe , UnwindSafe } ;
99use crate :: str:: FromStr ;
1010use crate :: { fmt, intrinsics, ptr, ub_checks} ;
11-
11+ use safety:: { ensures, requires} ;
12+ #[ cfg( kani) ]
13+ use crate :: kani;
1214/// A marker trait for primitive types which can be zero.
1315///
1416/// This is an implementation detail for <code>[NonZero]\<T></code> which may disappear or be replaced at any time.
@@ -364,6 +366,27 @@ where
364366 #[ rustc_const_stable( feature = "nonzero" , since = "1.28.0" ) ]
365367 #[ must_use]
366368 #[ 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+ } ) ]
367390 pub const unsafe fn new_unchecked ( n : T ) -> Self {
368391 match Self :: new ( n) {
369392 Some ( n) => n,
@@ -2159,3 +2182,36 @@ nonzero_integer! {
21592182 swapped = "0x5634129078563412" ,
21602183 reversed = "0x6a2c48091e6a2c48" ,
21612184}
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