Skip to content

Commit

Permalink
Auto merge of rust-lang#115249 - clarfonthey:alignment, r=scottmcm
Browse files Browse the repository at this point in the history
impl more traits for ptr::Alignment, add mask method

Changes:

* Adds `rustc_const_unstable` attributes where missing
* Makes `log2` method const
* Adds `mask` method
* Implements `Default`, which is equivalent to `Alignment::MIN`

No longer included in PR:

* Removes indirection of `AlignmentEnum` type alias (this was intentional)
* Implements `Display`, `Binary`, `Octal`, `LowerHex`, and `UpperHex` (should go through libs-api instead)
* Controversially implements `LowerExp` and `UpperExp` using `p` instead of `e` to indicate a power of 2 (also should go through libs-api)

Tracking issue for `ptr::Alignment`: rust-lang#102070
  • Loading branch information
bors committed Oct 14, 2023
2 parents fcab248 + 5dda0c9 commit 2c4b73c
Showing 1 changed file with 41 additions and 1 deletion.
42 changes: 41 additions & 1 deletion library/core/src/ptr/alignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ impl Alignment {
/// This provides the same numerical value as [`mem::align_of`],
/// but in an `Alignment` instead of a `usize`.
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
#[inline]
pub const fn of<T>() -> Self {
// SAFETY: rustc ensures that type alignment is always a power of two.
Expand All @@ -53,6 +54,7 @@ impl Alignment {
///
/// Note that `0` is not a power of two, nor a valid alignment.
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
#[inline]
pub const fn new(align: usize) -> Option<Self> {
if align.is_power_of_two() {
Expand Down Expand Up @@ -98,6 +100,7 @@ impl Alignment {

/// Returns the alignment as a [`NonZeroUsize`]
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
#[inline]
pub const fn as_nonzero(self) -> NonZeroUsize {
// SAFETY: All the discriminants are non-zero.
Expand All @@ -118,10 +121,39 @@ impl Alignment {
/// assert_eq!(Alignment::new(1024).unwrap().log2(), 10);
/// ```
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
#[inline]
pub fn log2(self) -> u32 {
pub const fn log2(self) -> u32 {
self.as_nonzero().trailing_zeros()
}

/// Returns a bit mask that can be used to match this alignment.
///
/// This is equivalent to `!(self.as_usize() - 1)`.
///
/// # Examples
///
/// ```
/// #![feature(ptr_alignment_type)]
/// #![feature(ptr_mask)]
/// use std::ptr::{Alignment, NonNull};
///
/// let one = <NonNull<u8>>::dangling().as_ptr();
/// let four = <NonNull<u32>>::dangling().as_ptr();
///
/// assert_eq!(four.mask(Alignment::of::<u8>().mask()), four);
/// assert_eq!(four.mask(Alignment::of::<u16>().mask()), four);
/// assert_eq!(four.mask(Alignment::of::<u32>().mask()), four);
/// assert_ne!(four.mask(Alignment::of::<u64>().mask()), four);
/// assert_ne!(one.mask(Alignment::of::<u64>().mask()), one);
/// ```
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
#[inline]
pub const fn mask(self) -> usize {
// SAFETY: The alignment is always nonzero, and therefore decrementing won't overflow.
!(unsafe { self.as_usize().unchecked_sub(1) })
}
}

#[unstable(feature = "ptr_alignment_type", issue = "102070")]
Expand Down Expand Up @@ -193,6 +225,14 @@ impl hash::Hash for Alignment {
}
}

/// Returns [`Alignment::MIN`], which is valid for any type.
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
impl Default for Alignment {
fn default() -> Alignment {
Alignment::MIN
}
}

#[cfg(target_pointer_width = "16")]
type AlignmentEnum = AlignmentEnum16;
#[cfg(target_pointer_width = "32")]
Expand Down

0 comments on commit 2c4b73c

Please sign in to comment.