Skip to content

use is_multiple_of and div_ceil #143477

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

Merged
merged 2 commits into from
Jul 6, 2025
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
3 changes: 1 addition & 2 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,8 +527,7 @@ impl Size {
/// not a multiple of 8.
pub fn from_bits(bits: impl TryInto<u64>) -> Size {
let bits = bits.try_into().ok().unwrap();
// Avoid potential overflow from `bits + 7`.
Size { raw: bits / 8 + ((bits % 8) + 7) / 8 }
Size { raw: bits.div_ceil(8) }
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/polonius/legacy/location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,6 @@ impl PoloniusLocationTable {
impl LocationIndex {
fn is_start(self) -> bool {
// even indices are start points; odd indices are mid points
(self.index() % 2) == 0
self.index().is_multiple_of(2)
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ impl LlvmType for CastTarget {
"total size {:?} cannot be divided into units of zero size",
self.rest.total
);
if self.rest.total.bytes() % self.rest.unit.size.bytes() != 0 {
if !self.rest.total.bytes().is_multiple_of(self.rest.unit.size.bytes()) {
assert_eq!(self.rest.unit.kind, RegKind::Integer, "only int regs can be split");
}
self.rest.total.bytes().div_ceil(self.rest.unit.size.bytes())
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/va_arg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,10 @@ fn emit_aapcs_va_arg<'ll, 'tcx>(

let gr_type = target_ty.is_any_ptr() || target_ty.is_integral();
let (reg_off, reg_top, slot_size) = if gr_type {
let nreg = (layout.size.bytes() + 7) / 8;
let nreg = layout.size.bytes().div_ceil(8);
(gr_offs, gr_top, nreg * 8)
} else {
let nreg = (layout.size.bytes() + 15) / 16;
let nreg = layout.size.bytes().div_ceil(16);
(vr_offs, vr_top, nreg * 16)
};

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {

#[inline]
fn is_offset_misaligned(offset: u64, align: Align) -> Option<Misalignment> {
if offset % align.bytes() == 0 {
if offset.is_multiple_of(align.bytes()) {
None
} else {
// The biggest power of two through which `offset` is divisible.
Expand Down Expand Up @@ -1554,7 +1554,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
// If the allocation is N-aligned, and the offset is not divisible by N,
// then `base + offset` has a non-zero remainder after division by `N`,
// which means `base + offset` cannot be null.
if offset.bytes() % info.align.bytes() != 0 {
if !offset.bytes().is_multiple_of(info.align.bytes()) {
return interp_ok(false);
}
// We don't know enough, this might be null.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_index/src/bit_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1744,13 +1744,13 @@ impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {

#[inline]
fn num_words<T: Idx>(domain_size: T) -> usize {
(domain_size.index() + WORD_BITS - 1) / WORD_BITS
domain_size.index().div_ceil(WORD_BITS)
}

#[inline]
fn num_chunks<T: Idx>(domain_size: T) -> usize {
assert!(domain_size.index() > 0);
(domain_size.index() + CHUNK_BITS - 1) / CHUNK_BITS
domain_size.index().div_ceil(CHUNK_BITS)
}

#[inline]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/liveness/rwu_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl RWUTable {
const WORD_RWU_COUNT: usize = Self::WORD_BITS / Self::RWU_BITS;

pub(super) fn new(live_nodes: usize, vars: usize) -> RWUTable {
let live_node_words = (vars + Self::WORD_RWU_COUNT - 1) / Self::WORD_RWU_COUNT;
let live_node_words = vars.div_ceil(Self::WORD_RWU_COUNT);
Self { live_nodes, vars, live_node_words, words: vec![0u8; live_node_words * live_nodes] }
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_query_system/src/query/plumbing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ where
// from disk. Re-hashing results is fairly expensive, so we can't
// currently afford to verify every hash. This subset should still
// give us some coverage of potential bugs though.
let try_verify = prev_fingerprint.split().1.as_u64() % 32 == 0;
let try_verify = prev_fingerprint.split().1.as_u64().is_multiple_of(32);
if std::intrinsics::unlikely(
try_verify || qcx.dep_context().sess().opts.unstable_opts.incremental_verify_ich,
) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_serialize/src/leb128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::serialize::Decoder;
/// Returns the length of the longest LEB128 encoding for `T`, assuming `T` is an integer type
pub const fn max_leb128_len<T>() -> usize {
// The longest LEB128 encoding for an integer uses 7 bits per byte.
(size_of::<T>() * 8 + 6) / 7
(size_of::<T>() * 8).div_ceil(7)
}

/// Returns the length of the longest LEB128 encoding of all supported integer types.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_span/src/edit_distance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ pub fn edit_distance_with_substrings(a: &str, b: &str, limit: usize) -> Option<u
1 // Exact substring match, but not a total word match so return non-zero
} else if !big_len_diff {
// Not a big difference in length, discount cost of length difference
score + (len_diff + 1) / 2
score + len_diff.div_ceil(2)
} else {
// A big difference in length, add back the difference in length to the score
score + len_diff
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_target/src/callconv/sparc64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ where
_ => {}
}

if (offset.bytes() % 4) != 0
if !offset.bytes().is_multiple_of(4)
&& matches!(scalar2.primitive(), Primitive::Float(Float::F32 | Float::F64))
{
offset += Size::from_bytes(4 - (offset.bytes() % 4));
Expand Down Expand Up @@ -181,7 +181,7 @@ where
// Structure { float, int, int } doesn't like to be handled like
// { float, long int }. Other way around it doesn't mind.
if data.last_offset < arg.layout.size
&& (data.last_offset.bytes() % 8) != 0
&& !data.last_offset.bytes().is_multiple_of(8)
&& data.prefix_index < data.prefix.len()
{
data.prefix[data.prefix_index] = Some(Reg::i32());
Expand All @@ -190,7 +190,7 @@ where
}

let mut rest_size = arg.layout.size - data.last_offset;
if (rest_size.bytes() % 8) != 0 && data.prefix_index < data.prefix.len() {
if !rest_size.bytes().is_multiple_of(8) && data.prefix_index < data.prefix.len() {
data.prefix[data.prefix_index] = Some(Reg::i32());
rest_size = rest_size - Reg::i32().size;
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/callconv/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ pub(crate) fn fill_inregs<'a, Ty, C>(
continue;
}

let size_in_regs = (arg.layout.size.bits() + 31) / 32;
let size_in_regs = arg.layout.size.bits().div_ceil(32);

if size_in_regs == 0 {
continue;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/callconv/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ where
Ok(())
}

let n = ((arg.layout.size.bytes() + 7) / 8) as usize;
let n = arg.layout.size.bytes().div_ceil(8) as usize;
if n > MAX_EIGHTBYTES {
return Err(Memory);
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/callconv/xtensa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ where
// Determine the number of GPRs needed to pass the current argument
// according to the ABI. 2*XLen-aligned varargs are passed in "aligned"
// register pairs, so may consume 3 registers.
let mut needed_arg_gprs = (size + 32 - 1) / 32;
let mut needed_arg_gprs = size.div_ceil(32);
if needed_align == 64 {
needed_arg_gprs += *arg_gprs_left % 2;
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ty_utils/src/layout/invariant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutCx, TyAndLayout};
pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayout<'tcx>) {
let tcx = cx.tcx();

if layout.size.bytes() % layout.align.abi.bytes() != 0 {
if !layout.size.bytes().is_multiple_of(layout.align.abi.bytes()) {
bug!("size is not a multiple of align, in the following layout:\n{layout:#?}");
}
if layout.size.bytes() >= tcx.data_layout.obj_size_bound() {
Expand Down
8 changes: 4 additions & 4 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1316,7 +1316,7 @@ impl<T> [T] {
assert_unsafe_precondition!(
check_language_ub,
"slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks",
(n: usize = N, len: usize = self.len()) => n != 0 && len % n == 0,
(n: usize = N, len: usize = self.len()) => n != 0 && len.is_multiple_of(n),
);
// SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length
let new_len = unsafe { exact_div(self.len(), N) };
Expand Down Expand Up @@ -1512,7 +1512,7 @@ impl<T> [T] {
assert_unsafe_precondition!(
check_language_ub,
"slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks",
(n: usize = N, len: usize = self.len()) => n != 0 && len % n == 0
(n: usize = N, len: usize = self.len()) => n != 0 && len.is_multiple_of(n)
);
// SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length
let new_len = unsafe { exact_div(self.len(), N) };
Expand Down Expand Up @@ -4866,7 +4866,7 @@ impl<T> [T] {

let byte_offset = elem_start.wrapping_sub(self_start);

if byte_offset % size_of::<T>() != 0 {
if !byte_offset.is_multiple_of(size_of::<T>()) {
return None;
}

Expand Down Expand Up @@ -4920,7 +4920,7 @@ impl<T> [T] {

let byte_start = subslice_start.wrapping_sub(self_start);

if byte_start % size_of::<T>() != 0 {
if !byte_start.is_multiple_of(size_of::<T>()) {
return None;
}

Expand Down
2 changes: 1 addition & 1 deletion library/core/src/slice/sort/shared/smallsort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,7 @@ unsafe fn bidirectional_merge<T: FreezeMarker, F: FnMut(&T, &T) -> bool>(
let right_end = right_rev.wrapping_add(1);

// Odd length, so one element is left unconsumed in the input.
if len % 2 != 0 {
if !len.is_multiple_of(2) {
let left_nonempty = left < left_end;
let last_src = if left_nonempty { left } else { right };
ptr::copy_nonoverlapping(last_src, dst, 1);
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/slice/sort/stable/drift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ fn merge_tree_scale_factor(n: usize) -> u64 {
panic!("Platform not supported");
}

((1 << 62) + n as u64 - 1) / n as u64
(1u64 << 62).div_ceil(n as u64)
}

// Note: merge_tree_depth output is < 64 when left < right as f*x and f*y must
Expand All @@ -182,7 +182,7 @@ fn sqrt_approx(n: usize) -> usize {
// Finally we note that the exponentiation / division can be done directly
// with shifts. We OR with 1 to avoid zero-checks in the integer log.
let ilog = (n | 1).ilog2();
let shift = (1 + ilog) / 2;
let shift = ilog.div_ceil(2);
((1 << shift) + (n >> shift)) / 2
}

Expand Down
2 changes: 1 addition & 1 deletion library/core/src/str/count.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn do_count_chars(s: &str) -> usize {
// Check the properties of `CHUNK_SIZE` and `UNROLL_INNER` that are required
// for correctness.
const _: () = assert!(CHUNK_SIZE < 256);
const _: () = assert!(CHUNK_SIZE % UNROLL_INNER == 0);
const _: () = assert!(CHUNK_SIZE.is_multiple_of(UNROLL_INNER));

// SAFETY: transmuting `[u8]` to `[usize]` is safe except for size
// differences which are handled by `align_to`.
Expand Down
6 changes: 3 additions & 3 deletions library/core/src/str/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl<'a> Iterator for Chars<'a> {
// `(len + 3)` can't overflow, because we know that the `slice::Iter`
// belongs to a slice in memory which has a maximum length of
// `isize::MAX` (that's well below `usize::MAX`).
((len + 3) / 4, Some(len))
(len.div_ceil(4), Some(len))
}

#[inline]
Expand Down Expand Up @@ -1532,11 +1532,11 @@ impl<'a> Iterator for EncodeUtf16<'a> {
// belongs to a slice in memory which has a maximum length of
// `isize::MAX` (that's well below `usize::MAX`)
if self.extra == 0 {
((len + 2) / 3, Some(len))
(len.div_ceil(3), Some(len))
} else {
// We're in the middle of a surrogate pair, so add the remaining
// surrogate to the bounds.
((len + 2) / 3 + 1, Some(len + 1))
(len.div_ceil(3) + 1, Some(len + 1))
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/str/validations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ pub(super) const fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
// Ascii case, try to skip forward quickly.
// When the pointer is aligned, read 2 words of data per iteration
// until we find a word containing a non-ascii byte.
if align != usize::MAX && align.wrapping_sub(index) % USIZE_BYTES == 0 {
if align != usize::MAX && align.wrapping_sub(index).is_multiple_of(USIZE_BYTES) {
let ptr = v.as_ptr();
while index < blocks_end {
// SAFETY: since `align - index` and `ascii_block_size` are
Expand Down
2 changes: 1 addition & 1 deletion library/portable-simd/crates/core_simd/src/lane_count.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub struct LaneCount<const N: usize>;

impl<const N: usize> LaneCount<N> {
/// The number of bytes in a bitmask with this many lanes.
pub const BITMASK_LEN: usize = (N + 7) / 8;
pub const BITMASK_LEN: usize = N.div_ceil(8);
}

/// Statically guarantees that a lane count is marked as supported.
Expand Down
Loading