@@ -1009,6 +1009,15 @@ macro_rules! nonzero_integer {
1009
1009
#[ must_use = "this returns the result of the operation, \
1010
1010
without modifying the original"]
1011
1011
#[ inline]
1012
+ #[ requires( {
1013
+ let ( result, overflow) = self . get( ) . overflowing_mul( other. get( ) ) ;
1014
+ !overflow // Precondition to ensure no overflow occurs during multiplication
1015
+ } ) ]
1016
+ #[ ensures( |result: & Self | {
1017
+ // Ensure the resulting value is the expected product
1018
+ let ( expected_result, _) = self . get( ) . overflowing_mul( other. get( ) ) ;
1019
+ result. get( ) == expected_result
1020
+ } ) ]
1012
1021
pub const unsafe fn unchecked_mul( self , other: Self ) -> Self {
1013
1022
// SAFETY: The caller ensures there is no overflow.
1014
1023
unsafe { Self :: new_unchecked( self . get( ) . unchecked_mul( other. get( ) ) ) }
@@ -1371,6 +1380,15 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
1371
1380
#[ must_use = "this returns the result of the operation, \
1372
1381
without modifying the original"]
1373
1382
#[ inline]
1383
+ #[ requires( {
1384
+ let ( result, overflow) = self . get( ) . overflowing_add( other) ;
1385
+ !overflow // Precondition: no overflow can occur
1386
+ } ) ]
1387
+ #[ ensures( |result: & Self | {
1388
+ // Postcondition: the result matches the expected addition
1389
+ let ( expected_result, _) = self . get( ) . overflowing_add( other) ;
1390
+ result. get( ) == expected_result
1391
+ } ) ]
1374
1392
pub const unsafe fn unchecked_add( self , other: $Int) -> Self {
1375
1393
// SAFETY: The caller ensures there is no overflow.
1376
1394
unsafe { Self :: new_unchecked( self . get( ) . unchecked_add( other) ) }
@@ -2214,4 +2232,28 @@ mod verify {
2214
2232
nonzero_check ! ( u64 , core:: num:: NonZeroU64 , nonzero_check_new_unchecked_for_u64) ;
2215
2233
nonzero_check ! ( u128 , core:: num:: NonZeroU128 , nonzero_check_new_unchecked_for_u128) ;
2216
2234
nonzero_check ! ( usize , core:: num:: NonZeroUsize , nonzero_check_new_unchecked_for_usize) ;
2217
- }
2235
+
2236
+ #[ kani:: proof_for_contract( i8 :: unchecked_mul) ]
2237
+ fn nonzero_unchecked_mul ( ) {
2238
+ let x: NonZeroI8 = kani:: any ( ) ;
2239
+ let y: NonZeroI8 = kani:: any ( ) ;
2240
+
2241
+ // Check the precondition to assume no overflow
2242
+ let ( result, overflow) = x. get ( ) . overflowing_mul ( y. get ( ) ) ;
2243
+ kani:: assume ( !overflow) ; // Ensure the multiplication does not overflow
2244
+
2245
+ unsafe {
2246
+ let _ = x. unchecked_mul ( y) ;
2247
+ }
2248
+ }
2249
+
2250
+ #[ kani:: proof_for_contract( i8 :: unchecked_add) ]
2251
+ fn nonzero_unchecked_add ( ) {
2252
+ let x: i8 = kani:: any ( ) ;
2253
+ let y: i8 = kani:: any ( ) ;
2254
+ unsafe {
2255
+ let _ = x. unchecked_add ( y) ; // Call the unchecked function
2256
+ }
2257
+ }
2258
+
2259
+ }
0 commit comments