Auto merge of #106275 - Nilstrieb:const-eval-select-me-some-compile-time, r=thomcc
Use some more `const_eval_select` in pointer methods for compile times Builds on top of #105435 `is_aligned_to` is _huge_ with calling `align_offset`, so this should cut it down a lot. This shows up in https://github.com/rust-lang/rust/issues/65031#issuecomment-1367574340
This commit is contained in:
commit
dd01a163c1
@ -1,6 +1,6 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
||||||
use crate::intrinsics;
|
use crate::intrinsics::{self, const_eval_select};
|
||||||
use crate::mem;
|
use crate::mem;
|
||||||
use crate::slice::{self, SliceIndex};
|
use crate::slice::{self, SliceIndex};
|
||||||
|
|
||||||
@ -34,12 +34,23 @@ impl<T: ?Sized> *const T {
|
|||||||
#[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
|
#[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn is_null(self) -> bool {
|
pub const fn is_null(self) -> bool {
|
||||||
// Compare via a cast to a thin pointer, so fat pointers are only
|
#[inline]
|
||||||
// considering their "data" part for null-ness.
|
fn runtime_impl(ptr: *const u8) -> bool {
|
||||||
match (self as *const u8).guaranteed_eq(null()) {
|
ptr.addr() == 0
|
||||||
None => false,
|
|
||||||
Some(res) => res,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
const fn const_impl(ptr: *const u8) -> bool {
|
||||||
|
// Compare via a cast to a thin pointer, so fat pointers are only
|
||||||
|
// considering their "data" part for null-ness.
|
||||||
|
match (ptr).guaranteed_eq(null_mut()) {
|
||||||
|
None => false,
|
||||||
|
Some(res) => res,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SAFETY: The two versions are equivalent at runtime.
|
||||||
|
unsafe { const_eval_select((self as *const u8,), const_impl, runtime_impl) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Casts to a pointer of another type.
|
/// Casts to a pointer of another type.
|
||||||
@ -1587,11 +1598,22 @@ pub const fn is_aligned_to(self, align: usize) -> bool {
|
|||||||
panic!("is_aligned_to: align is not a power-of-two");
|
panic!("is_aligned_to: align is not a power-of-two");
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can't use the address of `self` in a `const fn`, so we use `align_offset` instead.
|
#[inline]
|
||||||
// The cast to `()` is used to
|
fn runtime_impl(ptr: *const (), align: usize) -> bool {
|
||||||
// 1. deal with fat pointers; and
|
ptr.addr() & (align - 1) == 0
|
||||||
// 2. ensure that `align_offset` doesn't actually try to compute an offset.
|
}
|
||||||
self.cast::<()>().align_offset(align) == 0
|
|
||||||
|
#[inline]
|
||||||
|
const fn const_impl(ptr: *const (), align: usize) -> bool {
|
||||||
|
// We can't use the address of `self` in a `const fn`, so we use `align_offset` instead.
|
||||||
|
// The cast to `()` is used to
|
||||||
|
// 1. deal with fat pointers; and
|
||||||
|
// 2. ensure that `align_offset` doesn't actually try to compute an offset.
|
||||||
|
ptr.align_offset(align) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// SAFETY: The two versions are equivalent at runtime.
|
||||||
|
unsafe { const_eval_select((self.cast::<()>(), align), const_impl, runtime_impl) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
||||||
use crate::intrinsics;
|
use crate::intrinsics::{self, const_eval_select};
|
||||||
use crate::slice::{self, SliceIndex};
|
use crate::slice::{self, SliceIndex};
|
||||||
|
|
||||||
impl<T: ?Sized> *mut T {
|
impl<T: ?Sized> *mut T {
|
||||||
@ -33,12 +33,23 @@ impl<T: ?Sized> *mut T {
|
|||||||
#[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
|
#[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn is_null(self) -> bool {
|
pub const fn is_null(self) -> bool {
|
||||||
// Compare via a cast to a thin pointer, so fat pointers are only
|
#[inline]
|
||||||
// considering their "data" part for null-ness.
|
fn runtime_impl(ptr: *mut u8) -> bool {
|
||||||
match (self as *mut u8).guaranteed_eq(null_mut()) {
|
ptr.addr() == 0
|
||||||
None => false,
|
|
||||||
Some(res) => res,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
const fn const_impl(ptr: *mut u8) -> bool {
|
||||||
|
// Compare via a cast to a thin pointer, so fat pointers are only
|
||||||
|
// considering their "data" part for null-ness.
|
||||||
|
match (ptr).guaranteed_eq(null_mut()) {
|
||||||
|
None => false,
|
||||||
|
Some(res) => res,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SAFETY: The two versions are equivalent at runtime.
|
||||||
|
unsafe { const_eval_select((self as *mut u8,), const_impl, runtime_impl) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Casts to a pointer of another type.
|
/// Casts to a pointer of another type.
|
||||||
@ -1859,11 +1870,22 @@ pub const fn is_aligned_to(self, align: usize) -> bool {
|
|||||||
panic!("is_aligned_to: align is not a power-of-two");
|
panic!("is_aligned_to: align is not a power-of-two");
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can't use the address of `self` in a `const fn`, so we use `align_offset` instead.
|
#[inline]
|
||||||
// The cast to `()` is used to
|
fn runtime_impl(ptr: *mut (), align: usize) -> bool {
|
||||||
// 1. deal with fat pointers; and
|
ptr.addr() & (align - 1) == 0
|
||||||
// 2. ensure that `align_offset` doesn't actually try to compute an offset.
|
}
|
||||||
self.cast::<()>().align_offset(align) == 0
|
|
||||||
|
#[inline]
|
||||||
|
const fn const_impl(ptr: *mut (), align: usize) -> bool {
|
||||||
|
// We can't use the address of `self` in a `const fn`, so we use `align_offset` instead.
|
||||||
|
// The cast to `()` is used to
|
||||||
|
// 1. deal with fat pointers; and
|
||||||
|
// 2. ensure that `align_offset` doesn't actually try to compute an offset.
|
||||||
|
ptr.align_offset(align) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// SAFETY: The two versions are equivalent at runtime.
|
||||||
|
unsafe { const_eval_select((self.cast::<()>(), align), const_impl, runtime_impl) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user