@@ -1574,10 +1574,14 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
1574
1574
1575
1575
/// Align pointer `p`.
1576
1576
///
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
1578
1578
/// to pointer `p` so that pointer `p` would get aligned to `a`.
1579
1579
///
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.
1581
1585
/// The only real change that can be made here is change of `INV_TABLE_MOD_16` and associated
1582
1586
/// constants.
1583
1587
///
@@ -1586,8 +1590,10 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
1586
1590
/// than trying to adapt this to accommodate that change.
1587
1591
///
1588
1592
/// 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.
1589
1595
#[ 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 {
1591
1597
// FIXME(#75598): Direct use of these intrinsics improves codegen significantly at opt-level <=
1592
1598
// 1, where the method versions of these operations are not inlined.
1593
1599
use intrinsics:: {
@@ -1604,7 +1610,7 @@ pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
1604
1610
///
1605
1611
/// Implementation of this function shall not panic. Ever.
1606
1612
#[ inline]
1607
- unsafe fn mod_inv ( x : usize , m : usize ) -> usize {
1613
+ const unsafe fn mod_inv ( x : usize , m : usize ) -> usize {
1608
1614
/// Multiplicative modular inverse table modulo 2⁴ = 16.
1609
1615
///
1610
1616
/// 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 {
1646
1652
inverse & m_minus_one
1647
1653
}
1648
1654
1649
- let addr = p. addr ( ) ;
1650
1655
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
+
1651
1662
// SAFETY: `a` is a power-of-two, therefore non-zero.
1652
1663
let a_minus_one = unsafe { unchecked_sub ( a, 1 ) } ;
1653
1664
0 commit comments