Add assert_unsafe_precondition to unchecked_{add,sub,neg,mul,shl,shr} methods
This commit is contained in:
parent
9c8a58fdb8
commit
72b7171031
23 changed files with 289 additions and 193 deletions
|
@ -488,9 +488,19 @@ macro_rules! int_impl {
|
|||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
|
||||
// SAFETY: the caller must uphold the safety contract for
|
||||
// `unchecked_add`.
|
||||
unsafe { intrinsics::unchecked_add(self, rhs) }
|
||||
assert_unsafe_precondition!(
|
||||
check_language_ub,
|
||||
concat!(stringify!($SelfT), "::unchecked_add cannot overflow"),
|
||||
(
|
||||
lhs: $SelfT = self,
|
||||
rhs: $SelfT = rhs,
|
||||
) => !lhs.overflowing_add(rhs).1,
|
||||
);
|
||||
|
||||
// SAFETY: this is guaranteed to be safe by the caller.
|
||||
unsafe {
|
||||
intrinsics::unchecked_add(self, rhs)
|
||||
}
|
||||
}
|
||||
|
||||
/// Checked addition with an unsigned integer. Computes `self + rhs`,
|
||||
|
@ -630,9 +640,19 @@ macro_rules! int_impl {
|
|||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self {
|
||||
// SAFETY: the caller must uphold the safety contract for
|
||||
// `unchecked_sub`.
|
||||
unsafe { intrinsics::unchecked_sub(self, rhs) }
|
||||
assert_unsafe_precondition!(
|
||||
check_language_ub,
|
||||
concat!(stringify!($SelfT), "::unchecked_sub cannot overflow"),
|
||||
(
|
||||
lhs: $SelfT = self,
|
||||
rhs: $SelfT = rhs,
|
||||
) => !lhs.overflowing_sub(rhs).1,
|
||||
);
|
||||
|
||||
// SAFETY: this is guaranteed to be safe by the caller.
|
||||
unsafe {
|
||||
intrinsics::unchecked_sub(self, rhs)
|
||||
}
|
||||
}
|
||||
|
||||
/// Checked subtraction with an unsigned integer. Computes `self - rhs`,
|
||||
|
@ -772,9 +792,19 @@ macro_rules! int_impl {
|
|||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self {
|
||||
// SAFETY: the caller must uphold the safety contract for
|
||||
// `unchecked_mul`.
|
||||
unsafe { intrinsics::unchecked_mul(self, rhs) }
|
||||
assert_unsafe_precondition!(
|
||||
check_language_ub,
|
||||
concat!(stringify!($SelfT), "::unchecked_mul cannot overflow"),
|
||||
(
|
||||
lhs: $SelfT = self,
|
||||
rhs: $SelfT = rhs,
|
||||
) => !lhs.overflowing_mul(rhs).1,
|
||||
);
|
||||
|
||||
// SAFETY: this is guaranteed to be safe by the caller.
|
||||
unsafe {
|
||||
intrinsics::unchecked_mul(self, rhs)
|
||||
}
|
||||
}
|
||||
|
||||
/// Checked integer division. Computes `self / rhs`, returning `None` if `rhs == 0`
|
||||
|
@ -1111,9 +1141,22 @@ macro_rules! int_impl {
|
|||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn unchecked_neg(self) -> Self {
|
||||
// SAFETY: the caller must uphold the safety contract for
|
||||
// `unchecked_neg`.
|
||||
unsafe { intrinsics::unchecked_sub(0, self) }
|
||||
// ICE resolved by #125184 isn't in bootstrap compiler
|
||||
#[cfg(not(bootstrap))]
|
||||
{
|
||||
assert_unsafe_precondition!(
|
||||
check_language_ub,
|
||||
concat!(stringify!($SelfT), "::unchecked_neg cannot overflow"),
|
||||
(
|
||||
lhs: $SelfT = self,
|
||||
) => !lhs.overflowing_neg().1,
|
||||
);
|
||||
}
|
||||
|
||||
// SAFETY: this is guaranteed to be safe by the caller.
|
||||
unsafe {
|
||||
intrinsics::unchecked_sub(0, self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Strict negation. Computes `-self`, panicking if `self == MIN`.
|
||||
|
@ -1234,9 +1277,19 @@ macro_rules! int_impl {
|
|||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
|
||||
// SAFETY: the caller must uphold the safety contract for
|
||||
// `unchecked_shl`.
|
||||
unsafe { intrinsics::unchecked_shl(self, rhs) }
|
||||
assert_unsafe_precondition!(
|
||||
check_language_ub,
|
||||
concat!(stringify!($SelfT), "::unchecked_shl cannot overflow"),
|
||||
(
|
||||
rhs: u32 = rhs,
|
||||
bits: u32 = Self::BITS,
|
||||
) => rhs < bits,
|
||||
);
|
||||
|
||||
// SAFETY: this is guaranteed to be safe by the caller.
|
||||
unsafe {
|
||||
intrinsics::unchecked_shl(self, rhs)
|
||||
}
|
||||
}
|
||||
|
||||
/// Checked shift right. Computes `self >> rhs`, returning `None` if `rhs` is
|
||||
|
@ -1323,9 +1376,19 @@ macro_rules! int_impl {
|
|||
#[inline(always)]
|
||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||
pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
|
||||
// SAFETY: the caller must uphold the safety contract for
|
||||
// `unchecked_shr`.
|
||||
unsafe { intrinsics::unchecked_shr(self, rhs) }
|
||||
assert_unsafe_precondition!(
|
||||
check_language_ub,
|
||||
concat!(stringify!($SelfT), "::unchecked_shr cannot overflow"),
|
||||
(
|
||||
rhs: u32 = rhs,
|
||||
bits: u32 = Self::BITS,
|
||||
) => rhs < bits,
|
||||
);
|
||||
|
||||
// SAFETY: this is guaranteed to be safe by the caller.
|
||||
unsafe {
|
||||
intrinsics::unchecked_shr(self, rhs)
|
||||
}
|
||||
}
|
||||
|
||||
/// Checked absolute value. Computes `self.abs()`, returning `None` if
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue