Tell LLVM that the negation in <*const T>::sub
cannot overflow
Today it's just `sub` <https://rust.godbolt.org/z/8EzEPnMr5>; with this PR it's `sub nsw`.
This commit is contained in:
parent
8e7fd55131
commit
ab6e2bc3d0
3 changed files with 58 additions and 5 deletions
|
@ -1,6 +1,7 @@
|
|||
use super::*;
|
||||
use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
||||
use crate::intrinsics::{self, const_eval_select};
|
||||
use crate::mem::SizedTypeProperties;
|
||||
use crate::slice::{self, SliceIndex};
|
||||
|
||||
impl<T: ?Sized> *mut T {
|
||||
|
@ -1095,14 +1096,23 @@ impl<T: ?Sized> *mut 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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue