From 95236c63c64ae0c2719265ff8ec2f277ac7bd9dd Mon Sep 17 00:00:00 2001 From: Lars Schumann Date: Sat, 25 Jul 2026 18:32:18 +0000 Subject: [PATCH] Prefer `T::SIZE` over `size_of::()` in core --- library/core/src/any.rs | 4 ++-- library/core/src/cell.rs | 4 ++-- library/core/src/fmt/num.rs | 4 ++-- library/core/src/hash/sip.rs | 5 +++-- library/core/src/intrinsics/mod.rs | 7 ++++--- library/core/src/io/error/repr_bitpacked.rs | 21 ++++++++++--------- library/core/src/mem/alignment.rs | 3 ++- library/core/src/mem/maybe_uninit.rs | 13 +++--------- library/core/src/num/imp/dec2flt/fpu.rs | 3 ++- library/core/src/num/int_macros.rs | 12 +++++------ library/core/src/num/mod.rs | 9 ++++---- library/core/src/num/traits.rs | 5 +++-- library/core/src/num/uint_macros.rs | 14 ++++++------- library/core/src/ptr/const_ptr.rs | 10 ++++----- library/core/src/ptr/mod.rs | 12 +++++------ library/core/src/ptr/mut_ptr.rs | 6 +++--- library/core/src/slice/ascii.rs | 5 +++-- library/core/src/slice/cmp.rs | 2 +- library/core/src/slice/memchr.rs | 5 +++-- library/core/src/slice/mod.rs | 18 ++++++++-------- library/core/src/slice/raw.rs | 5 +++-- library/core/src/slice/rotate.rs | 4 ++-- .../core/src/slice/sort/shared/smallsort.rs | 18 ++++++++-------- library/core/src/slice/sort/stable/mod.rs | 4 ++-- .../core/src/slice/sort/stable/quicksort.rs | 4 ++-- .../core/src/slice/sort/unstable/quicksort.rs | 6 +++--- library/core/src/str/count.rs | 3 ++- library/core/src/str/validations.rs | 3 ++- library/core/src/sync/atomic.rs | 6 +++--- 29 files changed, 110 insertions(+), 105 deletions(-) diff --git a/library/core/src/any.rs b/library/core/src/any.rs index 85ff2fe1dd6ee..49925b1a82480 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -87,8 +87,8 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::intrinsics::{self, type_id, type_id_vtable}; -use crate::mem::transmute; use crate::mem::type_info::{TraitImpl, TypeKind}; +use crate::mem::{SizedTypeProperties, transmute}; use crate::{fmt, hash, ptr}; /////////////////////////////////////////////////////////////////////////////// @@ -727,7 +727,7 @@ pub struct TypeId { /// the TypeId actually is, allowing CTFE and miri to operate based off it. /// At runtime all the pointers in the array contain bits of the hash, making /// the entire `TypeId` actually just be a `u128` hash of the type. - pub(crate) data: [*const (); 16 / size_of::<*const ()>()], + pub(crate) data: [*const (); 16 / <*const ()>::SIZE], } // SAFETY: the raw pointer is always an integer diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 1b8ec2a91478a..3ec96162bc56c 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -252,7 +252,7 @@ use crate::cmp::Ordering; use crate::fmt::{self, Debug, Display}; use crate::marker::{Destruct, PhantomData, Unsize}; -use crate::mem::{self, ManuallyDrop}; +use crate::mem::{self, ManuallyDrop, SizedTypeProperties}; use crate::ops::{self, CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn}; use crate::panic::const_panic; use crate::pin::PinCoerceUnsized; @@ -469,7 +469,7 @@ impl Cell { let src_usize = src.addr(); let dst_usize = dst.addr(); let diff = src_usize.abs_diff(dst_usize); - diff >= size_of::() + diff >= T::SIZE } if ptr::eq(self, other) { diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index 61c9cd7923e5f..8784a1a8782fa 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -1,7 +1,7 @@ //! Integer and floating-point number formatting use crate::fmt::NumBuffer; -use crate::mem::MaybeUninit; +use crate::mem::{MaybeUninit, SizedTypeProperties}; use crate::num::imp::fmt as numfmt; use crate::{fmt, str}; @@ -195,7 +195,7 @@ macro_rules! impl_Display { // Format per four digits from the lookup table. // Four digits need a 16-bit $Unsigned or wider. - while size_of::() > 1 && remain > 999.try_into().expect("branch is not hit for types that cannot fit 999 (u8)") { + while Self::SIZE > 1 && remain > 999.try_into().expect("branch is not hit for types that cannot fit 999 (u8)") { // SAFETY: All of the decimals fit in buf due to MAX_DEC_N // and the while condition ensures at least 4 more decimals. unsafe { core::hint::assert_unchecked(offset >= 4) } diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs index bc74bd0e085ff..48f35d13617d5 100644 --- a/library/core/src/hash/sip.rs +++ b/library/core/src/hash/sip.rs @@ -3,6 +3,7 @@ #![allow(deprecated)] // the types in this module are deprecated use crate::marker::PhantomData; +use crate::mem::SizedTypeProperties; use crate::{cmp, ptr}; /// An implementation of SipHash 1-3. @@ -101,12 +102,12 @@ macro_rules! compress { /// `$i..$i+size_of::<$int_ty>()`, so that must be in-bounds. macro_rules! load_int_le { ($buf:expr, $i:expr, $int_ty:ident) => {{ - debug_assert!($i + size_of::<$int_ty>() <= $buf.len()); + debug_assert!($i + <$int_ty>::SIZE <= $buf.len()); let mut data = 0 as $int_ty; ptr::copy_nonoverlapping( $buf.as_ptr().add($i), &mut data as *mut _ as *mut u8, - size_of::<$int_ty>(), + <$int_ty>::SIZE, ); data.to_le() }}; diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index e9875f31fe784..d23074305d25a 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -55,8 +55,9 @@ use crate::ffi::{VaArgSafe, VaList}; use crate::marker::{ConstParamTy, DiscriminantKind, PointeeSized, Tuple}; +use crate::mem::SizedTypeProperties; use crate::num::imp::libm; -use crate::{mem, ptr}; +use crate::ptr; mod bounds; pub mod fallback; @@ -2193,7 +2194,7 @@ pub const fn rotate_left(x: T, shift: u32) -> // Make sure to call the intrinsic for `funnel_shl`, not the fallback impl. // SAFETY: we modulo `shift` so that the result is definitely less than the size of // `T` in bits. - unsafe { unchecked_funnel_shl(x, x, shift % (mem::size_of::() as u32 * 8)) } + unsafe { unchecked_funnel_shl(x, x, shift % (T::SIZE as u32 * 8)) } } /// Performs rotate right. @@ -2215,7 +2216,7 @@ pub const fn rotate_right(x: T, shift: u32) -> // Make sure to call the intrinsic for `funnel_shr`, not the fallback impl. // SAFETY: we modulo `shift` so that the result is definitely less than the size of // `T` in bits. - unsafe { unchecked_funnel_shr(x, x, shift % (mem::size_of::() as u32 * 8)) } + unsafe { unchecked_funnel_shr(x, x, shift % (T::SIZE as u32 * 8)) } } /// Wrapping (modular) addition. Computes `a + b`, diff --git a/library/core/src/io/error/repr_bitpacked.rs b/library/core/src/io/error/repr_bitpacked.rs index 22cb331924081..c38cdc2232e98 100644 --- a/library/core/src/io/error/repr_bitpacked.rs +++ b/library/core/src/io/error/repr_bitpacked.rs @@ -103,6 +103,7 @@ //! the time. use core::marker::PhantomData; +use core::mem::SizedTypeProperties; use core::num::NonZeroUsize; use core::ptr::NonNull; @@ -138,7 +139,7 @@ impl Repr { // Should only be possible if an allocator handed out a pointer with // wrong alignment. debug_assert_eq!(p.addr() & TAG_MASK, 0); - // Note: We know `TAG_CUSTOM <= size_of::()` (static_assert at + // Note: We know `TAG_CUSTOM <= Custom::SIZE` (static_assert at // end of file), and both the start and end of the expression must be // valid without address space wraparound due to `Box`'s semantics. // @@ -302,14 +303,14 @@ macro_rules! static_assert { } // The bitpacking we use requires pointers be exactly 64 bits. -static_assert!(@usize_eq: size_of::>(), 8); +static_assert!(@usize_eq: NonNull::<()>::SIZE, 8); // We also require pointers and usize be the same size. -static_assert!(@usize_eq: size_of::>(), size_of::()); +static_assert!(@usize_eq: NonNull::<()>::SIZE, usize::SIZE); // `Custom` and `SimpleMessage` need to be thin pointers. -static_assert!(@usize_eq: size_of::<&'static SimpleMessage>(), 8); -static_assert!(@usize_eq: size_of::(), 8); +static_assert!(@usize_eq: <&'static SimpleMessage>::SIZE, 8); +static_assert!(@usize_eq: CustomOwner::SIZE, 8); static_assert!((TAG_MASK + 1).is_power_of_two()); // And they must have sufficient alignment. @@ -330,7 +331,7 @@ static_assert!(@usize_eq: TAG_MASK & TAG_SIMPLE, TAG_SIMPLE); // check isn't needed for that one, although the assertion that we don't // actually wrap around in that wrapping_add does simplify the safety reasoning // elsewhere considerably. -static_assert!(size_of::() >= TAG_CUSTOM); +static_assert!(Custom::SIZE >= TAG_CUSTOM); // These two store a payload which is allowed to be zero, so they must be // non-zero to preserve the `NonNull`'s range invariant. @@ -345,7 +346,7 @@ static_assert!(@usize_eq: TAG_SIMPLE_MESSAGE, 0); // as it's not `#[repr(transparent)]`/`#[repr(C)]`. We could add that, but // the `#[repr()]` would show up in rustdoc, which might be seen as a stable // commitment. -static_assert!(@usize_eq: size_of::(), 8); -static_assert!(@usize_eq: size_of::>(), 8); -static_assert!(@usize_eq: size_of::>(), 8); -static_assert!(@usize_eq: size_of::>(), 16); +static_assert!(@usize_eq: Repr::SIZE, 8); +static_assert!(@usize_eq: Option::::SIZE, 8); +static_assert!(@usize_eq: Result::<(), Repr>::SIZE, 8); +static_assert!(@usize_eq: Result::::SIZE, 16); diff --git a/library/core/src/mem/alignment.rs b/library/core/src/mem/alignment.rs index 8f453685a6f92..65d986f11e4e1 100644 --- a/library/core/src/mem/alignment.rs +++ b/library/core/src/mem/alignment.rs @@ -1,6 +1,7 @@ #![allow(clippy::enum_clike_unportable_variant)] use crate::marker::MetaSized; +use crate::mem::SizedTypeProperties; use crate::num::NonZero; use crate::ub_checks::assert_unsafe_precondition; use crate::{cmp, fmt, hash, mem, num}; @@ -22,7 +23,7 @@ pub struct Alignment { } // Alignment is `repr(usize)`, but via extra steps. -const _: () = assert!(size_of::() == size_of::()); +const _: () = assert!(Alignment::SIZE == usize::SIZE); const _: () = assert!(align_of::() == align_of::()); fn _alignment_can_be_structurally_matched(a: Alignment) -> bool { diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 9bc8b0d128d2b..5950352abbc4c 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -1,7 +1,7 @@ use crate::any::type_name; use crate::clone::TrivialClone; use crate::marker::Destruct; -use crate::mem::{ManuallyDrop, transmute_neo}; +use crate::mem::{ManuallyDrop, SizedTypeProperties, transmute_neo}; use crate::{fmt, intrinsics, ptr, slice}; /// A wrapper type to construct uninitialized instances of `T`. @@ -1077,9 +1077,7 @@ impl MaybeUninit { #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] pub const fn as_bytes(&self) -> &[MaybeUninit] { // SAFETY: MaybeUninit is always valid, even for padding bytes - unsafe { - slice::from_raw_parts(self.as_ptr().cast::>(), super::size_of::()) - } + unsafe { slice::from_raw_parts(self.as_ptr().cast::>(), T::SIZE) } } /// Returns the contents of this `MaybeUninit` as a mutable slice of potentially uninitialized @@ -1108,12 +1106,7 @@ impl MaybeUninit { #[unstable(feature = "maybe_uninit_as_bytes", issue = "93092")] pub const fn as_bytes_mut(&mut self) -> &mut [MaybeUninit] { // SAFETY: MaybeUninit is always valid, even for padding bytes - unsafe { - slice::from_raw_parts_mut( - self.as_mut_ptr().cast::>(), - super::size_of::(), - ) - } + unsafe { slice::from_raw_parts_mut(self.as_mut_ptr().cast::>(), T::SIZE) } } } diff --git a/library/core/src/num/imp/dec2flt/fpu.rs b/library/core/src/num/imp/dec2flt/fpu.rs index 8aad087ec1bc4..7baee7c6250be 100644 --- a/library/core/src/num/imp/dec2flt/fpu.rs +++ b/library/core/src/num/imp/dec2flt/fpu.rs @@ -22,6 +22,7 @@ pub(super) use fpu_precision::set_precision; #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))] mod fpu_precision { use core::arch::asm; + use core::mem::SizedTypeProperties; /// A structure used to preserve the original value of the FPU control word, so that it can be /// restored when the structure is dropped. @@ -60,7 +61,7 @@ mod fpu_precision { let mut cw = 0_u16; // Compute the value for the Precision Control field that is appropriate for `T`. - let cw_precision = match size_of::() { + let cw_precision = match T::SIZE { 4 => 0x0000, // 32 bits 8 => 0x0200, // 64 bits _ => 0x0300, // default, 80 bits diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index a2d367931ea9b..ea11fba6804ca 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -3751,7 +3751,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn to_be_bytes(self) -> [u8; size_of::()] { + pub const fn to_be_bytes(self) -> [u8; Self::SIZE] { self.to_be().to_ne_bytes() } @@ -3771,7 +3771,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn to_le_bytes(self) -> [u8; size_of::()] { + pub const fn to_le_bytes(self) -> [u8; Self::SIZE] { self.to_le().to_ne_bytes() } @@ -3808,7 +3808,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn to_ne_bytes(self) -> [u8; size_of::()] { + pub const fn to_ne_bytes(self) -> [u8; Self::SIZE] { // SAFETY: integers are plain old datatypes so we can always transmute them to // arrays of bytes unsafe { mem::transmute(self) } @@ -3839,7 +3839,7 @@ macro_rules! int_impl { #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] #[must_use] #[inline] - pub const fn from_be_bytes(bytes: [u8; size_of::()]) -> Self { + pub const fn from_be_bytes(bytes: [u8; Self::SIZE]) -> Self { Self::from_be(Self::from_ne_bytes(bytes)) } @@ -3868,7 +3868,7 @@ macro_rules! int_impl { #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] #[must_use] #[inline] - pub const fn from_le_bytes(bytes: [u8; size_of::()]) -> Self { + pub const fn from_le_bytes(bytes: [u8; Self::SIZE]) -> Self { Self::from_le(Self::from_ne_bytes(bytes)) } @@ -3911,7 +3911,7 @@ macro_rules! int_impl { // SAFETY: const sound because integers are plain old datatypes so we can always // transmute to them #[inline] - pub const fn from_ne_bytes(bytes: [u8; size_of::()]) -> Self { + pub const fn from_ne_bytes(bytes: [u8; Self::SIZE]) -> Self { // SAFETY: integers are plain old datatypes so we can always transmute to them unsafe { mem::transmute(bytes) } } diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 59dfe6bd8d9b7..a4c25c7f23f33 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -3,10 +3,11 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::convert::{BoundedCastFromInt, CheckedCastFromInt}; +use crate::mem::{self, SizedTypeProperties}; use crate::panic::const_panic; use crate::str::FromStr; use crate::ub_checks::assert_unsafe_precondition; -use crate::{ascii, intrinsics, mem}; +use crate::{ascii, intrinsics}; // FIXME(const-hack): Used because the `?` operator is not allowed in a const context. macro_rules! try_opt { @@ -1479,7 +1480,7 @@ impl usize { /// Returns an `usize` where every byte is equal to `x`. #[inline] pub(crate) const fn repeat_u8(x: u8) -> usize { - usize::from_ne_bytes([x; size_of::()]) + usize::from_ne_bytes([x; usize::SIZE]) } /// Returns an `usize` where every byte pair is equal to `x`. @@ -1487,7 +1488,7 @@ impl usize { pub(crate) const fn repeat_u16(x: u16) -> usize { let mut r = 0usize; let mut i = 0; - while i < size_of::() { + while i < usize::SIZE { // Use `wrapping_shl` to make it work on targets with 16-bit `usize` r = r.wrapping_shl(16) | (x as usize); i += 2; @@ -1568,7 +1569,7 @@ pub enum FpCategory { #[inline(always)] #[unstable(issue = "none", feature = "std_internals")] pub const fn can_not_overflow(radix: u32, is_signed_ty: bool, digits: &[u8]) -> bool { - radix <= 16 && digits.len() <= size_of::() * 2 - is_signed_ty as usize + radix <= 16 && digits.len() <= T::SIZE * 2 - is_signed_ty as usize } #[cfg_attr(not(panic = "immediate-abort"), inline(never))] diff --git a/library/core/src/num/traits.rs b/library/core/src/num/traits.rs index 8f5daf2345df9..b7ab5fce3751e 100644 --- a/library/core/src/num/traits.rs +++ b/library/core/src/num/traits.rs @@ -1,5 +1,6 @@ /// Definitions of traits for numeric types // Implementation based on `num_conv` by jhpratt, under (MIT OR Apache-2.0). +use crate::mem::SizedTypeProperties; /// Trait for types that this type can be truncated to #[unstable(feature = "num_internals", reason = "internal implementation detail", issue = "none")] @@ -26,7 +27,7 @@ pub impl(self) const trait WidenTarget { macro_rules! impl_truncate { ($($from:ty => $($to:ty),+;)*) => {$($( const _: () = assert!( - size_of::<$from>() >= size_of::<$to>(), + <$from>::SIZE >= <$to>::SIZE, concat!( "cannot truncate ", stringify!($from), @@ -73,7 +74,7 @@ macro_rules! impl_truncate { macro_rules! impl_widen { ($($from:ty => $($to:ty),+;)*) => {$($( const _: () = assert!( - size_of::<$from>() <= size_of::<$to>(), + <$from>::SIZE <= <$to>::SIZE, concat!( "cannot widen ", stringify!($from), diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index b33b2b5db1a32..f848aa3499d03 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -3133,7 +3133,7 @@ macro_rules! uint_impl { without modifying the original"] #[inline] pub const fn abs_diff(self, other: Self) -> Self { - if size_of::() == 1 { + if Self::SIZE == 1 { // Trick LLVM into generating the psadbw instruction when SSE2 // is available and this function is autovectorized for u8's. (self as i32).wrapping_sub(other as i32).unsigned_abs() as Self @@ -3955,7 +3955,7 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn to_be_bytes(self) -> [u8; size_of::()] { + pub const fn to_be_bytes(self) -> [u8; Self::SIZE] { self.to_be().to_ne_bytes() } @@ -3975,7 +3975,7 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] - pub const fn to_le_bytes(self) -> [u8; size_of::()] { + pub const fn to_le_bytes(self) -> [u8; Self::SIZE] { self.to_le().to_ne_bytes() } @@ -4012,7 +4012,7 @@ macro_rules! uint_impl { // SAFETY: const sound because integers are plain old datatypes so we can always // transmute them to arrays of bytes #[inline] - pub const fn to_ne_bytes(self) -> [u8; size_of::()] { + pub const fn to_ne_bytes(self) -> [u8; Self::SIZE] { // SAFETY: integers are plain old datatypes so we can always transmute them to // arrays of bytes unsafe { mem::transmute(self) } @@ -4043,7 +4043,7 @@ macro_rules! uint_impl { #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] #[must_use] #[inline] - pub const fn from_be_bytes(bytes: [u8; size_of::()]) -> Self { + pub const fn from_be_bytes(bytes: [u8; Self::SIZE]) -> Self { Self::from_be(Self::from_ne_bytes(bytes)) } @@ -4072,7 +4072,7 @@ macro_rules! uint_impl { #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")] #[must_use] #[inline] - pub const fn from_le_bytes(bytes: [u8; size_of::()]) -> Self { + pub const fn from_le_bytes(bytes: [u8; Self::SIZE]) -> Self { Self::from_le(Self::from_ne_bytes(bytes)) } @@ -4115,7 +4115,7 @@ macro_rules! uint_impl { // SAFETY: const sound because integers are plain old datatypes so we can always // transmute to them #[inline] - pub const fn from_ne_bytes(bytes: [u8; size_of::()]) -> Self { + pub const fn from_ne_bytes(bytes: [u8; Self::SIZE]) -> Self { // SAFETY: integers are plain old datatypes so we can always transmute to them unsafe { mem::transmute(bytes) } } diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 87e2f0db25a76..7af98d60cc6d5 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -381,7 +381,7 @@ impl *const T { ( this: *const () = self as *const (), count: isize = count, - size: usize = size_of::(), + size: usize = T::SIZE, ) => runtime_offset_nowrap(this, count, size) ); @@ -617,7 +617,7 @@ impl *const T { where T: Sized, { - let pointee_size = size_of::(); + let pointee_size = T::SIZE; assert!(0 < pointee_size && pointee_size <= isize::MAX as usize); // SAFETY: the caller must uphold the safety contract for `ptr_offset_from`. unsafe { intrinsics::ptr_offset_from(self, origin) } @@ -727,7 +727,7 @@ impl *const T { ) => runtime_ptr_ge(this, origin) ); - let pointee_size = size_of::(); + let pointee_size = T::SIZE; assert!(0 < pointee_size && pointee_size <= isize::MAX as usize); // SAFETY: the caller must uphold the safety contract for `ptr_offset_from_unsigned`. unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } @@ -863,7 +863,7 @@ impl *const T { ( this: *const () = self as *const (), count: usize = count, - size: usize = size_of::(), + size: usize = T::SIZE, ) => runtime_add_nowrap(this, count, size) ); @@ -941,7 +941,7 @@ impl *const T { ( this: *const () = self as *const (), count: usize = count, - size: usize = size_of::(), + size: usize = T::SIZE, ) => runtime_sub_nowrap(this, count, size) ); diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index c758d5f4b89d6..e4ed5198fd8c8 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -538,7 +538,7 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us ( src: *const () = src as *const (), dst: *mut () = dst as *mut (), - size: usize = size_of::(), + size: usize = T::SIZE, align: usize = align_of::(), count: usize = count, ) => { @@ -1388,7 +1388,7 @@ pub const unsafe fn swap_nonoverlapping(x: *mut T, y: *mut T, count: usize) { ( x: *mut () = x as *mut (), y: *mut () = y as *mut (), - size: usize = size_of::(), + size: usize = T::SIZE, align: usize = align_of::(), count: usize = count, ) => { @@ -1497,7 +1497,7 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, bytes: NonZero(); + const CHUNK_SIZE: usize = <*const ()>::SIZE; let bytes = bytes.get(); let chunks = bytes / CHUNK_SIZE; @@ -1816,7 +1816,7 @@ pub const unsafe fn read_unaligned(src: *const T) -> T { // Always true thanks to the repr, but to demonstrate const { assert!(mem::offset_of!(Unaligned::, 0) == 0); - assert!(size_of::() == size_of::>()); + assert!(T::SIZE == Unaligned::::SIZE); } let src = src.cast::>(); @@ -2026,7 +2026,7 @@ pub const unsafe fn write_unaligned(dst: *mut T, src: T) { // Always true thanks to the repr, but to demonstrate const { assert!(mem::offset_of!(Unaligned::, 0) == 0); - assert!(size_of::() == size_of::>()); + assert!(T::SIZE == size_of::>()); } let dst = dst.cast::>(); @@ -2325,7 +2325,7 @@ pub(crate) unsafe fn align_offset(p: *const T, a: usize) -> usize { inverse & m_minus_one } - let stride = size_of::(); + let stride = T::SIZE; let addr: usize = p.addr(); diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 327e4ad3fb0e0..38bcb5234c637 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -384,7 +384,7 @@ impl *mut T { ( this: *const () = self as *const (), count: isize = count, - size: usize = size_of::(), + size: usize = T::SIZE, ) => runtime_offset_nowrap(this, count, size) ); @@ -963,7 +963,7 @@ impl *mut T { ( this: *const () = self as *const (), count: usize = count, - size: usize = size_of::(), + size: usize = T::SIZE, ) => runtime_add_nowrap(this, count, size) ); @@ -1041,7 +1041,7 @@ impl *mut T { ( this: *const () = self as *const (), count: usize = count, - size: usize = size_of::(), + size: usize = T::SIZE, ) => runtime_sub_nowrap(this, count, size) ); diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs index 9db07d8abbbef..d8b8b315532b6 100644 --- a/library/core/src/slice/ascii.rs +++ b/library/core/src/slice/ascii.rs @@ -5,6 +5,7 @@ use core::ascii::EscapeDefault; use crate::fmt::{self, Write}; #[cfg(not(all(target_arch = "loongarch64", target_feature = "lsx")))] use crate::intrinsics::const_eval_select; +use crate::mem::SizedTypeProperties; use crate::{ascii, iter, ops}; impl [u8] { @@ -470,7 +471,7 @@ const fn is_ascii(s: &[u8]) -> bool { (NONASCII_MASK & v) != 0 } - const USIZE_SIZE: usize = size_of::(); + const USIZE_SIZE: usize = usize::SIZE; let len = s.len(); let align_offset = s.as_ptr().align_offset(USIZE_SIZE); @@ -592,7 +593,7 @@ fn is_ascii_sse2(bytes: &[u8]) -> bool { #[inline] #[rustc_allow_const_fn_unstable(const_eval_select)] const fn is_ascii(bytes: &[u8]) -> bool { - const USIZE_SIZE: usize = size_of::(); + const USIZE_SIZE: usize = usize::SIZE; const NONASCII_MASK: usize = usize::MAX / 255 * 0x80; const_eval_select!( diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs index 10a0088477162..a4fcb2357e064 100644 --- a/library/core/src/slice/cmp.rs +++ b/library/core/src/slice/cmp.rs @@ -419,7 +419,7 @@ macro_rules! impl_slice_contains { fn slice_contains(&self, arr: &[$t]) -> bool { // Make our LANE_COUNT 4x the normal lane count (aiming for 128 bit vectors). // The compiler will nicely unroll it. - const LANE_COUNT: usize = 4 * (128 / (size_of::<$t>() * 8)); + const LANE_COUNT: usize = 4 * (128 / (<$t>::SIZE * 8)); // SIMD let mut chunks = arr.chunks_exact(LANE_COUNT); for chunk in &mut chunks { diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index 1e1053583a617..2dafd790c3755 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -2,10 +2,11 @@ // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch use crate::intrinsics::const_eval_select; +use crate::mem::SizedTypeProperties; const LO_USIZE: usize = usize::repeat_u8(0x01); const HI_USIZE: usize = usize::repeat_u8(0x80); -const USIZE_BYTES: usize = size_of::(); +const USIZE_BYTES: usize = usize::SIZE; /// Returns `true` if `x` contains any zero byte. /// @@ -137,7 +138,7 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option { // offset is always aligned, so just testing `>` is sufficient and avoids possible // overflow. let repeated_x = usize::repeat_u8(x); - let chunk_bytes = size_of::(); + let chunk_bytes = Chunk::SIZE; while offset > min_aligned_offset { // SAFETY: offset starts at len - suffix.len(), as long as it is greater than diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 83d8ab4ca53b1..a191f17a451c4 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -4465,9 +4465,9 @@ impl [T] { // Explicitly wrap the function call in a const block so it gets // constant-evaluated even in debug mode. - let gcd: usize = const { gcd(size_of::(), size_of::()) }; - let ts: usize = size_of::() / gcd; - let us: usize = size_of::() / gcd; + let gcd: usize = const { gcd(T::SIZE, U::SIZE) }; + let ts: usize = U::SIZE / gcd; + let us: usize = T::SIZE / gcd; // Armed with this knowledge, we can find how many `U`s we can fit! let us_len = self.len() / ts * us; @@ -4670,7 +4670,7 @@ impl [T] { // These are expected to always match, as vector types are laid out like // arrays per , but we // might as well double-check since it'll optimize away anyhow. - assert_eq!(size_of::>(), size_of::<[T; LANES]>()); + assert_eq!(Simd::::SIZE, <[T; LANES]>::SIZE); // SAFETY: The simd types have the same layout as arrays, just with // potentially-higher alignment, so the de-facto transmutes are sound. @@ -4705,7 +4705,7 @@ impl [T] { // These are expected to always match, as vector types are laid out like // arrays per , but we // might as well double-check since it'll optimize away anyhow. - assert_eq!(size_of::>(), size_of::<[T; LANES]>()); + assert_eq!(Simd::::SIZE, <[T; LANES]>::SIZE); // SAFETY: The simd types have the same layout as arrays, just with // potentially-higher alignment, so the de-facto transmutes are sound. @@ -5279,11 +5279,11 @@ impl [T] { let byte_offset = elem_start.wrapping_sub(self_start); - if !byte_offset.is_multiple_of(size_of::()) { + if !byte_offset.is_multiple_of(T::SIZE) { return None; } - let offset = byte_offset / size_of::(); + let offset = byte_offset / T::SIZE; if offset < self.len() { Some(offset) } else { None } } @@ -5333,11 +5333,11 @@ impl [T] { let byte_start = subslice_start.wrapping_sub(self_start); - if !byte_start.is_multiple_of(size_of::()) { + if !byte_start.is_multiple_of(T::SIZE) { return None; } - let start = byte_start / size_of::(); + let start = byte_start / T::SIZE; let end = start.wrapping_add(subslice.len()); if start <= self.len() && end <= self.len() { diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 80b2176933dab..ca1822146aab0 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -1,5 +1,6 @@ //! Free functions to create `&[T]` and `&mut [T]`. +use crate::mem::SizedTypeProperties; use crate::ops::Range; use crate::{array, ptr, ub_checks}; @@ -129,7 +130,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] "slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`", ( data: *mut () = data as *mut (), - size: usize = size_of::(), + size: usize = T::SIZE, align: usize = align_of::(), len: usize = len, ) => @@ -184,7 +185,7 @@ pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a m "slice::from_raw_parts_mut requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`", ( data: *mut () = data as *mut (), - size: usize = size_of::(), + size: usize = T::SIZE, align: usize = align_of::(), len: usize = len, ) => diff --git a/library/core/src/slice/rotate.rs b/library/core/src/slice/rotate.rs index b3b64422884d5..5fa8e1858a0cb 100644 --- a/library/core/src/slice/rotate.rs +++ b/library/core/src/slice/rotate.rs @@ -22,12 +22,12 @@ pub(super) const unsafe fn ptr_rotate(left: usize, mid: *mut T, right: usize) // `T` is not a zero-sized type, so it's okay to divide by its size. if !cfg!(feature = "optimize_for_size") // FIXME(const-hack): Use cmp::min when available in const - && const_min(left, right) <= size_of::() / size_of::() + && const_min(left, right) <= BufType::SIZE / T::SIZE { // SAFETY: guaranteed by the caller unsafe { ptr_rotate_memmove(left, mid, right) }; } else if !cfg!(feature = "optimize_for_size") - && ((left + right < 24) || (size_of::() > size_of::<[usize; 4]>())) + && ((left + right < 24) || (T::SIZE > <[usize; 4]>::SIZE)) { // SAFETY: guaranteed by the caller unsafe { ptr_rotate_gcd(left, mid, right) } diff --git a/library/core/src/slice/sort/shared/smallsort.rs b/library/core/src/slice/sort/shared/smallsort.rs index 0017feb75b641..f3888b511dfaa 100644 --- a/library/core/src/slice/sort/shared/smallsort.rs +++ b/library/core/src/slice/sort/shared/smallsort.rs @@ -1,6 +1,6 @@ //! This module contains a variety of sort implementations that are optimized for small lengths. -use crate::mem::{self, ManuallyDrop, MaybeUninit}; +use crate::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; use crate::slice::sort::shared::FreezeMarker; use crate::{hint, intrinsics, ptr, slice}; @@ -113,7 +113,7 @@ pub(crate) trait UnstableSmallSortFreezeTypeImpl: Sized + FreezeMarker { impl UnstableSmallSortFreezeTypeImpl for T { #[inline(always)] default fn small_sort_threshold() -> usize { - if (size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { + if (T::SIZE * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { SMALL_SORT_GENERAL_THRESHOLD } else { SMALL_SORT_FALLBACK_THRESHOLD @@ -125,7 +125,7 @@ impl UnstableSmallSortFreezeTypeImpl for T { where F: FnMut(&T, &T) -> bool, { - if (size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { + if (T::SIZE * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { small_sort_general(v, is_less); } else { small_sort_fallback(v, is_less); @@ -143,10 +143,10 @@ impl UnstableSmallSortFreezeTypeImpl for T { #[inline(always)] fn small_sort_threshold() -> usize { if has_efficient_in_place_swap::() - && (size_of::() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE + && (T::SIZE * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { SMALL_SORT_NETWORK_THRESHOLD - } else if (size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { + } else if (T::SIZE * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { SMALL_SORT_GENERAL_THRESHOLD } else { SMALL_SORT_FALLBACK_THRESHOLD @@ -159,10 +159,10 @@ impl UnstableSmallSortFreezeTypeImpl for T { F: FnMut(&T, &T) -> bool, { if has_efficient_in_place_swap::() - && (size_of::() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE + && (T::SIZE * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { small_sort_network(v, is_less); - } else if (size_of::() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { + } else if (T::SIZE * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE { small_sort_general(v, is_less); } else { small_sort_fallback(v, is_less); @@ -238,7 +238,7 @@ fn small_sort_general_with_scratch bool>( unsafe { let scratch_base = scratch.as_mut_ptr() as *mut T; - let presorted_len = if const { size_of::() <= 16 } && len >= 16 { + let presorted_len = if const { T::SIZE <= 16 } && len >= 16 { // SAFETY: scratch_base is valid and has enough space. sort8_stable(v_base, scratch_base, scratch_base.add(len), is_less); sort8_stable( @@ -857,5 +857,5 @@ fn panic_on_ord_violation() -> ! { #[must_use] pub(crate) const fn has_efficient_in_place_swap() -> bool { // Heuristic that holds true on all tested 64-bit capable architectures. - size_of::() <= 8 // size_of::() + T::SIZE <= 8 // u64::SIZE } diff --git a/library/core/src/slice/sort/stable/mod.rs b/library/core/src/slice/sort/stable/mod.rs index 8b4e5c0c8c3a1..6a037a1730001 100644 --- a/library/core/src/slice/sort/stable/mod.rs +++ b/library/core/src/slice/sort/stable/mod.rs @@ -109,7 +109,7 @@ fn driftsort_main bool, BufT: BufGuard>(v: &mut [T], i // If min_good_run_len is ever modified, this code must be updated to allocate // the correct scratch size for it. const MAX_FULL_ALLOC_BYTES: usize = 8_000_000; // 8MB - let max_full_alloc = MAX_FULL_ALLOC_BYTES / size_of::(); + let max_full_alloc = MAX_FULL_ALLOC_BYTES / T::SIZE; let len = v.len(); let alloc_len = cmp::max( cmp::max(len - len / 2, cmp::min(len, max_full_alloc)), @@ -157,7 +157,7 @@ impl AlignedStorage { } fn as_uninit_slice_mut(&mut self) -> &mut [MaybeUninit] { - let len = N / size_of::(); + let len = N / T::SIZE; // SAFETY: `_align` ensures we are correctly aligned. unsafe { core::slice::from_raw_parts_mut(self.storage.as_mut_ptr().cast(), len) } diff --git a/library/core/src/slice/sort/stable/quicksort.rs b/library/core/src/slice/sort/stable/quicksort.rs index acc8a5e838e12..f10448c6e02ae 100644 --- a/library/core/src/slice/sort/stable/quicksort.rs +++ b/library/core/src/slice/sort/stable/quicksort.rs @@ -1,6 +1,6 @@ //! This module contains a stable quicksort and partition implementation. -use crate::mem::MaybeUninit; +use crate::mem::{MaybeUninit, SizedTypeProperties}; use crate::slice::sort::shared::FreezeMarker; use crate::slice::sort::shared::pivot::choose_pivot; use crate::slice::sort::shared::smallsort::StableSmallSortTypeImpl; @@ -125,7 +125,7 @@ fn stable_partition bool>( // this gave significant performance boosts in benchmarks. Unrolling // through for _ in 0..UNROLL_LEN { .. } instead of manually improves // compile times but has a ~10-20% performance penalty on opt-level=s. - if const { size_of::() <= 16 } { + if const { T::SIZE <= 16 } { const UNROLL_LEN: usize = 4; let unroll_end = v_base.add(loop_end_pos.saturating_sub(UNROLL_LEN - 1)); while state.scan < unroll_end { diff --git a/library/core/src/slice/sort/unstable/quicksort.rs b/library/core/src/slice/sort/unstable/quicksort.rs index bdf56a8080305..9c5dc95d590cc 100644 --- a/library/core/src/slice/sort/unstable/quicksort.rs +++ b/library/core/src/slice/sort/unstable/quicksort.rs @@ -2,7 +2,7 @@ #[cfg(not(feature = "optimize_for_size"))] use crate::mem; -use crate::mem::ManuallyDrop; +use crate::mem::{ManuallyDrop, SizedTypeProperties}; #[cfg(not(feature = "optimize_for_size"))] use crate::slice::sort::shared::pivot::choose_pivot; #[cfg(not(feature = "optimize_for_size"))] @@ -138,7 +138,7 @@ where const fn inst_partition bool>() -> fn(&mut [T], &T, &mut F) -> usize { const MAX_BRANCHLESS_PARTITION_SIZE: usize = 96; - if size_of::() <= MAX_BRANCHLESS_PARTITION_SIZE { + if T::SIZE <= MAX_BRANCHLESS_PARTITION_SIZE { // Specialize for types that are relatively cheap to copy, where branchless optimizations // have large leverage e.g. `u64` and `String`. cfg_select! { @@ -306,7 +306,7 @@ where // Manual unrolling that works well on x86, Arm and with opt-level=s without murdering // compile-times. Leaving this to the compiler yields ok to bad results. - let unroll_len = const { if size_of::() <= 16 { 2 } else { 1 } }; + let unroll_len = const { if T::SIZE <= 16 { 2 } else { 1 } }; let unroll_end = v_base.add(len - (unroll_len - 1)); while state.right < unroll_end { diff --git a/library/core/src/str/count.rs b/library/core/src/str/count.rs index f59ad3e66b43b..8620c60b986aa 100644 --- a/library/core/src/str/count.rs +++ b/library/core/src/str/count.rs @@ -19,8 +19,9 @@ //! the term "non-continuation byte" to refer to these bytes in the code. use core::intrinsics::unlikely; +use core::mem::SizedTypeProperties; -const USIZE_SIZE: usize = size_of::(); +const USIZE_SIZE: usize = usize::SIZE; const UNROLL_INNER: usize = 4; #[inline] diff --git a/library/core/src/str/validations.rs b/library/core/src/str/validations.rs index b54d6478e584d..ac9514fef622a 100644 --- a/library/core/src/str/validations.rs +++ b/library/core/src/str/validations.rs @@ -2,6 +2,7 @@ use super::Utf8Error; use crate::intrinsics::const_eval_select; +use crate::mem::SizedTypeProperties; /// Returns the initial codepoint accumulator for the first byte. /// The first byte is special, only want bottom 5 bits for width 2, 4 bits @@ -127,7 +128,7 @@ pub(super) const fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { let mut index = 0; let len = v.len(); - const USIZE_BYTES: usize = size_of::(); + const USIZE_BYTES: usize = usize::SIZE; let ascii_block_size = 2 * USIZE_BYTES; let blocks_end = if len >= ascii_block_size { len - ascii_block_size + 1 } else { 0 }; diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 1a767d8092bda..8c103b6f41398 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -247,7 +247,7 @@ use self::Ordering::*; use crate::cell::UnsafeCell; use crate::hint::spin_loop; use crate::intrinsics::AtomicOrdering as AO; -use crate::mem::transmute; +use crate::mem::{SizedTypeProperties, transmute}; use crate::{fmt, intrinsics}; #[unstable( @@ -2205,7 +2205,7 @@ impl AtomicPtr { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T { - self.fetch_byte_add(val.wrapping_mul(size_of::()), order) + self.fetch_byte_add(val.wrapping_mul(T::SIZE), order) } /// Offsets the pointer's address by subtracting `val` (in units of `T`), @@ -2250,7 +2250,7 @@ impl AtomicPtr { #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces #[rustc_should_not_be_called_on_const_items] pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T { - self.fetch_byte_sub(val.wrapping_mul(size_of::()), order) + self.fetch_byte_sub(val.wrapping_mul(T::SIZE), order) } /// Offsets the pointer's address by adding `val` *bytes*, returning the