mirror of https://github.com/rust-lang/rust.git
Convert many `assert_unsafe_precondition` to `debug_assert_nounwind`
This commit is contained in:
parent
4ccec4558f
commit
97c1502066
|
@ -98,12 +98,13 @@ use crate::intrinsics;
|
||||||
#[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")]
|
#[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")]
|
||||||
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
|
||||||
pub const unsafe fn unreachable_unchecked() -> ! {
|
pub const unsafe fn unreachable_unchecked() -> ! {
|
||||||
|
crate::panic::debug_assert_nounwind!(
|
||||||
|
false,
|
||||||
|
"hint::unreachable_unchecked must never be reached"
|
||||||
|
);
|
||||||
// SAFETY: the safety contract for `intrinsics::unreachable` must
|
// SAFETY: the safety contract for `intrinsics::unreachable` must
|
||||||
// be upheld by the caller.
|
// be upheld by the caller.
|
||||||
unsafe {
|
unsafe { intrinsics::unreachable() }
|
||||||
intrinsics::assert_unsafe_precondition!("hint::unreachable_unchecked must never be reached", () => false);
|
|
||||||
intrinsics::unreachable()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Emits a machine instruction to signal the processor that it is running in
|
/// Emits a machine instruction to signal the processor that it is running in
|
||||||
|
|
|
@ -75,12 +75,12 @@ macro_rules! nonzero_integers {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const unsafe fn new_unchecked(n: $Int) -> Self {
|
pub const unsafe fn new_unchecked(n: $Int) -> Self {
|
||||||
|
crate::panic::debug_assert_nounwind!(
|
||||||
|
n != 0,
|
||||||
|
concat!(stringify!($Ty), "::new_unchecked requires a non-zero argument")
|
||||||
|
);
|
||||||
// SAFETY: this is guaranteed to be safe by the caller.
|
// SAFETY: this is guaranteed to be safe by the caller.
|
||||||
unsafe {
|
unsafe {
|
||||||
core::intrinsics::assert_unsafe_precondition!(
|
|
||||||
concat!(stringify!($Ty), "::new_unchecked requires a non-zero argument"),
|
|
||||||
(n: $Int) => n != 0
|
|
||||||
);
|
|
||||||
Self(n)
|
Self(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::intrinsics::{assert_unsafe_precondition, unchecked_add, unchecked_sub};
|
use crate::intrinsics::{unchecked_add, unchecked_sub};
|
||||||
use crate::iter::{FusedIterator, TrustedLen};
|
use crate::iter::{FusedIterator, TrustedLen};
|
||||||
use crate::num::NonZeroUsize;
|
use crate::num::NonZeroUsize;
|
||||||
|
|
||||||
|
@ -19,13 +19,10 @@ impl IndexRange {
|
||||||
/// - `start <= end`
|
/// - `start <= end`
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const unsafe fn new_unchecked(start: usize, end: usize) -> Self {
|
pub const unsafe fn new_unchecked(start: usize, end: usize) -> Self {
|
||||||
// SAFETY: comparisons on usize are pure
|
crate::panic::debug_assert_nounwind!(
|
||||||
unsafe {
|
start <= end,
|
||||||
assert_unsafe_precondition!(
|
"IndexRange::new_unchecked requires `start <= end`"
|
||||||
"IndexRange::new_unchecked requires `start <= end`",
|
);
|
||||||
(start: usize, end: usize) => start <= end
|
|
||||||
)
|
|
||||||
};
|
|
||||||
IndexRange { start, end }
|
IndexRange { start, end }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::convert::{TryFrom, TryInto};
|
use crate::convert::{TryFrom, TryInto};
|
||||||
use crate::intrinsics::assert_unsafe_precondition;
|
|
||||||
use crate::num::NonZeroUsize;
|
use crate::num::NonZeroUsize;
|
||||||
use crate::{cmp, fmt, hash, mem, num};
|
use crate::{cmp, fmt, hash, mem, num};
|
||||||
|
|
||||||
|
@ -77,13 +76,10 @@ impl Alignment {
|
||||||
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
|
#[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const unsafe fn new_unchecked(align: usize) -> Self {
|
pub const unsafe fn new_unchecked(align: usize) -> Self {
|
||||||
// SAFETY: Precondition passed to the caller.
|
crate::panic::debug_assert_nounwind!(
|
||||||
unsafe {
|
align.is_power_of_two(),
|
||||||
assert_unsafe_precondition!(
|
"Alignment::new_unchecked requires a power of two"
|
||||||
"Alignment::new_unchecked requires a power of two",
|
);
|
||||||
(align: usize) => align.is_power_of_two()
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
// SAFETY: By precondition, this must be a power of two, and
|
// SAFETY: By precondition, this must be a power of two, and
|
||||||
// our variants encompass all possible powers of two.
|
// our variants encompass all possible powers of two.
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
//! Indexing implementations for `[T]`.
|
//! Indexing implementations for `[T]`.
|
||||||
|
|
||||||
use crate::intrinsics::assert_unsafe_precondition;
|
|
||||||
use crate::intrinsics::const_eval_select;
|
use crate::intrinsics::const_eval_select;
|
||||||
use crate::intrinsics::unchecked_sub;
|
use crate::intrinsics::unchecked_sub;
|
||||||
use crate::ops;
|
use crate::ops;
|
||||||
|
use crate::panic::debug_assert_nounwind;
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -225,31 +225,25 @@ unsafe impl<T> SliceIndex<[T]> for usize {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
|
||||||
let this = self;
|
debug_assert_nounwind!(
|
||||||
|
self < slice.len(),
|
||||||
|
"slice::get_unchecked requires that the index is within the slice",
|
||||||
|
);
|
||||||
// SAFETY: the caller guarantees that `slice` is not dangling, so it
|
// SAFETY: the caller guarantees that `slice` is not dangling, so it
|
||||||
// cannot be longer than `isize::MAX`. They also guarantee that
|
// cannot be longer than `isize::MAX`. They also guarantee that
|
||||||
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
|
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
|
||||||
// so the call to `add` is safe.
|
// so the call to `add` is safe.
|
||||||
unsafe {
|
unsafe { slice.as_ptr().add(self) }
|
||||||
assert_unsafe_precondition!(
|
|
||||||
"slice::get_unchecked requires that the index is within the slice",
|
|
||||||
[T](this: usize, slice: *const [T]) => this < slice.len()
|
|
||||||
);
|
|
||||||
slice.as_ptr().add(self)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
|
||||||
let this = self;
|
debug_assert_nounwind!(
|
||||||
|
self < slice.len(),
|
||||||
|
"slice::get_unchecked_mut requires that the index is within the slice",
|
||||||
|
);
|
||||||
// SAFETY: see comments for `get_unchecked` above.
|
// SAFETY: see comments for `get_unchecked` above.
|
||||||
unsafe {
|
unsafe { slice.as_mut_ptr().add(self) }
|
||||||
assert_unsafe_precondition!(
|
|
||||||
"slice::get_unchecked_mut requires that the index is within the slice",
|
|
||||||
[T](this: usize, slice: *mut [T]) => this < slice.len()
|
|
||||||
);
|
|
||||||
slice.as_mut_ptr().add(self)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -293,32 +287,25 @@ unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
|
||||||
let end = self.end();
|
debug_assert_nounwind!(
|
||||||
|
self.end() <= slice.len(),
|
||||||
|
"slice::get_unchecked requires that the index is within the slice"
|
||||||
|
);
|
||||||
// SAFETY: the caller guarantees that `slice` is not dangling, so it
|
// SAFETY: the caller guarantees that `slice` is not dangling, so it
|
||||||
// cannot be longer than `isize::MAX`. They also guarantee that
|
// cannot be longer than `isize::MAX`. They also guarantee that
|
||||||
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
|
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
|
||||||
// so the call to `add` is safe.
|
// so the call to `add` is safe.
|
||||||
|
unsafe { ptr::slice_from_raw_parts(slice.as_ptr().add(self.start()), self.len()) }
|
||||||
unsafe {
|
|
||||||
assert_unsafe_precondition!(
|
|
||||||
"slice::get_unchecked requires that the index is within the slice",
|
|
||||||
[T](end: usize, slice: *const [T]) => end <= slice.len()
|
|
||||||
);
|
|
||||||
ptr::slice_from_raw_parts(slice.as_ptr().add(self.start()), self.len())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
|
||||||
let end = self.end();
|
debug_assert_nounwind!(
|
||||||
|
self.end() <= slice.len(),
|
||||||
|
"slice::get_unchecked_mut requires that the index is within the slice",
|
||||||
|
);
|
||||||
// SAFETY: see comments for `get_unchecked` above.
|
// SAFETY: see comments for `get_unchecked` above.
|
||||||
unsafe {
|
unsafe { ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start()), self.len()) }
|
||||||
assert_unsafe_precondition!(
|
|
||||||
"slice::get_unchecked_mut requires that the index is within the slice",
|
|
||||||
[T](end: usize, slice: *mut [T]) => end <= slice.len()
|
|
||||||
);
|
|
||||||
ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start()), self.len())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -369,17 +356,15 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
|
unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
|
||||||
let this = ops::Range { ..self };
|
debug_assert_nounwind!(
|
||||||
|
self.end >= self.start && self.end <= slice.len(),
|
||||||
|
"slice::get_unchecked requires that the range is within the slice",
|
||||||
|
);
|
||||||
// SAFETY: the caller guarantees that `slice` is not dangling, so it
|
// SAFETY: the caller guarantees that `slice` is not dangling, so it
|
||||||
// cannot be longer than `isize::MAX`. They also guarantee that
|
// cannot be longer than `isize::MAX`. They also guarantee that
|
||||||
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
|
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
|
||||||
// so the call to `add` is safe and the length calculation cannot overflow.
|
// so the call to `add` is safe and the length calculation cannot overflow.
|
||||||
unsafe {
|
unsafe {
|
||||||
assert_unsafe_precondition!(
|
|
||||||
"slice::get_unchecked requires that the range is within the slice",
|
|
||||||
[T](this: ops::Range<usize>, slice: *const [T]) =>
|
|
||||||
this.end >= this.start && this.end <= slice.len()
|
|
||||||
);
|
|
||||||
let new_len = unchecked_sub(self.end, self.start);
|
let new_len = unchecked_sub(self.end, self.start);
|
||||||
ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len)
|
ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len)
|
||||||
}
|
}
|
||||||
|
@ -387,14 +372,12 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
|
unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
|
||||||
let this = ops::Range { ..self };
|
debug_assert_nounwind!(
|
||||||
|
self.end >= self.start && self.end <= slice.len(),
|
||||||
|
"slice::get_unchecked_mut requires that the range is within the slice",
|
||||||
|
);
|
||||||
// SAFETY: see comments for `get_unchecked` above.
|
// SAFETY: see comments for `get_unchecked` above.
|
||||||
unsafe {
|
unsafe {
|
||||||
assert_unsafe_precondition!(
|
|
||||||
"slice::get_unchecked_mut requires that the range is within the slice",
|
|
||||||
[T](this: ops::Range<usize>, slice: *mut [T]) =>
|
|
||||||
this.end >= this.start && this.end <= slice.len()
|
|
||||||
);
|
|
||||||
let new_len = unchecked_sub(self.end, self.start);
|
let new_len = unchecked_sub(self.end, self.start);
|
||||||
ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len)
|
ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,14 @@
|
||||||
|
|
||||||
use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::intrinsics::{assert_unsafe_precondition, exact_div};
|
use crate::intrinsics::exact_div;
|
||||||
use crate::marker::Copy;
|
use crate::marker::Copy;
|
||||||
use crate::mem::{self, SizedTypeProperties};
|
use crate::mem::{self, SizedTypeProperties};
|
||||||
use crate::num::NonZeroUsize;
|
use crate::num::NonZeroUsize;
|
||||||
use crate::ops::{Bound, FnMut, OneSidedRange, Range, RangeBounds};
|
use crate::ops::{Bound, FnMut, OneSidedRange, Range, RangeBounds};
|
||||||
use crate::option::Option;
|
use crate::option::Option;
|
||||||
use crate::option::Option::{None, Some};
|
use crate::option::Option::{None, Some};
|
||||||
|
use crate::panic::debug_assert_nounwind;
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
use crate::result::Result;
|
use crate::result::Result;
|
||||||
use crate::result::Result::{Err, Ok};
|
use crate::result::Result::{Err, Ok};
|
||||||
|
@ -929,14 +930,14 @@ impl<T> [T] {
|
||||||
#[unstable(feature = "slice_swap_unchecked", issue = "88539")]
|
#[unstable(feature = "slice_swap_unchecked", issue = "88539")]
|
||||||
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
|
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
|
||||||
pub const unsafe fn swap_unchecked(&mut self, a: usize, b: usize) {
|
pub const unsafe fn swap_unchecked(&mut self, a: usize, b: usize) {
|
||||||
let this = self;
|
debug_assert_nounwind!(
|
||||||
let ptr = this.as_mut_ptr();
|
a < self.len() && b < self.len(),
|
||||||
|
"slice::swap_unchecked requires that the indices are within the slice",
|
||||||
|
);
|
||||||
|
|
||||||
|
let ptr = self.as_mut_ptr();
|
||||||
// SAFETY: caller has to guarantee that `a < self.len()` and `b < self.len()`
|
// SAFETY: caller has to guarantee that `a < self.len()` and `b < self.len()`
|
||||||
unsafe {
|
unsafe {
|
||||||
assert_unsafe_precondition!(
|
|
||||||
"slice::swap_unchecked requires that the indices are within the slice",
|
|
||||||
[T](a: usize, b: usize, this: &mut [T]) => a < this.len() && b < this.len()
|
|
||||||
);
|
|
||||||
ptr::swap(ptr.add(a), ptr.add(b));
|
ptr::swap(ptr.add(a), ptr.add(b));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1269,15 +1270,12 @@ impl<T> [T] {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]] {
|
pub const unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]] {
|
||||||
let this = self;
|
debug_assert_nounwind!(
|
||||||
|
N != 0 && self.len() % N == 0,
|
||||||
|
"slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks",
|
||||||
|
);
|
||||||
// SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length
|
// SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length
|
||||||
let new_len = unsafe {
|
let new_len = unsafe { exact_div(self.len(), N) };
|
||||||
assert_unsafe_precondition!(
|
|
||||||
"slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks",
|
|
||||||
[T](this: &[T], N: usize) => N != 0 && this.len() % N == 0
|
|
||||||
);
|
|
||||||
exact_div(self.len(), N)
|
|
||||||
};
|
|
||||||
// SAFETY: We cast a slice of `new_len * N` elements into
|
// SAFETY: We cast a slice of `new_len * N` elements into
|
||||||
// a slice of `new_len` many `N` elements chunks.
|
// a slice of `new_len` many `N` elements chunks.
|
||||||
unsafe { from_raw_parts(self.as_ptr().cast(), new_len) }
|
unsafe { from_raw_parts(self.as_ptr().cast(), new_len) }
|
||||||
|
@ -1426,15 +1424,12 @@ impl<T> [T] {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const unsafe fn as_chunks_unchecked_mut<const N: usize>(&mut self) -> &mut [[T; N]] {
|
pub const unsafe fn as_chunks_unchecked_mut<const N: usize>(&mut self) -> &mut [[T; N]] {
|
||||||
let this = &*self;
|
debug_assert_nounwind!(
|
||||||
|
N != 0 && self.len() % N == 0,
|
||||||
|
"slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks",
|
||||||
|
);
|
||||||
// SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length
|
// SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length
|
||||||
let new_len = unsafe {
|
let new_len = unsafe { exact_div(self.len(), N) };
|
||||||
assert_unsafe_precondition!(
|
|
||||||
"slice::as_chunks_unchecked_mut requires `N != 0` and the slice to split exactly into `N`-element chunks",
|
|
||||||
[T](this: &[T], N: usize) => N != 0 && this.len() % N == 0
|
|
||||||
);
|
|
||||||
exact_div(this.len(), N)
|
|
||||||
};
|
|
||||||
// SAFETY: We cast a slice of `new_len * N` elements into
|
// SAFETY: We cast a slice of `new_len * N` elements into
|
||||||
// a slice of `new_len` many `N` elements chunks.
|
// a slice of `new_len` many `N` elements chunks.
|
||||||
unsafe { from_raw_parts_mut(self.as_mut_ptr().cast(), new_len) }
|
unsafe { from_raw_parts_mut(self.as_mut_ptr().cast(), new_len) }
|
||||||
|
@ -1967,14 +1962,13 @@ impl<T> [T] {
|
||||||
let len = self.len();
|
let len = self.len();
|
||||||
let ptr = self.as_ptr();
|
let ptr = self.as_ptr();
|
||||||
|
|
||||||
|
debug_assert_nounwind!(
|
||||||
|
mid <= len,
|
||||||
|
"slice::split_at_unchecked requires the index to be within the slice",
|
||||||
|
);
|
||||||
|
|
||||||
// SAFETY: Caller has to check that `0 <= mid <= self.len()`
|
// SAFETY: Caller has to check that `0 <= mid <= self.len()`
|
||||||
unsafe {
|
unsafe { (from_raw_parts(ptr, mid), from_raw_parts(ptr.add(mid), len - mid)) }
|
||||||
assert_unsafe_precondition!(
|
|
||||||
"slice::split_at_unchecked requires the index to be within the slice",
|
|
||||||
(mid: usize, len: usize) => mid <= len
|
|
||||||
);
|
|
||||||
(from_raw_parts(ptr, mid), from_raw_parts(ptr.add(mid), len - mid))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Divides one mutable slice into two at an index, without doing bounds checking.
|
/// Divides one mutable slice into two at an index, without doing bounds checking.
|
||||||
|
@ -2018,17 +2012,16 @@ impl<T> [T] {
|
||||||
let len = self.len();
|
let len = self.len();
|
||||||
let ptr = self.as_mut_ptr();
|
let ptr = self.as_mut_ptr();
|
||||||
|
|
||||||
|
debug_assert_nounwind!(
|
||||||
|
mid <= len,
|
||||||
|
"slice::split_at_mut_unchecked requires the index to be within the slice",
|
||||||
|
);
|
||||||
|
|
||||||
// SAFETY: Caller has to check that `0 <= mid <= self.len()`.
|
// SAFETY: Caller has to check that `0 <= mid <= self.len()`.
|
||||||
//
|
//
|
||||||
// `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference
|
// `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference
|
||||||
// is fine.
|
// is fine.
|
||||||
unsafe {
|
unsafe { (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid)) }
|
||||||
assert_unsafe_precondition!(
|
|
||||||
"slice::split_at_mut_unchecked requires the index to be within the slice",
|
|
||||||
(mid: usize, len: usize) => mid <= len
|
|
||||||
);
|
|
||||||
(from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Divides one slice into an array and a remainder slice at an index.
|
/// Divides one slice into an array and a remainder slice at an index.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
//! Trait implementations for `str`.
|
//! Trait implementations for `str`.
|
||||||
|
|
||||||
use crate::cmp::Ordering;
|
use crate::cmp::Ordering;
|
||||||
use crate::intrinsics::assert_unsafe_precondition;
|
|
||||||
use crate::ops;
|
use crate::ops;
|
||||||
|
use crate::panic::debug_assert_nounwind;
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
use crate::slice::SliceIndex;
|
use crate::slice::SliceIndex;
|
||||||
|
|
||||||
|
@ -191,39 +191,35 @@ unsafe impl SliceIndex<str> for ops::Range<usize> {
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
|
unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
|
||||||
let slice = slice as *const [u8];
|
let slice = slice as *const [u8];
|
||||||
|
|
||||||
|
debug_assert_nounwind!(
|
||||||
|
// We'd like to check that the bounds are on char boundaries,
|
||||||
|
// but there's not really a way to do so without reading
|
||||||
|
// behind the pointer, which has aliasing implications.
|
||||||
|
// It's also not possible to move this check up to
|
||||||
|
// `str::get_unchecked` without adding a special function
|
||||||
|
// to `SliceIndex` just for this.
|
||||||
|
self.end >= self.start && self.end <= slice.len(),
|
||||||
|
"str::get_unchecked requires that the range is within the string slice",
|
||||||
|
);
|
||||||
|
|
||||||
// SAFETY: the caller guarantees that `self` is in bounds of `slice`
|
// SAFETY: the caller guarantees that `self` is in bounds of `slice`
|
||||||
// which satisfies all the conditions for `add`.
|
// which satisfies all the conditions for `add`.
|
||||||
let ptr = unsafe {
|
let ptr = unsafe { slice.as_ptr().add(self.start) };
|
||||||
let this = ops::Range { ..self };
|
|
||||||
assert_unsafe_precondition!(
|
|
||||||
"str::get_unchecked requires that the range is within the string slice",
|
|
||||||
(this: ops::Range<usize>, slice: *const [u8]) =>
|
|
||||||
// We'd like to check that the bounds are on char boundaries,
|
|
||||||
// but there's not really a way to do so without reading
|
|
||||||
// behind the pointer, which has aliasing implications.
|
|
||||||
// It's also not possible to move this check up to
|
|
||||||
// `str::get_unchecked` without adding a special function
|
|
||||||
// to `SliceIndex` just for this.
|
|
||||||
this.end >= this.start && this.end <= slice.len()
|
|
||||||
);
|
|
||||||
slice.as_ptr().add(self.start)
|
|
||||||
};
|
|
||||||
let len = self.end - self.start;
|
let len = self.end - self.start;
|
||||||
ptr::slice_from_raw_parts(ptr, len) as *const str
|
ptr::slice_from_raw_parts(ptr, len) as *const str
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
|
unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
|
||||||
let slice = slice as *mut [u8];
|
let slice = slice as *mut [u8];
|
||||||
|
|
||||||
|
debug_assert_nounwind!(
|
||||||
|
self.end >= self.start && self.end <= slice.len(),
|
||||||
|
"str::get_unchecked_mut requires that the range is within the string slice",
|
||||||
|
);
|
||||||
|
|
||||||
// SAFETY: see comments for `get_unchecked`.
|
// SAFETY: see comments for `get_unchecked`.
|
||||||
let ptr = unsafe {
|
let ptr = unsafe { slice.as_mut_ptr().add(self.start) };
|
||||||
let this = ops::Range { ..self };
|
|
||||||
assert_unsafe_precondition!(
|
|
||||||
"str::get_unchecked_mut requires that the range is within the string slice",
|
|
||||||
(this: ops::Range<usize>, slice: *mut [u8]) =>
|
|
||||||
this.end >= this.start && this.end <= slice.len()
|
|
||||||
);
|
|
||||||
slice.as_mut_ptr().add(self.start)
|
|
||||||
};
|
|
||||||
let len = self.end - self.start;
|
let len = self.end - self.start;
|
||||||
ptr::slice_from_raw_parts_mut(ptr, len) as *mut str
|
ptr::slice_from_raw_parts_mut(ptr, len) as *mut str
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue