about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/hint.rs9
-rw-r--r--library/core/src/num/nonzero.rs8
-rw-r--r--library/core/src/ops/index_range.rs13
-rw-r--r--library/core/src/ptr/alignment.rs12
-rw-r--r--library/core/src/slice/index.rs75
-rw-r--r--library/core/src/slice/mod.rs67
-rw-r--r--library/core/src/str/traits.rs46
7 files changed, 98 insertions, 132 deletions
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index ff177c70d39..8e23d6bea3b 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -98,12 +98,13 @@ use crate::intrinsics;
 #[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 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
     // be upheld by the caller.
-    unsafe {
-        intrinsics::assert_unsafe_precondition!("hint::unreachable_unchecked must never be reached", () => false);
-        intrinsics::unreachable()
-    }
+    unsafe { intrinsics::unreachable() }
 }
 
 /// Emits a machine instruction to signal the processor that it is running in
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 7f8d673c179..cc94ee280c6 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -75,12 +75,12 @@ macro_rules! nonzero_integers {
                 #[must_use]
                 #[inline]
                 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.
                     unsafe {
-                        core::intrinsics::assert_unsafe_precondition!(
-                            concat!(stringify!($Ty), "::new_unchecked requires a non-zero argument"),
-                            (n: $Int) => n != 0
-                        );
                         Self(n)
                     }
                 }
diff --git a/library/core/src/ops/index_range.rs b/library/core/src/ops/index_range.rs
index 265022a394e..743799c4b3e 100644
--- a/library/core/src/ops/index_range.rs
+++ b/library/core/src/ops/index_range.rs
@@ -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::num::NonZeroUsize;
 
@@ -19,13 +19,10 @@ impl IndexRange {
     /// - `start <= end`
     #[inline]
     pub const unsafe fn new_unchecked(start: usize, end: usize) -> Self {
-        // SAFETY: comparisons on usize are pure
-        unsafe {
-            assert_unsafe_precondition!(
-               "IndexRange::new_unchecked requires `start <= end`",
-                (start: usize, end: usize) => start <= end
-            )
-        };
+        crate::panic::debug_assert_nounwind!(
+            start <= end,
+            "IndexRange::new_unchecked requires `start <= end`"
+        );
         IndexRange { start, end }
     }
 
diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs
index e578d2257f6..ce176e6fc18 100644
--- a/library/core/src/ptr/alignment.rs
+++ b/library/core/src/ptr/alignment.rs
@@ -1,5 +1,4 @@
 use crate::convert::{TryFrom, TryInto};
-use crate::intrinsics::assert_unsafe_precondition;
 use crate::num::NonZeroUsize;
 use crate::{cmp, fmt, hash, mem, num};
 
@@ -77,13 +76,10 @@ impl Alignment {
     #[rustc_const_unstable(feature = "ptr_alignment_type", issue = "102070")]
     #[inline]
     pub const unsafe fn new_unchecked(align: usize) -> Self {
-        // SAFETY: Precondition passed to the caller.
-        unsafe {
-            assert_unsafe_precondition!(
-               "Alignment::new_unchecked requires a power of two",
-                (align: usize) => align.is_power_of_two()
-            )
-        };
+        crate::panic::debug_assert_nounwind!(
+            align.is_power_of_two(),
+            "Alignment::new_unchecked requires a power of two"
+        );
 
         // SAFETY: By precondition, this must be a power of two, and
         // our variants encompass all possible powers of two.
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index 1da3a87e117..27afd3b8017 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -1,9 +1,9 @@
 //! Indexing implementations for `[T]`.
 
-use crate::intrinsics::assert_unsafe_precondition;
 use crate::intrinsics::const_eval_select;
 use crate::intrinsics::unchecked_sub;
 use crate::ops;
+use crate::panic::debug_assert_nounwind;
 use crate::ptr;
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -225,31 +225,25 @@ unsafe impl<T> SliceIndex<[T]> for usize {
 
     #[inline]
     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
         // 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 {
-            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)
-        }
+        unsafe { slice.as_ptr().add(self) }
     }
 
     #[inline]
     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.
-        unsafe {
-            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)
-        }
+        unsafe { slice.as_mut_ptr().add(self) }
     }
 
     #[inline]
@@ -293,32 +287,25 @@ unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
 
     #[inline]
     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
         // 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 {
-            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())
-        }
+        unsafe { ptr::slice_from_raw_parts(slice.as_ptr().add(self.start()), self.len()) }
     }
 
     #[inline]
     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.
-        unsafe {
-            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())
-        }
+        unsafe { ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start()), self.len()) }
     }
 
     #[inline]
@@ -369,17 +356,15 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
 
     #[inline]
     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
         // 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 and the length calculation cannot overflow.
         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);
             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]
     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.
         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);
             ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len)
         }
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 998ece3afa9..65aae8499f3 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -8,13 +8,14 @@
 
 use crate::cmp::Ordering::{self, Equal, Greater, Less};
 use crate::fmt;
-use crate::intrinsics::{assert_unsafe_precondition, exact_div};
+use crate::intrinsics::exact_div;
 use crate::marker::Copy;
 use crate::mem::{self, SizedTypeProperties};
 use crate::num::NonZeroUsize;
 use crate::ops::{Bound, FnMut, OneSidedRange, Range, RangeBounds};
 use crate::option::Option;
 use crate::option::Option::{None, Some};
+use crate::panic::debug_assert_nounwind;
 use crate::ptr;
 use crate::result::Result;
 use crate::result::Result::{Err, Ok};
@@ -929,14 +930,14 @@ impl<T> [T] {
     #[unstable(feature = "slice_swap_unchecked", issue = "88539")]
     #[rustc_const_unstable(feature = "const_swap", issue = "83163")]
     pub const unsafe fn swap_unchecked(&mut self, a: usize, b: usize) {
-        let this = self;
-        let ptr = this.as_mut_ptr();
+        debug_assert_nounwind!(
+            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()`
         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));
         }
     }
@@ -1269,15 +1270,12 @@ impl<T> [T] {
     #[inline]
     #[must_use]
     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
-        let new_len = unsafe {
-            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)
-        };
+        let new_len = unsafe { exact_div(self.len(), N) };
         // SAFETY: We cast a slice of `new_len * N` elements into
         // a slice of `new_len` many `N` elements chunks.
         unsafe { from_raw_parts(self.as_ptr().cast(), new_len) }
@@ -1426,15 +1424,12 @@ impl<T> [T] {
     #[inline]
     #[must_use]
     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
-        let new_len = unsafe {
-            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)
-        };
+        let new_len = unsafe { exact_div(self.len(), N) };
         // SAFETY: We cast a slice of `new_len * N` elements into
         // a slice of `new_len` many `N` elements chunks.
         unsafe { from_raw_parts_mut(self.as_mut_ptr().cast(), new_len) }
@@ -1967,14 +1962,13 @@ impl<T> [T] {
         let len = self.len();
         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()`
-        unsafe {
-            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))
-        }
+        unsafe { (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.
@@ -2018,17 +2012,16 @@ impl<T> [T] {
         let len = self.len();
         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()`.
         //
         // `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference
         // is fine.
-        unsafe {
-            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))
-        }
+        unsafe { (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.
diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs
index 16fb1dad723..777ad0d818b 100644
--- a/library/core/src/str/traits.rs
+++ b/library/core/src/str/traits.rs
@@ -1,8 +1,8 @@
 //! Trait implementations for `str`.
 
 use crate::cmp::Ordering;
-use crate::intrinsics::assert_unsafe_precondition;
 use crate::ops;
+use crate::panic::debug_assert_nounwind;
 use crate::ptr;
 use crate::slice::SliceIndex;
 
@@ -191,39 +191,35 @@ unsafe impl SliceIndex<str> for ops::Range<usize> {
     #[inline]
     unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output {
         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`
         // which satisfies all the conditions for `add`.
-        let ptr = unsafe {
-            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 ptr = unsafe { slice.as_ptr().add(self.start) };
         let len = self.end - self.start;
         ptr::slice_from_raw_parts(ptr, len) as *const str
     }
     #[inline]
     unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output {
         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`.
-        let ptr = unsafe {
-            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 ptr = unsafe { slice.as_mut_ptr().add(self.start) };
         let len = self.end - self.start;
         ptr::slice_from_raw_parts_mut(ptr, len) as *mut str
     }