-
Notifications
You must be signed in to change notification settings - Fork 14.1k
Add ilog10 result range hints
#149207
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
Add ilog10 result range hints
#149207
Conversation
|
rustbot has assigned @Mark-Simulacrum. Use |
|
Is this motivated by concrete codegen improvements (the codegen tests are quite artificial)? |
|
Interesting that llvm can already infer some bounds, but apparently not the tightest ones. Looking at the following functions in compiler explorer, there are no panics: pub fn test_u8(i: std::num::NonZeroU8, a: &[u32; 3]) -> u32 {
a[i.ilog10() as usize]
}
pub fn test_u16(i: std::num::NonZeroU16, a: &[u32; 8]) -> u32 {
a[i.ilog10() as usize]
}
pub fn test_u32(i: std::num::NonZeroU32, a: &[u32; 13]) -> u32 {
a[i.ilog10() as usize]
}
pub fn test_u64(i: std::num::NonZeroU64, a: &[u32; 23]) -> u32 {
a[i.ilog10() as usize]
}These functions with tighter bounds would make for nicer codegen test. |
|
@Noratrieb: An example would be getting a slice of digits of an integer where adding an assertion can remove bound checking code: pub fn get_digits(mut x: u32, buffer: &mut [u8; 10]) -> &mut [u8] {
let digits = &mut buffer[..x.checked_ilog10().unwrap_or_default() as usize + 1];
for slot in &mut *digits {
*slot = (x % 10) as u8;
x /= 10;
}
digits
}You can compare the the codegen results here. Also, rust/library/core/src/num/uint_macros.rs Lines 3373 to 3392 in 94b49fd
I think it is reasonable that we do the same on |
|
Reminder, once the PR becomes ready for a review, use |
1ce044b to
d0206df
Compare
This comment has been minimized.
This comment has been minimized.
d4dd0ab to
7a03ee3
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
This comment has been minimized.
This comment has been minimized.
7a03ee3 to
4046385
Compare
|
@rustbot ready. |
|
Given the precedent with sqrt I'll go ahead and approve this. I checked and neither the compiler nor rustc-perf seems to have any meaningful use of ilog10 so our perf suite is probably not capable of determining negative compile-time impact (which is one of the tradeoffs here). @bors r+ |
Rollup of 8 pull requests Successful merges: - #148935 (Fix division syntax in doc comments) - #149207 (Add `ilog10` result range hints) - #149676 (Tidying up tests/ui/issues tests [3/N]) - #149710 (Move ambient gdb discovery from compiletest to bootstrap) - #149714 (Check associated type where-clauses for lifetimes) - #149722 (contracts: fix lowering final declaration without trailing semicolon) - #149736 (contracts: clean up feature flag warning duplicated across tests) - #149739 (mailmap: add binarycat) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of #149207 - EFanZh:add-ilog10-result-range-hints, r=Mark-Simulacrum Add `ilog10` result range hints This PR adds hints that the return value of `T::ilog10` will never exceed `T::MAX.ilog10()`. This works because `ilog10` is a monotonically nondecreasing function, the maximum return value is reached at the max input value.
This PR adds hints that the return value of
T::ilog10will never exceedT::MAX.ilog10().This works because
ilog10is a monotonically nondecreasing function, the maximum return value is reached at the max input value.