@@ -1358,15 +1358,6 @@ impl<T: ?Sized> *const T {
1358
1358
/// beyond the allocation that the pointer points into. It is up to the caller to ensure that
1359
1359
/// the returned offset is correct in all terms other than alignment.
1360
1360
///
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
- ///
1370
1361
/// # Panics
1371
1362
///
1372
1363
/// The function panics if `align` is not a power-of-two.
@@ -1395,8 +1386,7 @@ impl<T: ?Sized> *const T {
1395
1386
#[ must_use]
1396
1387
#[ inline]
1397
1388
#[ 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
1400
1390
where
1401
1391
T : Sized ,
1402
1392
{
@@ -1431,94 +1421,10 @@ impl<T: ?Sized> *const T {
1431
1421
/// assert!(ptr.is_aligned());
1432
1422
/// assert!(!ptr.wrapping_byte_add(1).is_aligned());
1433
1423
/// ```
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
1517
1424
#[ must_use]
1518
1425
#[ inline]
1519
1426
#[ 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
1522
1428
where
1523
1429
T : Sized ,
1524
1430
{
@@ -1555,105 +1461,15 @@ impl<T: ?Sized> *const T {
1555
1461
///
1556
1462
/// assert_ne!(ptr.is_aligned_to(8), ptr.wrapping_add(1).is_aligned_to(8));
1557
1463
/// ```
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
1632
1464
#[ must_use]
1633
1465
#[ inline]
1634
1466
#[ 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 {
1637
1468
if !align. is_power_of_two ( ) {
1638
1469
panic ! ( "is_aligned_to: align is not a power-of-two" ) ;
1639
1470
}
1640
1471
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
1657
1473
}
1658
1474
}
1659
1475
0 commit comments