Skip to content

Commit ff37704

Browse files
author
Lukas Markeffsky
committed
make const align_offset useful
1 parent 65fb598 commit ff37704

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

core/src/ptr/const_ptr.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,21 @@ impl<T: ?Sized> *const T {
13221322
/// ```
13231323
#[stable(feature = "align_offset", since = "1.36.0")]
13241324
#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
1325+
#[cfg(not(bootstrap))]
1326+
pub const fn align_offset(self, align: usize) -> usize
1327+
where
1328+
T: Sized,
1329+
{
1330+
assert!(align.is_power_of_two(), "align_offset: align is not a power-of-two");
1331+
1332+
// SAFETY: `align` has been checked to be a power of 2 above
1333+
unsafe { align_offset(self, align) }
1334+
}
1335+
1336+
#[stable(feature = "align_offset", since = "1.36.0")]
1337+
#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
1338+
#[allow(missing_docs)]
1339+
#[cfg(bootstrap)]
13251340
pub const fn align_offset(self, align: usize) -> usize
13261341
where
13271342
T: Sized,

core/src/ptr/mod.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,10 +1574,14 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
15741574

15751575
/// Align pointer `p`.
15761576
///
1577-
/// Calculate offset (in terms of elements of `stride` stride) that has to be applied
1577+
/// Calculate offset (in terms of elements of `size_of::<T>()` stride) that has to be applied
15781578
/// to pointer `p` so that pointer `p` would get aligned to `a`.
15791579
///
1580-
/// Note: This implementation has been carefully tailored to not panic. It is UB for this to panic.
1580+
/// # Safety
1581+
/// `a` must be a power of two.
1582+
///
1583+
/// # Notes
1584+
/// This implementation has been carefully tailored to not panic. It is UB for this to panic.
15811585
/// The only real change that can be made here is change of `INV_TABLE_MOD_16` and associated
15821586
/// constants.
15831587
///
@@ -1586,8 +1590,10 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
15861590
/// than trying to adapt this to accommodate that change.
15871591
///
15881592
/// Any questions go to @nagisa.
1593+
// #[cfg(not(bootstrap))] -- Calling this function in a const context from the bootstrap
1594+
// compiler will always cause an error.
15891595
#[lang = "align_offset"]
1590-
pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
1596+
pub(crate) const unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
15911597
// FIXME(#75598): Direct use of these intrinsics improves codegen significantly at opt-level <=
15921598
// 1, where the method versions of these operations are not inlined.
15931599
use intrinsics::{
@@ -1604,7 +1610,7 @@ pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
16041610
///
16051611
/// Implementation of this function shall not panic. Ever.
16061612
#[inline]
1607-
unsafe fn mod_inv(x: usize, m: usize) -> usize {
1613+
const unsafe fn mod_inv(x: usize, m: usize) -> usize {
16081614
/// Multiplicative modular inverse table modulo 2⁴ = 16.
16091615
///
16101616
/// Note, that this table does not contain values where inverse does not exist (i.e., for
@@ -1646,8 +1652,13 @@ pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
16461652
inverse & m_minus_one
16471653
}
16481654

1649-
let addr = p.addr();
16501655
let stride = mem::size_of::<T>();
1656+
1657+
// SAFETY: At runtime transmuting a pointer to `usize` is always safe, because they have the
1658+
// same layout. During const eval we hook this function to ensure that the pointer always has
1659+
// an address (only the standard library can do this).
1660+
let addr = unsafe { mem::transmute(p) };
1661+
16511662
// SAFETY: `a` is a power-of-two, therefore non-zero.
16521663
let a_minus_one = unsafe { unchecked_sub(a, 1) };
16531664

core/src/ptr/mut_ptr.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,6 +1590,21 @@ impl<T: ?Sized> *mut T {
15901590
/// ```
15911591
#[stable(feature = "align_offset", since = "1.36.0")]
15921592
#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
1593+
#[cfg(not(bootstrap))]
1594+
pub const fn align_offset(self, align: usize) -> usize
1595+
where
1596+
T: Sized,
1597+
{
1598+
assert!(align.is_power_of_two(), "align_offset: align is not a power-of-two");
1599+
1600+
// SAFETY: `align` has been checked to be a power of 2 above
1601+
unsafe { align_offset(self, align) }
1602+
}
1603+
1604+
#[stable(feature = "align_offset", since = "1.36.0")]
1605+
#[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
1606+
#[allow(missing_docs)]
1607+
#[cfg(bootstrap)]
15931608
pub const fn align_offset(self, align: usize) -> usize
15941609
where
15951610
T: Sized,

0 commit comments

Comments
 (0)