Skip to content

Commit 9b91b9f

Browse files
author
Ubuntu
committed
Unchecked Add and Mul: Init
1 parent dcbf4f5 commit 9b91b9f

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

library/core/src/num/nonzero.rs

+43-1
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,15 @@ macro_rules! nonzero_integer {
10091009
#[must_use = "this returns the result of the operation, \
10101010
without modifying the original"]
10111011
#[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+
})]
10121021
pub const unsafe fn unchecked_mul(self, other: Self) -> Self {
10131022
// SAFETY: The caller ensures there is no overflow.
10141023
unsafe { Self::new_unchecked(self.get().unchecked_mul(other.get())) }
@@ -1371,6 +1380,15 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
13711380
#[must_use = "this returns the result of the operation, \
13721381
without modifying the original"]
13731382
#[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+
})]
13741392
pub const unsafe fn unchecked_add(self, other: $Int) -> Self {
13751393
// SAFETY: The caller ensures there is no overflow.
13761394
unsafe { Self::new_unchecked(self.get().unchecked_add(other)) }
@@ -2214,4 +2232,28 @@ mod verify {
22142232
nonzero_check!(u64, core::num::NonZeroU64, nonzero_check_new_unchecked_for_u64);
22152233
nonzero_check!(u128, core::num::NonZeroU128, nonzero_check_new_unchecked_for_u128);
22162234
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

Comments
 (0)