Skip to content

Commit 6f6320a

Browse files
author
Lukas Markeffsky
committed
constify pointer::is_aligned{,_to}
1 parent 8cf6b16 commit 6f6320a

File tree

3 files changed

+39
-12
lines changed

3 files changed

+39
-12
lines changed

library/core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
#![feature(const_option)]
131131
#![feature(const_option_ext)]
132132
#![feature(const_pin)]
133+
#![feature(const_pointer_is_aligned)]
133134
#![feature(const_ptr_sub_ptr)]
134135
#![feature(const_replace)]
135136
#![feature(const_result_drop)]

library/core/src/ptr/const_ptr.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,10 +1363,13 @@ impl<T: ?Sized> *const T {
13631363
}
13641364

13651365
/// Returns whether the pointer is properly aligned for `T`.
1366+
// #[cfg(not(bootstrap))] -- Calling this function in a const context from the bootstrap
1367+
// compiler will always return false.
13661368
#[must_use]
13671369
#[inline]
13681370
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1369-
pub fn is_aligned(self) -> bool
1371+
#[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")]
1372+
pub const fn is_aligned(self) -> bool
13701373
where
13711374
T: Sized,
13721375
{
@@ -1381,16 +1384,26 @@ impl<T: ?Sized> *const T {
13811384
/// # Panics
13821385
///
13831386
/// The function panics if `align` is not a power-of-two (this includes 0).
1387+
// #[cfg(not(bootstrap))] -- Calling this function in a const context from the bootstrap
1388+
// compiler will always return false.
13841389
#[must_use]
13851390
#[inline]
13861391
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1387-
pub fn is_aligned_to(self, align: usize) -> bool {
1388-
if !align.is_power_of_two() {
1389-
panic!("is_aligned_to: align is not a power-of-two");
1392+
#[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")]
1393+
pub const fn is_aligned_to(self, align: usize) -> bool {
1394+
assert!(align.is_power_of_two(), "is_aligned_to: align is not a power-of-two");
1395+
1396+
#[inline]
1397+
fn runtime(ptr: *const u8, align: usize) -> bool {
1398+
ptr.addr() & (align - 1) == 0
1399+
}
1400+
1401+
const fn comptime(ptr: *const u8, align: usize) -> bool {
1402+
ptr.align_offset(align) == 0
13901403
}
13911404

1392-
// Cast is needed for `T: !Sized`
1393-
self.cast::<u8>().addr() & align - 1 == 0
1405+
// SAFETY: `ptr.align_offset(align)` returns 0 if and only if the pointer is already aligned.
1406+
unsafe { intrinsics::const_eval_select((self.cast::<u8>(), align), comptime, runtime) }
13941407
}
13951408
}
13961409

library/core/src/ptr/mut_ptr.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,10 +1631,13 @@ impl<T: ?Sized> *mut T {
16311631
}
16321632

16331633
/// Returns whether the pointer is properly aligned for `T`.
1634+
// #[cfg(not(bootstrap))] -- Calling this function in a const context from the bootstrap
1635+
// compiler will always return false.
16341636
#[must_use]
16351637
#[inline]
16361638
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1637-
pub fn is_aligned(self) -> bool
1639+
#[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")]
1640+
pub const fn is_aligned(self) -> bool
16381641
where
16391642
T: Sized,
16401643
{
@@ -1649,16 +1652,26 @@ impl<T: ?Sized> *mut T {
16491652
/// # Panics
16501653
///
16511654
/// The function panics if `align` is not a power-of-two (this includes 0).
1655+
// #[cfg(not(bootstrap))] -- Calling this function in a const context from the bootstrap
1656+
// compiler will always return false.
16521657
#[must_use]
16531658
#[inline]
16541659
#[unstable(feature = "pointer_is_aligned", issue = "96284")]
1655-
pub fn is_aligned_to(self, align: usize) -> bool {
1656-
if !align.is_power_of_two() {
1657-
panic!("is_aligned_to: align is not a power-of-two");
1660+
#[rustc_const_unstable(feature = "const_pointer_is_aligned", issue = "none")]
1661+
pub const fn is_aligned_to(self, align: usize) -> bool {
1662+
assert!(align.is_power_of_two(), "is_aligned_to: align is not a power-of-two");
1663+
1664+
#[inline]
1665+
fn runtime(ptr: *mut u8, align: usize) -> bool {
1666+
ptr.addr() & (align - 1) == 0
1667+
}
1668+
1669+
const fn comptime(ptr: *mut u8, align: usize) -> bool {
1670+
ptr.align_offset(align) == 0
16581671
}
16591672

1660-
// Cast is needed for `T: !Sized`
1661-
self.cast::<u8>().addr() & align - 1 == 0
1673+
// SAFETY: `ptr.align_offset(align)` returns 0 if and only if the pointer is already aligned.
1674+
unsafe { intrinsics::const_eval_select((self.cast::<u8>(), align), comptime, runtime) }
16621675
}
16631676
}
16641677

0 commit comments

Comments
 (0)