Skip to content

Commit 186a428

Browse files
author
Lukas Markeffsky
committed
constify pointer::is_aligned{,_to}
1 parent 326f631 commit 186a428

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

library/core/src/lib.rs

Lines changed: 1 addition & 0 deletions
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+
#![cfg_attr(not(bootstrap), 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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,20 @@ impl<T: ?Sized> *const T {
13471347
#[must_use]
13481348
#[inline]
13491349
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1350+
#[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")]
1351+
#[cfg(not(bootstrap))]
1352+
pub const fn is_aligned(self) -> bool
1353+
where
1354+
T: Sized,
1355+
{
1356+
self.is_aligned_to(core::mem::align_of::<T>())
1357+
}
1358+
1359+
#[must_use]
1360+
#[inline]
1361+
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1362+
#[allow(missing_docs)]
1363+
#[cfg(bootstrap)]
13501364
pub fn is_aligned(self) -> bool
13511365
where
13521366
T: Sized,
@@ -1365,6 +1379,28 @@ impl<T: ?Sized> *const T {
13651379
#[must_use]
13661380
#[inline]
13671381
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1382+
#[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")]
1383+
#[cfg(not(bootstrap))]
1384+
pub const fn is_aligned_to(self, align: usize) -> bool {
1385+
assert!(align.is_power_of_two(), "is_aligned_to: align is not a power-of-two");
1386+
1387+
fn runtime(ptr: *const u8, align: usize) -> bool {
1388+
ptr.addr() & (align - 1) == 0
1389+
}
1390+
1391+
const fn comptime(ptr: *const u8, align: usize) -> bool {
1392+
ptr.align_offset(align) == 0
1393+
}
1394+
1395+
// SAFETY: `ptr.align_offset(align)` returns 0 if and only if the pointer is already aligned.
1396+
unsafe { intrinsics::const_eval_select((self.cast::<u8>(), align), comptime, runtime) }
1397+
}
1398+
1399+
#[must_use]
1400+
#[inline]
1401+
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1402+
#[allow(missing_docs)]
1403+
#[cfg(bootstrap)]
13681404
pub fn is_aligned_to(self, align: usize) -> bool {
13691405
if !align.is_power_of_two() {
13701406
panic!("is_aligned_to: align is not a power-of-two");

library/core/src/ptr/mut_ptr.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,20 @@ impl<T: ?Sized> *mut T {
16181618
#[must_use]
16191619
#[inline]
16201620
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1621+
#[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")]
1622+
#[cfg(not(bootstrap))]
1623+
pub const fn is_aligned(self) -> bool
1624+
where
1625+
T: Sized,
1626+
{
1627+
self.is_aligned_to(core::mem::align_of::<T>())
1628+
}
1629+
1630+
#[must_use]
1631+
#[inline]
1632+
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1633+
#[allow(missing_docs)]
1634+
#[cfg(bootstrap)]
16211635
pub fn is_aligned(self) -> bool
16221636
where
16231637
T: Sized,
@@ -1636,6 +1650,28 @@ impl<T: ?Sized> *mut T {
16361650
#[must_use]
16371651
#[inline]
16381652
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1653+
#[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")]
1654+
#[cfg(not(bootstrap))]
1655+
pub const fn is_aligned_to(self, align: usize) -> bool {
1656+
assert!(align.is_power_of_two(), "is_aligned_to: align is not a power-of-two");
1657+
1658+
fn runtime(ptr: *mut u8, align: usize) -> bool {
1659+
ptr.addr() & (align - 1) == 0
1660+
}
1661+
1662+
const fn comptime(ptr: *mut u8, align: usize) -> bool {
1663+
ptr.align_offset(align) == 0
1664+
}
1665+
1666+
// SAFETY: `ptr.align_offset(align)` returns 0 if and only if the pointer is already aligned.
1667+
unsafe { intrinsics::const_eval_select((self.cast::<u8>(), align), comptime, runtime) }
1668+
}
1669+
1670+
#[must_use]
1671+
#[inline]
1672+
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1673+
#[allow(missing_docs)]
1674+
#[cfg(bootstrap)]
16391675
pub fn is_aligned_to(self, align: usize) -> bool {
16401676
if !align.is_power_of_two() {
16411677
panic!("is_aligned_to: align is not a power-of-two");

0 commit comments

Comments
 (0)