|
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