summaryrefslogtreecommitdiffstats
path: root/library/core/src/ptr/const_ptr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/core/src/ptr/const_ptr.rs')
-rw-r--r--library/core/src/ptr/const_ptr.rs17
1 files changed, 14 insertions, 3 deletions
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 926189a17..ee69d89a4 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -1,7 +1,7 @@
use super::*;
use crate::cmp::Ordering::{self, Equal, Greater, Less};
use crate::intrinsics::{self, const_eval_select};
-use crate::mem;
+use crate::mem::{self, SizedTypeProperties};
use crate::slice::{self, SliceIndex};
impl<T: ?Sized> *const T {
@@ -30,6 +30,7 @@ impl<T: ?Sized> *const T {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
+ #[rustc_diagnostic_item = "ptr_const_is_null"]
#[inline]
pub const fn is_null(self) -> bool {
#[inline]
@@ -54,6 +55,7 @@ impl<T: ?Sized> *const T {
/// Casts to a pointer of another type.
#[stable(feature = "ptr_cast", since = "1.38.0")]
#[rustc_const_stable(feature = "const_ptr_cast", since = "1.38.0")]
+ #[rustc_diagnostic_item = "const_ptr_cast"]
#[inline(always)]
pub const fn cast<U>(self) -> *const U {
self as _
@@ -994,14 +996,23 @@ impl<T: ?Sized> *const T {
#[stable(feature = "pointer_methods", since = "1.26.0")]
#[must_use = "returns a new pointer rather than modifying its argument"]
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
+ // We could always go back to wrapping if unchecked becomes unacceptable
+ #[rustc_allow_const_fn_unstable(const_int_unchecked_arith)]
#[inline(always)]
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
pub const unsafe fn sub(self, count: usize) -> Self
where
T: Sized,
{
- // SAFETY: the caller must uphold the safety contract for `offset`.
- unsafe { self.offset((count as isize).wrapping_neg()) }
+ if T::IS_ZST {
+ // Pointer arithmetic does nothing when the pointee is a ZST.
+ self
+ } else {
+ // SAFETY: the caller must uphold the safety contract for `offset`.
+ // Because the pointee is *not* a ZST, that means that `count` is
+ // at most `isize::MAX`, and thus the negation cannot overflow.
+ unsafe { self.offset(intrinsics::unchecked_sub(0, count as isize)) }
+ }
}
/// Calculates the offset from a pointer in bytes (convenience for