|
8 | 8 |
|
9 | 9 | use crate::cmp::Ordering::{self, Greater, Less}; |
10 | 10 | use crate::fmt; |
11 | | -use crate::intrinsics::{assert_unsafe_precondition, exact_div}; |
| 11 | +use crate::intrinsics::exact_div; |
12 | 12 | use crate::marker::Copy; |
13 | 13 | use crate::mem::{self, SizedTypeProperties}; |
14 | 14 | use crate::num::NonZeroUsize; |
15 | 15 | use crate::ops::{Bound, FnMut, OneSidedRange, Range, RangeBounds}; |
16 | 16 | use crate::option::Option; |
17 | 17 | use crate::option::Option::{None, Some}; |
| 18 | +use crate::panic::debug_assert_nounwind; |
18 | 19 | use crate::ptr; |
19 | 20 | use crate::result::Result; |
20 | 21 | use crate::result::Result::{Err, Ok}; |
@@ -656,14 +657,14 @@ impl<T> [T] { |
656 | 657 | #[unstable(feature = "slice_swap_unchecked", issue = "88539")] |
657 | 658 | #[rustc_const_unstable(feature = "const_swap", issue = "83163")] |
658 | 659 | pub const unsafe fn swap_unchecked(&mut self, a: usize, b: usize) { |
659 | | - let this = self; |
660 | | - let ptr = this.as_mut_ptr(); |
| 660 | + debug_assert_nounwind!( |
| 661 | + a < self.len() && b < self.len(), |
| 662 | + "slice::swap_unchecked requires that the indices are within the slice", |
| 663 | + ); |
| 664 | + |
| 665 | + let ptr = self.as_mut_ptr(); |
661 | 666 | // SAFETY: caller has to guarantee that `a < self.len()` and `b < self.len()` |
662 | 667 | unsafe { |
663 | | - assert_unsafe_precondition!( |
664 | | - "slice::swap_unchecked requires that the indices are within the slice", |
665 | | - [T](a: usize, b: usize, this: &mut [T]) => a < this.len() && b < this.len() |
666 | | - ); |
667 | 668 | ptr::swap(ptr.add(a), ptr.add(b)); |
668 | 669 | } |
669 | 670 | } |
@@ -997,15 +998,12 @@ impl<T> [T] { |
997 | 998 | #[inline] |
998 | 999 | #[must_use] |
999 | 1000 | pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]] { |
1000 | | - let this = self; |
| 1001 | + debug_assert_nounwind!( |
| 1002 | + N != 0 && self.len() % N == 0, |
| 1003 | + "slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks", |
| 1004 | + ); |
1001 | 1005 | // SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length |
1002 | | - let new_len = unsafe { |
1003 | | - assert_unsafe_precondition!( |
1004 | | - "slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks", |
1005 | | - [T](this: &[T], N: usize) => N != 0 && this.len() % N == 0 |
1006 | | - ); |
1007 | | - exact_div(self.len(), N) |
1008 | | - }; |
| 1006 | + let new_len = unsafe { exact_div(self.len(), N) }; |
1009 | 1007 | // SAFETY: We cast a slice of `new_len * N` elements into |
1010 | 1008 | // a slice of `new_len` many `N` elements chunks. |
1011 | 1009 | unsafe { from_raw_parts(self.as_ptr().cast(), new_len) } |
@@ -1154,15 +1152,12 @@ impl<T> [T] { |
1154 | 1152 | #[inline] |
1155 | 1153 | #[must_use] |
1156 | 1154 | pub unsafe fn as_chunks_unchecked_mut<const N: usize>(&mut self) -> &mut [[T; N]] { |
1157 | | - let this = &*self; |
| 1155 | + debug_assert_nounwind!( |
| 1156 | + N != 0 && self.len() % N == 0, |
| 1157 | + "slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks", |
| 1158 | + ); |
1158 | 1159 | // SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length |
1159 | | - let new_len = unsafe { |
1160 | | - assert_unsafe_precondition!( |
1161 | | - "slice::as_chunks_unchecked_mut requires `N != 0` and the slice to split exactly into `N`-element chunks", |
1162 | | - [T](this: &[T], N: usize) => N != 0 && this.len() % N == 0 |
1163 | | - ); |
1164 | | - exact_div(this.len(), N) |
1165 | | - }; |
| 1160 | + let new_len = unsafe { exact_div(self.len(), N) }; |
1166 | 1161 | // SAFETY: We cast a slice of `new_len * N` elements into |
1167 | 1162 | // a slice of `new_len` many `N` elements chunks. |
1168 | 1163 | unsafe { from_raw_parts_mut(self.as_mut_ptr().cast(), new_len) } |
@@ -1694,14 +1689,13 @@ impl<T> [T] { |
1694 | 1689 | let len = self.len(); |
1695 | 1690 | let ptr = self.as_ptr(); |
1696 | 1691 |
|
| 1692 | + debug_assert_nounwind!( |
| 1693 | + mid <= len, |
| 1694 | + "slice::split_at_unchecked requires the index to be within the slice", |
| 1695 | + ); |
| 1696 | + |
1697 | 1697 | // SAFETY: Caller has to check that `0 <= mid <= self.len()` |
1698 | | - unsafe { |
1699 | | - assert_unsafe_precondition!( |
1700 | | - "slice::split_at_unchecked requires the index to be within the slice", |
1701 | | - (mid: usize, len: usize) => mid <= len |
1702 | | - ); |
1703 | | - (from_raw_parts(ptr, mid), from_raw_parts(ptr.add(mid), len - mid)) |
1704 | | - } |
| 1698 | + unsafe { (from_raw_parts(ptr, mid), from_raw_parts(ptr.add(mid), len - mid)) } |
1705 | 1699 | } |
1706 | 1700 |
|
1707 | 1701 | /// Divides one mutable slice into two at an index, without doing bounds checking. |
@@ -1745,17 +1739,16 @@ impl<T> [T] { |
1745 | 1739 | let len = self.len(); |
1746 | 1740 | let ptr = self.as_mut_ptr(); |
1747 | 1741 |
|
| 1742 | + debug_assert_nounwind!( |
| 1743 | + mid <= len, |
| 1744 | + "slice::split_at_mut_unchecked requires the index to be within the slice", |
| 1745 | + ); |
| 1746 | + |
1748 | 1747 | // SAFETY: Caller has to check that `0 <= mid <= self.len()`. |
1749 | 1748 | // |
1750 | 1749 | // `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference |
1751 | 1750 | // is fine. |
1752 | | - unsafe { |
1753 | | - assert_unsafe_precondition!( |
1754 | | - "slice::split_at_mut_unchecked requires the index to be within the slice", |
1755 | | - (mid: usize, len: usize) => mid <= len |
1756 | | - ); |
1757 | | - (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid)) |
1758 | | - } |
| 1751 | + unsafe { (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid)) } |
1759 | 1752 | } |
1760 | 1753 |
|
1761 | 1754 | /// Divides one slice into an array and a remainder slice at an index. |
|
0 commit comments