@@ -1358,15 +1358,6 @@ impl<T: ?Sized> *const T {
13581358 /// beyond the allocation that the pointer points into. It is up to the caller to ensure that
13591359 /// the returned offset is correct in all terms other than alignment.
13601360 ///
1361- /// When this is called during compile-time evaluation (which is unstable), the implementation
1362- /// may return `usize::MAX` in cases where that can never happen at runtime. This is because the
1363- /// actual alignment of pointers is not known yet during compile-time, so an offset with
1364- /// guaranteed alignment can sometimes not be computed. For example, a buffer declared as `[u8;
1365- /// N]` might be allocated at an odd or an even address, but at compile-time this is not yet
1366- /// known, so the execution has to be correct for either choice. It is therefore impossible to
1367- /// find an offset that is guaranteed to be 2-aligned. (This behavior is subject to change, as usual
1368- /// for unstable APIs.)
1369- ///
13701361 /// # Panics
13711362 ///
13721363 /// The function panics if `align` is not a power-of-two.
@@ -1395,8 +1386,7 @@ impl<T: ?Sized> *const T {
13951386 #[ must_use]
13961387 #[ inline]
13971388 #[ stable( feature = "align_offset" , since = "1.36.0" ) ]
1398- #[ rustc_const_unstable( feature = "const_align_offset" , issue = "90962" ) ]
1399- pub const fn align_offset ( self , align : usize ) -> usize
1389+ pub fn align_offset ( self , align : usize ) -> usize
14001390 where
14011391 T : Sized ,
14021392 {
@@ -1431,94 +1421,10 @@ impl<T: ?Sized> *const T {
14311421 /// assert!(ptr.is_aligned());
14321422 /// assert!(!ptr.wrapping_byte_add(1).is_aligned());
14331423 /// ```
1434- ///
1435- /// # At compiletime
1436- /// **Note: Alignment at compiletime is experimental and subject to change. See the
1437- /// [tracking issue] for details.**
1438- ///
1439- /// At compiletime, the compiler may not know where a value will end up in memory.
1440- /// Calling this function on a pointer created from a reference at compiletime will only
1441- /// return `true` if the pointer is guaranteed to be aligned. This means that the pointer
1442- /// is never aligned if cast to a type with a stricter alignment than the reference's
1443- /// underlying allocation.
1444- ///
1445- /// ```
1446- /// #![feature(const_pointer_is_aligned)]
1447- ///
1448- /// // On some platforms, the alignment of primitives is less than their size.
1449- /// #[repr(align(4))]
1450- /// struct AlignedI32(i32);
1451- /// #[repr(align(8))]
1452- /// struct AlignedI64(i64);
1453- ///
1454- /// const _: () = {
1455- /// let data = AlignedI32(42);
1456- /// let ptr = &data as *const AlignedI32;
1457- /// assert!(ptr.is_aligned());
1458- ///
1459- /// // At runtime either `ptr1` or `ptr2` would be aligned, but at compiletime neither is aligned.
1460- /// let ptr1 = ptr.cast::<AlignedI64>();
1461- /// let ptr2 = ptr.wrapping_add(1).cast::<AlignedI64>();
1462- /// assert!(!ptr1.is_aligned());
1463- /// assert!(!ptr2.is_aligned());
1464- /// };
1465- /// ```
1466- ///
1467- /// Due to this behavior, it is possible that a runtime pointer derived from a compiletime
1468- /// pointer is aligned, even if the compiletime pointer wasn't aligned.
1469- ///
1470- /// ```
1471- /// #![feature(const_pointer_is_aligned)]
1472- ///
1473- /// // On some platforms, the alignment of primitives is less than their size.
1474- /// #[repr(align(4))]
1475- /// struct AlignedI32(i32);
1476- /// #[repr(align(8))]
1477- /// struct AlignedI64(i64);
1478- ///
1479- /// // At compiletime, neither `COMPTIME_PTR` nor `COMPTIME_PTR + 1` is aligned.
1480- /// const COMPTIME_PTR: *const AlignedI32 = &AlignedI32(42);
1481- /// const _: () = assert!(!COMPTIME_PTR.cast::<AlignedI64>().is_aligned());
1482- /// const _: () = assert!(!COMPTIME_PTR.wrapping_add(1).cast::<AlignedI64>().is_aligned());
1483- ///
1484- /// // At runtime, either `runtime_ptr` or `runtime_ptr + 1` is aligned.
1485- /// let runtime_ptr = COMPTIME_PTR;
1486- /// assert_ne!(
1487- /// runtime_ptr.cast::<AlignedI64>().is_aligned(),
1488- /// runtime_ptr.wrapping_add(1).cast::<AlignedI64>().is_aligned(),
1489- /// );
1490- /// ```
1491- ///
1492- /// If a pointer is created from a fixed address, this function behaves the same during
1493- /// runtime and compiletime.
1494- ///
1495- /// ```
1496- /// #![feature(const_pointer_is_aligned)]
1497- ///
1498- /// // On some platforms, the alignment of primitives is less than their size.
1499- /// #[repr(align(4))]
1500- /// struct AlignedI32(i32);
1501- /// #[repr(align(8))]
1502- /// struct AlignedI64(i64);
1503- ///
1504- /// const _: () = {
1505- /// let ptr = 40 as *const AlignedI32;
1506- /// assert!(ptr.is_aligned());
1507- ///
1508- /// // For pointers with a known address, runtime and compiletime behavior are identical.
1509- /// let ptr1 = ptr.cast::<AlignedI64>();
1510- /// let ptr2 = ptr.wrapping_add(1).cast::<AlignedI64>();
1511- /// assert!(ptr1.is_aligned());
1512- /// assert!(!ptr2.is_aligned());
1513- /// };
1514- /// ```
1515- ///
1516- /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
15171424 #[ must_use]
15181425 #[ inline]
15191426 #[ stable( feature = "pointer_is_aligned" , since = "1.79.0" ) ]
1520- #[ rustc_const_unstable( feature = "const_pointer_is_aligned" , issue = "104203" ) ]
1521- pub const fn is_aligned ( self ) -> bool
1427+ pub fn is_aligned ( self ) -> bool
15221428 where
15231429 T : Sized ,
15241430 {
@@ -1555,105 +1461,15 @@ impl<T: ?Sized> *const T {
15551461 ///
15561462 /// assert_ne!(ptr.is_aligned_to(8), ptr.wrapping_add(1).is_aligned_to(8));
15571463 /// ```
1558- ///
1559- /// # At compiletime
1560- /// **Note: Alignment at compiletime is experimental and subject to change. See the
1561- /// [tracking issue] for details.**
1562- ///
1563- /// At compiletime, the compiler may not know where a value will end up in memory.
1564- /// Calling this function on a pointer created from a reference at compiletime will only
1565- /// return `true` if the pointer is guaranteed to be aligned. This means that the pointer
1566- /// cannot be stricter aligned than the reference's underlying allocation.
1567- ///
1568- /// ```
1569- /// #![feature(pointer_is_aligned_to)]
1570- /// #![feature(const_pointer_is_aligned)]
1571- ///
1572- /// // On some platforms, the alignment of i32 is less than 4.
1573- /// #[repr(align(4))]
1574- /// struct AlignedI32(i32);
1575- ///
1576- /// const _: () = {
1577- /// let data = AlignedI32(42);
1578- /// let ptr = &data as *const AlignedI32;
1579- ///
1580- /// assert!(ptr.is_aligned_to(1));
1581- /// assert!(ptr.is_aligned_to(2));
1582- /// assert!(ptr.is_aligned_to(4));
1583- ///
1584- /// // At compiletime, we know for sure that the pointer isn't aligned to 8.
1585- /// assert!(!ptr.is_aligned_to(8));
1586- /// assert!(!ptr.wrapping_add(1).is_aligned_to(8));
1587- /// };
1588- /// ```
1589- ///
1590- /// Due to this behavior, it is possible that a runtime pointer derived from a compiletime
1591- /// pointer is aligned, even if the compiletime pointer wasn't aligned.
1592- ///
1593- /// ```
1594- /// #![feature(pointer_is_aligned_to)]
1595- /// #![feature(const_pointer_is_aligned)]
1596- ///
1597- /// // On some platforms, the alignment of i32 is less than 4.
1598- /// #[repr(align(4))]
1599- /// struct AlignedI32(i32);
1600- ///
1601- /// // At compiletime, neither `COMPTIME_PTR` nor `COMPTIME_PTR + 1` is aligned.
1602- /// const COMPTIME_PTR: *const AlignedI32 = &AlignedI32(42);
1603- /// const _: () = assert!(!COMPTIME_PTR.is_aligned_to(8));
1604- /// const _: () = assert!(!COMPTIME_PTR.wrapping_add(1).is_aligned_to(8));
1605- ///
1606- /// // At runtime, either `runtime_ptr` or `runtime_ptr + 1` is aligned.
1607- /// let runtime_ptr = COMPTIME_PTR;
1608- /// assert_ne!(
1609- /// runtime_ptr.is_aligned_to(8),
1610- /// runtime_ptr.wrapping_add(1).is_aligned_to(8),
1611- /// );
1612- /// ```
1613- ///
1614- /// If a pointer is created from a fixed address, this function behaves the same during
1615- /// runtime and compiletime.
1616- ///
1617- /// ```
1618- /// #![feature(pointer_is_aligned_to)]
1619- /// #![feature(const_pointer_is_aligned)]
1620- ///
1621- /// const _: () = {
1622- /// let ptr = 40 as *const u8;
1623- /// assert!(ptr.is_aligned_to(1));
1624- /// assert!(ptr.is_aligned_to(2));
1625- /// assert!(ptr.is_aligned_to(4));
1626- /// assert!(ptr.is_aligned_to(8));
1627- /// assert!(!ptr.is_aligned_to(16));
1628- /// };
1629- /// ```
1630- ///
1631- /// [tracking issue]: https://github.com/rust-lang/rust/issues/104203
16321464 #[ must_use]
16331465 #[ inline]
16341466 #[ unstable( feature = "pointer_is_aligned_to" , issue = "96284" ) ]
1635- #[ rustc_const_unstable( feature = "const_pointer_is_aligned" , issue = "104203" ) ]
1636- pub const fn is_aligned_to ( self , align : usize ) -> bool {
1467+ pub fn is_aligned_to ( self , align : usize ) -> bool {
16371468 if !align. is_power_of_two ( ) {
16381469 panic ! ( "is_aligned_to: align is not a power-of-two" ) ;
16391470 }
16401471
1641- #[ inline]
1642- fn runtime_impl ( ptr : * const ( ) , align : usize ) -> bool {
1643- ptr. addr ( ) & ( align - 1 ) == 0
1644- }
1645-
1646- #[ inline]
1647- #[ rustc_const_unstable( feature = "const_pointer_is_aligned" , issue = "104203" ) ]
1648- const fn const_impl ( ptr : * const ( ) , align : usize ) -> bool {
1649- // We can't use the address of `self` in a `const fn`, so we use `align_offset` instead.
1650- ptr. align_offset ( align) == 0
1651- }
1652-
1653- // The cast to `()` is used to
1654- // 1. deal with fat pointers; and
1655- // 2. ensure that `align_offset` (in `const_impl`) doesn't actually try to compute an offset.
1656- const_eval_select ( ( self . cast :: < ( ) > ( ) , align) , const_impl, runtime_impl)
1472+ self . addr ( ) & ( align - 1 ) == 0
16571473 }
16581474}
16591475
0 commit comments