|
1 | 1 | use super::*; |
2 | 2 | use crate::cmp::Ordering::{self, Equal, Greater, Less}; |
3 | | -use crate::intrinsics; |
| 3 | +use crate::intrinsics::{self, const_eval_select}; |
4 | 4 | use crate::mem; |
5 | 5 | use crate::slice::{self, SliceIndex}; |
6 | 6 |
|
@@ -34,12 +34,23 @@ impl<T: ?Sized> *const T { |
34 | 34 | #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")] |
35 | 35 | #[inline] |
36 | 36 | pub const fn is_null(self) -> bool { |
37 | | - // Compare via a cast to a thin pointer, so fat pointers are only |
38 | | - // considering their "data" part for null-ness. |
39 | | - match (self as *const u8).guaranteed_eq(null()) { |
40 | | - None => false, |
41 | | - Some(res) => res, |
| 37 | + #[inline] |
| 38 | + fn runtime_impl(ptr: *const u8) -> bool { |
| 39 | + ptr.addr() == 0 |
42 | 40 | } |
| 41 | + |
| 42 | + #[inline] |
| 43 | + const fn const_impl(ptr: *const u8) -> bool { |
| 44 | + // Compare via a cast to a thin pointer, so fat pointers are only |
| 45 | + // considering their "data" part for null-ness. |
| 46 | + match (ptr).guaranteed_eq(null_mut()) { |
| 47 | + None => false, |
| 48 | + Some(res) => res, |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + // SAFETY: The two versions are equivalent at runtime. |
| 53 | + unsafe { const_eval_select((self as *const u8,), const_impl, runtime_impl) } |
43 | 54 | } |
44 | 55 |
|
45 | 56 | /// Casts to a pointer of another type. |
@@ -1587,11 +1598,22 @@ impl<T: ?Sized> *const T { |
1587 | 1598 | panic!("is_aligned_to: align is not a power-of-two"); |
1588 | 1599 | } |
1589 | 1600 |
|
1590 | | - // We can't use the address of `self` in a `const fn`, so we use `align_offset` instead. |
1591 | | - // The cast to `()` is used to |
1592 | | - // 1. deal with fat pointers; and |
1593 | | - // 2. ensure that `align_offset` doesn't actually try to compute an offset. |
1594 | | - self.cast::<()>().align_offset(align) == 0 |
| 1601 | + #[inline] |
| 1602 | + fn runtime_impl(ptr: *const (), align: usize) -> bool { |
| 1603 | + ptr.addr() & (align - 1) == 0 |
| 1604 | + } |
| 1605 | + |
| 1606 | + #[inline] |
| 1607 | + const fn const_impl(ptr: *const (), align: usize) -> bool { |
| 1608 | + // We can't use the address of `self` in a `const fn`, so we use `align_offset` instead. |
| 1609 | + // The cast to `()` is used to |
| 1610 | + // 1. deal with fat pointers; and |
| 1611 | + // 2. ensure that `align_offset` doesn't actually try to compute an offset. |
| 1612 | + ptr.align_offset(align) == 0 |
| 1613 | + } |
| 1614 | + |
| 1615 | + // SAFETY: The two versions are equivalent at runtime. |
| 1616 | + unsafe { const_eval_select((self.cast::<()>(), align), const_impl, runtime_impl) } |
1595 | 1617 | } |
1596 | 1618 | } |
1597 | 1619 |
|
|
0 commit comments