Skip to content

Commit 5d1c7a2

Browse files
author
Lukas Markeffsky
committed
constify pointer::is_aligned{,_to}
1 parent de33f9a commit 5d1c7a2

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
#![feature(const_option)]
130130
#![feature(const_option_ext)]
131131
#![feature(const_pin)]
132+
#![feature(const_pointer_is_aligned)]
132133
#![feature(const_ptr_sub_ptr)]
133134
#![feature(const_replace)]
134135
#![feature(const_ptr_as_ref)]

library/core/src/ptr/const_ptr.rs

+19-6
Original file line numberDiff line numberDiff line change
@@ -1344,10 +1344,13 @@ impl<T: ?Sized> *const T {
13441344
}
13451345

13461346
/// Returns whether the pointer is properly aligned for `T`.
1347+
// #[cfg(not(bootstrap))] -- Calling this function in a const context from the bootstrap
1348+
// compiler will always return false.
13471349
#[must_use]
13481350
#[inline]
13491351
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1350-
pub fn is_aligned(self) -> bool
1352+
#[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")]
1353+
pub const fn is_aligned(self) -> bool
13511354
where
13521355
T: Sized,
13531356
{
@@ -1362,16 +1365,26 @@ impl<T: ?Sized> *const T {
13621365
/// # Panics
13631366
///
13641367
/// The function panics if `align` is not a power-of-two (this includes 0).
1368+
// #[cfg(not(bootstrap))] -- Calling this function in a const context from the bootstrap
1369+
// compiler will always return false.
13651370
#[must_use]
13661371
#[inline]
13671372
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1368-
pub fn is_aligned_to(self, align: usize) -> bool {
1369-
if !align.is_power_of_two() {
1370-
panic!("is_aligned_to: align is not a power-of-two");
1373+
#[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")]
1374+
pub const fn is_aligned_to(self, align: usize) -> bool {
1375+
assert!(align.is_power_of_two(), "is_aligned_to: align is not a power-of-two");
1376+
1377+
#[inline]
1378+
fn runtime(ptr: *const u8, align: usize) -> bool {
1379+
ptr.addr() & (align - 1) == 0
1380+
}
1381+
1382+
const fn comptime(ptr: *const u8, align: usize) -> bool {
1383+
ptr.align_offset(align) == 0
13711384
}
13721385

1373-
// Cast is needed for `T: !Sized`
1374-
self.cast::<u8>().addr() & align - 1 == 0
1386+
// SAFETY: `ptr.align_offset(align)` returns 0 if and only if the pointer is already aligned.
1387+
unsafe { intrinsics::const_eval_select((self.cast::<u8>(), align), comptime, runtime) }
13751388
}
13761389
}
13771390

library/core/src/ptr/mut_ptr.rs

+19-6
Original file line numberDiff line numberDiff line change
@@ -1615,10 +1615,13 @@ impl<T: ?Sized> *mut T {
16151615
}
16161616

16171617
/// Returns whether the pointer is properly aligned for `T`.
1618+
// #[cfg(not(bootstrap))] -- Calling this function in a const context from the bootstrap
1619+
// compiler will always return false.
16181620
#[must_use]
16191621
#[inline]
16201622
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1621-
pub fn is_aligned(self) -> bool
1623+
#[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")]
1624+
pub const fn is_aligned(self) -> bool
16221625
where
16231626
T: Sized,
16241627
{
@@ -1633,16 +1636,26 @@ impl<T: ?Sized> *mut T {
16331636
/// # Panics
16341637
///
16351638
/// The function panics if `align` is not a power-of-two (this includes 0).
1639+
// #[cfg(not(bootstrap))] -- Calling this function in a const context from the bootstrap
1640+
// compiler will always return false.
16361641
#[must_use]
16371642
#[inline]
16381643
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1639-
pub fn is_aligned_to(self, align: usize) -> bool {
1640-
if !align.is_power_of_two() {
1641-
panic!("is_aligned_to: align is not a power-of-two");
1644+
#[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")]
1645+
pub const fn is_aligned_to(self, align: usize) -> bool {
1646+
assert!(align.is_power_of_two(), "is_aligned_to: align is not a power-of-two");
1647+
1648+
#[inline]
1649+
fn runtime(ptr: *mut u8, align: usize) -> bool {
1650+
ptr.addr() & (align - 1) == 0
1651+
}
1652+
1653+
const fn comptime(ptr: *mut u8, align: usize) -> bool {
1654+
ptr.align_offset(align) == 0
16421655
}
16431656

1644-
// Cast is needed for `T: !Sized`
1645-
self.cast::<u8>().addr() & align - 1 == 0
1657+
// SAFETY: `ptr.align_offset(align)` returns 0 if and only if the pointer is already aligned.
1658+
unsafe { intrinsics::const_eval_select((self.cast::<u8>(), align), comptime, runtime) }
16461659
}
16471660
}
16481661

0 commit comments

Comments
 (0)