-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Use intrinsics::debug_assertions in debug_assert_nounwind #120863
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,7 @@ where | |
{ | ||
type Output = I::Output; | ||
|
||
#[inline] | ||
#[inline(always)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I needed to apply this to fix the test added in #119878, I don't know if this deserves a comment? And if it does, I'm not sure if I should cite the test specifically; that seems rather fragile if the test is renamed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That PR did have the always too so it must have been removed in the meantime. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That PR added an always to |
||
fn index(&self, index: I) -> &I::Output { | ||
index.index(self) | ||
} | ||
|
@@ -24,7 +24,7 @@ impl<T, I> ops::IndexMut<I> for [T] | |
where | ||
I: SliceIndex<[T]>, | ||
{ | ||
#[inline] | ||
#[inline(always)] | ||
fn index_mut(&mut self, index: I) -> &mut I::Output { | ||
index.index_mut(self) | ||
} | ||
|
@@ -227,14 +227,16 @@ unsafe impl<T> SliceIndex<[T]> for usize { | |
unsafe fn get_unchecked(self, slice: *const [T]) -> *const T { | ||
debug_assert_nounwind!( | ||
self < slice.len(), | ||
"slice::get_unchecked requires that the index is within the slice", | ||
"slice::get_unchecked requires that the index is within the slice" | ||
); | ||
// SAFETY: the caller guarantees that `slice` is not dangling, so it | ||
// cannot be longer than `isize::MAX`. They also guarantee that | ||
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`, | ||
// so the call to `add` is safe. | ||
unsafe { | ||
crate::hint::assert_unchecked(self < slice.len()); | ||
// Use intrinsics::assume instead of hint::assert_unchecked so that we don't check the | ||
// precondition of this function twice. | ||
crate::intrinsics::assume(self < slice.len()); | ||
slice.as_ptr().add(self) | ||
} | ||
} | ||
|
@@ -243,7 +245,7 @@ unsafe impl<T> SliceIndex<[T]> for usize { | |
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T { | ||
debug_assert_nounwind!( | ||
self < slice.len(), | ||
"slice::get_unchecked_mut requires that the index is within the slice", | ||
"slice::get_unchecked_mut requires that the index is within the slice" | ||
); | ||
// SAFETY: see comments for `get_unchecked` above. | ||
unsafe { slice.as_mut_ptr().add(self) } | ||
|
@@ -305,8 +307,9 @@ unsafe impl<T> SliceIndex<[T]> for ops::IndexRange { | |
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { | ||
debug_assert_nounwind!( | ||
self.end() <= slice.len(), | ||
"slice::get_unchecked_mut requires that the index is within the slice", | ||
"slice::get_unchecked_mut requires that the index is within the slice" | ||
); | ||
|
||
// SAFETY: see comments for `get_unchecked` above. | ||
unsafe { ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start()), self.len()) } | ||
} | ||
|
@@ -361,8 +364,9 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> { | |
unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { | ||
debug_assert_nounwind!( | ||
self.end >= self.start && self.end <= slice.len(), | ||
"slice::get_unchecked requires that the range is within the slice", | ||
"slice::get_unchecked requires that the range is within the slice" | ||
); | ||
|
||
// SAFETY: the caller guarantees that `slice` is not dangling, so it | ||
// cannot be longer than `isize::MAX`. They also guarantee that | ||
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`, | ||
|
@@ -377,7 +381,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> { | |
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { | ||
debug_assert_nounwind!( | ||
self.end >= self.start && self.end <= slice.len(), | ||
"slice::get_unchecked_mut requires that the range is within the slice", | ||
"slice::get_unchecked_mut requires that the range is within the slice" | ||
); | ||
// SAFETY: see comments for `get_unchecked` above. | ||
unsafe { | ||
|
@@ -386,7 +390,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> { | |
} | ||
} | ||
|
||
#[inline] | ||
#[inline(always)] | ||
fn index(self, slice: &[T]) -> &[T] { | ||
if self.start > self.end { | ||
slice_index_order_fail(self.start, self.end); | ||
|
@@ -436,7 +440,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> { | |
unsafe { (0..self.end).get_unchecked_mut(slice) } | ||
} | ||
|
||
#[inline] | ||
#[inline(always)] | ||
fn index(self, slice: &[T]) -> &[T] { | ||
(0..self.end).index(slice) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this violates the contract for
intrinsics::debug_assertions
. We said this should only be used if there is anyway UB (meaning: language UB) when the condition is violated, butdebug_assert_nounwind
is used in places where there is only library UB.EDIT: #121583 adds some FIXMEs.