diff options
| author | Yuki Okushi <jtitor@2k36.org> | 2022-08-26 09:51:43 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-26 09:51:43 +0900 |
| commit | e193f4697f11aed89329177d04c84bcd9ce1b424 (patch) | |
| tree | b9a0db39817ad9cee968558357a92e4114f5f16a | |
| parent | 55562c7ddc0af4799cccae0c7c42328e992a533c (diff) | |
| parent | bc3d7199e1dcb650ef17c7a5370665641819545d (diff) | |
| download | rust-e193f4697f11aed89329177d04c84bcd9ce1b424.tar.gz rust-e193f4697f11aed89329177d04c84bcd9ce1b424.zip | |
Rollup merge of #100076 - tspiteri:const_slice_split_at, r=oli-obk
make slice::{split_at,split_at_unchecked} const functions
Now that `slice::from_raw_parts` is const in stable 1.64, it makes sense to have `split_at` const as well, otherwise unsafe code is required to achieve a const equivalent.
| -rw-r--r-- | library/core/src/lib.rs | 1 | ||||
| -rw-r--r-- | library/core/src/slice/mod.rs | 17 |
2 files changed, 14 insertions, 4 deletions
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 8d04a213f50..afec497ee44 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -149,6 +149,7 @@ #![feature(maybe_uninit_uninit_array)] #![feature(ptr_metadata)] #![feature(slice_ptr_get)] +#![feature(slice_split_at_unchecked)] #![feature(str_internals)] #![feature(utf16_extra)] #![feature(utf16_extra_const)] diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index ea6a70c2f4e..38f05f471cd 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -1541,13 +1541,14 @@ impl<T> [T] { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_slice_split_at_not_mut", issue = "none")] #[inline] #[track_caller] #[must_use] - pub fn split_at(&self, mid: usize) -> (&[T], &[T]) { + pub const fn split_at(&self, mid: usize) -> (&[T], &[T]) { assert!(mid <= self.len()); // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which - // fulfills the requirements of `from_raw_parts_mut`. + // fulfills the requirements of `split_at_unchecked`. unsafe { self.split_at_unchecked(mid) } } @@ -1626,11 +1627,19 @@ impl<T> [T] { /// } /// ``` #[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")] + #[rustc_const_unstable(feature = "slice_split_at_unchecked", issue = "76014")] #[inline] #[must_use] - pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) { + pub const unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) { + // HACK: the const function `from_raw_parts` is used to make this + // function const; previously the implementation used + // `(self.get_unchecked(..mid), self.get_unchecked(mid..))` + + let len = self.len(); + let ptr = self.as_ptr(); + // SAFETY: Caller has to check that `0 <= mid <= self.len()` - unsafe { (self.get_unchecked(..mid), self.get_unchecked(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. |
