Skip to content

Commit 2c9342d

Browse files
added unchecked_rem for signed and unsigned types
1 parent df83987 commit 2c9342d

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

library/core/src/num/int_macros.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,36 @@ macro_rules! int_impl {
10771077
}
10781078
}
10791079

1080+
/// Unchecked integer remainder. Computes `self % rhs`, assuming `rhs != 0`
1081+
/// and overflow cannot occur.
1082+
///
1083+
/// # Safety
1084+
///
1085+
/// This results in undefined behavior when `rhs == 0` or
1086+
#[doc = concat!("(`self == ", stringify!($SelfT), "::MIN` and `rhs == -1`),")]
1087+
/// i.e. when [`checked_rem`] would return `None`.
1088+
///
1089+
#[doc = concat!("[`checked_rem`]: ", stringify!($SelfT), "::checked_rem")]
1090+
#[unstable(feature = "unchecked_div_rem", issue = "136716")]
1091+
#[must_use = "this returns the result of the operation, \
1092+
without modifying the original"]
1093+
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1094+
pub const unsafe fn unchecked_rem(self, rhs: Self) -> Self {
1095+
assert_unsafe_precondition!(
1096+
check_language_ub,
1097+
concat!(stringify!($SelfT), "::unchecked_rem cannot overflow or divide by zero"),
1098+
(
1099+
lhs: $SelfT = self,
1100+
rhs: $SelfT = rhs
1101+
) => rhs != 0 && !lhs.overflowing_rem(rhs).1,
1102+
);
1103+
1104+
// SAFETY: this is guaranteed to be safe by the caller.
1105+
unsafe {
1106+
intrinsics::unchecked_rem(self, rhs)
1107+
}
1108+
}
1109+
10801110
/// Strict integer remainder. Computes `self % rhs`, panicking if
10811111
/// the division results in overflow.
10821112
///

library/core/src/num/uint_macros.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ macro_rules! uint_impl {
10241024
///
10251025
/// # Safety
10261026
///
1027-
/// This results in undefined behavior when `rhs == 0`
1027+
/// This results in undefined behavior when `rhs == 0`,
10281028
/// i.e. when [`checked_div`] would return `None`.
10291029
///
10301030
/// [`unwrap_unchecked`]: option/enum.Option.html#method.unwrap_unchecked
@@ -1166,6 +1166,33 @@ macro_rules! uint_impl {
11661166
}
11671167
}
11681168

1169+
/// Unchecked integer remainder. Computes `self % rhs`, assuming `rhs` is not zero.
1170+
///
1171+
/// # Safety
1172+
///
1173+
/// This results in undefined behavior when `rhs == 0`,
1174+
/// i.e. when [`checked_rem`] would return `None`.
1175+
///
1176+
#[doc = concat!("[`checked_rem`]: ", stringify!($SelfT), "::checked_rem")]
1177+
#[unstable(feature = "unchecked_div_rem", issue = "136716")]
1178+
#[must_use = "this returns the result of the operation, \
1179+
without modifying the original"]
1180+
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1181+
pub const unsafe fn unchecked_rem(self, rhs: Self) -> Self {
1182+
assert_unsafe_precondition!(
1183+
check_language_ub,
1184+
concat!(stringify!($SelfT), "::unchecked_rem cannot divide by zero"),
1185+
(
1186+
rhs: $SelfT = rhs
1187+
) => rhs != 0,
1188+
);
1189+
1190+
// SAFETY: this is guaranteed to be safe by the caller.
1191+
unsafe {
1192+
intrinsics::unchecked_rem(self, rhs)
1193+
}
1194+
}
1195+
11691196
/// Strict integer remainder. Computes `self % rhs`.
11701197
///
11711198
/// Strict remainder calculation on unsigned types is just the regular

0 commit comments

Comments
 (0)