Skip to content

Commit 2c4b73c

Browse files
committed
Auto merge of #115249 - clarfonthey:alignment, r=scottmcm
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`: #102070
2 parents fcab248 + 5dda0c9 commit 2c4b73c

File tree

1 file changed

+41
-1
lines changed

1 file changed

+41
-1
lines changed

library/core/src/ptr/alignment.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ impl Alignment {
4242
/// This provides the same numerical value as [`mem::align_of`],
4343
/// but in an `Alignment` instead of a `usize`.
4444
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
45+
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
4546
#[inline]
4647
pub const fn of<T>() -> Self {
4748
// SAFETY: rustc ensures that type alignment is always a power of two.
@@ -53,6 +54,7 @@ impl Alignment {
5354
///
5455
/// Note that `0` is not a power of two, nor a valid alignment.
5556
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
57+
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
5658
#[inline]
5759
pub const fn new(align: usize) -> Option<Self> {
5860
if align.is_power_of_two() {
@@ -98,6 +100,7 @@ impl Alignment {
98100

99101
/// Returns the alignment as a [`NonZeroUsize`]
100102
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
103+
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
101104
#[inline]
102105
pub const fn as_nonzero(self) -> NonZeroUsize {
103106
// SAFETY: All the discriminants are non-zero.
@@ -118,10 +121,39 @@ impl Alignment {
118121
/// assert_eq!(Alignment::new(1024).unwrap().log2(), 10);
119122
/// ```
120123
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
124+
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
121125
#[inline]
122-
pub fn log2(self) -> u32 {
126+
pub const fn log2(self) -> u32 {
123127
self.as_nonzero().trailing_zeros()
124128
}
129+
130+
/// Returns a bit mask that can be used to match this alignment.
131+
///
132+
/// This is equivalent to `!(self.as_usize() - 1)`.
133+
///
134+
/// # Examples
135+
///
136+
/// ```
137+
/// #![feature(ptr_alignment_type)]
138+
/// #![feature(ptr_mask)]
139+
/// use std::ptr::{Alignment, NonNull};
140+
///
141+
/// let one = <NonNull<u8>>::dangling().as_ptr();
142+
/// let four = <NonNull<u32>>::dangling().as_ptr();
143+
///
144+
/// assert_eq!(four.mask(Alignment::of::<u8>().mask()), four);
145+
/// assert_eq!(four.mask(Alignment::of::<u16>().mask()), four);
146+
/// assert_eq!(four.mask(Alignment::of::<u32>().mask()), four);
147+
/// assert_ne!(four.mask(Alignment::of::<u64>().mask()), four);
148+
/// assert_ne!(one.mask(Alignment::of::<u64>().mask()), one);
149+
/// ```
150+
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
151+
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
152+
#[inline]
153+
pub const fn mask(self) -> usize {
154+
// SAFETY: The alignment is always nonzero, and therefore decrementing won't overflow.
155+
!(unsafe { self.as_usize().unchecked_sub(1) })
156+
}
125157
}
126158

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

228+
/// Returns [`Alignment::MIN`], which is valid for any type.
229+
#[unstable(feature = "ptr_alignment_type", issue = "102070")]
230+
impl Default for Alignment {
231+
fn default() -> Alignment {
232+
Alignment::MIN
233+
}
234+
}
235+
196236
#[cfg(target_pointer_width = "16")]
197237
type AlignmentEnum = AlignmentEnum16;
198238
#[cfg(target_pointer_width = "32")]

0 commit comments

Comments
 (0)