Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panic for invalid arguments of {integer primitive}::ilog{,2,10} in all modes #102578

Merged
merged 3 commits into from
Oct 12, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
51 changes: 8 additions & 43 deletions library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2279,9 +2279,8 @@ macro_rules! int_impl {
///
/// # Panics
///
/// When the number is negative, zero, or if the base is not at least 2; it
/// panics in debug mode and the return value is 0 in release
/// mode.
/// This function will panic if `self` is less than or equal to zero,
/// or if `base` is less then 2.
///
/// # Examples
///
Expand All @@ -2294,27 +2293,16 @@ macro_rules! int_impl {
without modifying the original"]
#[inline]
#[track_caller]
#[rustc_inherit_overflow_checks]
#[allow(arithmetic_overflow)]
pub const fn ilog(self, base: Self) -> u32 {
match self.checked_ilog(base) {
Some(n) => n,
None => {
// In debug builds, trigger a panic on None.
// This should optimize completely out in release builds.
let _ = Self::MAX + 1;

0
},
}
assert!(base >= 2, "base of integer logarithm must be at least 2");
self.checked_ilog(base).expect("argument of integer logarithm must be positive")
}

/// Returns the base 2 logarithm of the number, rounded down.
///
/// # Panics
///
/// When the number is negative or zero it panics in debug mode and the return value
/// is 0 in release mode.
/// This function will panic if `self` is less than or equal to zero.
///
/// # Examples
///
Expand All @@ -2327,27 +2315,15 @@ macro_rules! int_impl {
without modifying the original"]
#[inline]
#[track_caller]
#[rustc_inherit_overflow_checks]
#[allow(arithmetic_overflow)]
pub const fn ilog2(self) -> u32 {
match self.checked_ilog2() {
Some(n) => n,
None => {
// In debug builds, trigger a panic on None.
// This should optimize completely out in release builds.
let _ = Self::MAX + 1;

0
},
}
self.checked_ilog2().expect("argument of integer logarithm must be positive")
}

/// Returns the base 10 logarithm of the number, rounded down.
///
/// # Panics
///
/// When the number is negative or zero it panics in debug mode and the return value
/// is 0 in release mode.
/// This function will panic if `self` is less than or equal to zero.
///
/// # Example
///
Expand All @@ -2360,19 +2336,8 @@ macro_rules! int_impl {
without modifying the original"]
#[inline]
#[track_caller]
#[rustc_inherit_overflow_checks]
#[allow(arithmetic_overflow)]
pub const fn ilog10(self) -> u32 {
match self.checked_ilog10() {
Some(n) => n,
None => {
// In debug builds, trigger a panic on None.
// This should optimize completely out in release builds.
let _ = Self::MAX + 1;

0
},
}
self.checked_ilog10().expect("argument of integer logarithm must be positive")
}

/// Returns the logarithm of the number with respect to an arbitrary base,
Expand Down
49 changes: 7 additions & 42 deletions library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,8 +692,7 @@ macro_rules! uint_impl {
///
/// # Panics
///
/// When the number is zero, or if the base is not at least 2;
/// it panics in debug mode and the return value is 0 in release mode.
/// This function will panic if `self` is zero, or if `base` is less then 2.
///
/// # Examples
///
Expand All @@ -706,27 +705,16 @@ macro_rules! uint_impl {
without modifying the original"]
#[inline]
#[track_caller]
#[rustc_inherit_overflow_checks]
#[allow(arithmetic_overflow)]
pub const fn ilog(self, base: Self) -> u32 {
match self.checked_ilog(base) {
Some(n) => n,
None => {
// In debug builds, trigger a panic on None.
// This should optimize completely out in release builds.
let _ = Self::MAX + 1;

0
},
}
assert!(base >= 2, "base of integer logarithm must be at least 2");
self.checked_ilog(base).expect("argument of integer logarithm must be positive")
}

/// Returns the base 2 logarithm of the number, rounded down.
///
/// # Panics
///
/// When the number is zero it panics in debug mode and
/// the return value is 0 in release mode.
/// This function will panic if `self` is zero.
///
/// # Examples
///
Expand All @@ -739,27 +727,15 @@ macro_rules! uint_impl {
without modifying the original"]
#[inline]
#[track_caller]
#[rustc_inherit_overflow_checks]
#[allow(arithmetic_overflow)]
pub const fn ilog2(self) -> u32 {
match self.checked_ilog2() {
Some(n) => n,
None => {
// In debug builds, trigger a panic on None.
// This should optimize completely out in release builds.
let _ = Self::MAX + 1;

0
},
}
self.checked_ilog2().expect("argument of integer logarithm must be positive")
}

/// Returns the base 10 logarithm of the number, rounded down.
///
/// # Panics
///
/// When the number is zero it panics in debug mode and the
/// return value is 0 in release mode.
/// This function will panic if `self` is zero.
///
/// # Example
///
Expand All @@ -772,19 +748,8 @@ macro_rules! uint_impl {
without modifying the original"]
#[inline]
#[track_caller]
#[rustc_inherit_overflow_checks]
#[allow(arithmetic_overflow)]
pub const fn ilog10(self) -> u32 {
match self.checked_ilog10() {
Some(n) => n,
None => {
// In debug builds, trigger a panic on None.
// This should optimize completely out in release builds.
let _ = Self::MAX + 1;

0
},
}
self.checked_ilog10().expect("argument of integer logarithm must be positive")
}

/// Returns the logarithm of the number with respect to an arbitrary base,
Expand Down
30 changes: 30 additions & 0 deletions library/core/tests/num/int_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,33 @@ fn ilog10_u64() {
fn ilog10_u128() {
ilog10_loop! { u128, 38 }
}

#[test]
#[should_panic(expected = "argument of integer logarithm must be positive")]
fn ilog2_of_0_panic() {
let _ = 0u32.ilog2();
}

#[test]
#[should_panic(expected = "argument of integer logarithm must be positive")]
fn ilog10_of_0_panic() {
let _ = 0u32.ilog10();
}

#[test]
#[should_panic(expected = "argument of integer logarithm must be positive")]
fn ilog3_of_0_panic() {
let _ = 0u32.ilog(3);
}

#[test]
#[should_panic(expected = "base of integer logarithm must be at least 2")]
fn ilog0_of_1_panic() {
let _ = 1u32.ilog(0);
}

#[test]
#[should_panic(expected = "base of integer logarithm must be at least 2")]
fn ilog1_of_1_panic() {
let _ = 1u32.ilog(1);
}