Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2160,6 +2160,7 @@ macro_rules! int_impl {
without modifying the original"]
#[inline(always)]
#[rustc_allow_const_fn_unstable(unchecked_shifts)]
#[ensures(|result| *result == self << (rhs & (Self::BITS - 1)))]
pub const fn wrapping_shl(self, rhs: u32) -> Self {
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
// out of bounds
Expand Down
39 changes: 39 additions & 0 deletions library/core/src/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1645,6 +1645,19 @@ mod verify {
}
}

// Verify `wrapping_{shl, shr}` which internally uses `unchecked_{shl,shr}`
macro_rules! generate_wrapping_shift_harness {
($type:ty, $method:ident, $harness_name:ident) => {
#[kani::proof_for_contract($type::$method)]
pub fn $harness_name() {
let num1: $type = kani::any::<$type>();
let num2: u32 = kani::any::<u32>();

let _ = num1.$method(num2);
}
}
}

macro_rules! generate_unchecked_neg_harness {
($type:ty, $harness_name:ident) => {
#[kani::proof_for_contract($type::unchecked_neg)]
Expand Down Expand Up @@ -1849,4 +1862,30 @@ mod verify {
generate_unchecked_math_harness!(u64, unchecked_sub, checked_unchecked_sub_u64);
generate_unchecked_math_harness!(u128, unchecked_sub, checked_unchecked_sub_u128);
generate_unchecked_math_harness!(usize, unchecked_sub, checked_unchecked_sub_usize);

// `wrapping_shl` proofs
//
// Target types:
// i{8,16,32,64,128,size} and u{8,16,32,64,128,size} -- 12 types in total
//
// Target contracts:
// #[requires(rhs < Self::BITS)]
// #[ensures(|result| *result == self << (rhs & (Self::BITS - 1)))]
//
// Target function:
// pub const fn wrapping_shl(self, rhs: u32) -> Self {
//
// This function performs an panic-free bitwise left shift operation.
generate_wrapping_shift_harness!(i8, wrapping_shl, checked_wrapping_shl_i8);
generate_wrapping_shift_harness!(i16, wrapping_shl, checked_wrapping_shl_i16);
generate_wrapping_shift_harness!(i32, wrapping_shl, checked_wrapping_shl_i32);
generate_wrapping_shift_harness!(i64, wrapping_shl, checked_wrapping_shl_i64);
generate_wrapping_shift_harness!(i128, wrapping_shl, checked_wrapping_shl_i128);
generate_wrapping_shift_harness!(isize, wrapping_shl, checked_wrapping_shl_isize);
generate_wrapping_shift_harness!(u8, wrapping_shl, checked_wrapping_shl_u8);
generate_wrapping_shift_harness!(u16, wrapping_shl, checked_wrapping_shl_u16);
generate_wrapping_shift_harness!(u32, wrapping_shl, checked_wrapping_shl_u32);
generate_wrapping_shift_harness!(u64, wrapping_shl, checked_wrapping_shl_u64);
generate_wrapping_shift_harness!(u128, wrapping_shl, checked_wrapping_shl_u128);
generate_wrapping_shift_harness!(usize, wrapping_shl, checked_wrapping_shl_usize);
}
1 change: 1 addition & 0 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2138,6 +2138,7 @@ macro_rules! uint_impl {
without modifying the original"]
#[inline(always)]
#[rustc_allow_const_fn_unstable(unchecked_shifts)]
#[ensures(|result| *result == self << (rhs & (Self::BITS - 1)))]
pub const fn wrapping_shl(self, rhs: u32) -> Self {
// SAFETY: the masking by the bitsize of the type ensures that we do not shift
// out of bounds
Expand Down
Loading