Skip to content

Commit e193f46

Browse files
authored
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.
2 parents 55562c7 + bc3d719 commit e193f46

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

Diff for: library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
#![feature(maybe_uninit_uninit_array)]
150150
#![feature(ptr_metadata)]
151151
#![feature(slice_ptr_get)]
152+
#![feature(slice_split_at_unchecked)]
152153
#![feature(str_internals)]
153154
#![feature(utf16_extra)]
154155
#![feature(utf16_extra_const)]

Diff for: library/core/src/slice/mod.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -1541,13 +1541,14 @@ impl<T> [T] {
15411541
/// }
15421542
/// ```
15431543
#[stable(feature = "rust1", since = "1.0.0")]
1544+
#[rustc_const_unstable(feature = "const_slice_split_at_not_mut", issue = "none")]
15441545
#[inline]
15451546
#[track_caller]
15461547
#[must_use]
1547-
pub fn split_at(&self, mid: usize) -> (&[T], &[T]) {
1548+
pub const fn split_at(&self, mid: usize) -> (&[T], &[T]) {
15481549
assert!(mid <= self.len());
15491550
// SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
1550-
// fulfills the requirements of `from_raw_parts_mut`.
1551+
// fulfills the requirements of `split_at_unchecked`.
15511552
unsafe { self.split_at_unchecked(mid) }
15521553
}
15531554

@@ -1626,11 +1627,19 @@ impl<T> [T] {
16261627
/// }
16271628
/// ```
16281629
#[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")]
1630+
#[rustc_const_unstable(feature = "slice_split_at_unchecked", issue = "76014")]
16291631
#[inline]
16301632
#[must_use]
1631-
pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) {
1633+
pub const unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) {
1634+
// HACK: the const function `from_raw_parts` is used to make this
1635+
// function const; previously the implementation used
1636+
// `(self.get_unchecked(..mid), self.get_unchecked(mid..))`
1637+
1638+
let len = self.len();
1639+
let ptr = self.as_ptr();
1640+
16321641
// SAFETY: Caller has to check that `0 <= mid <= self.len()`
1633-
unsafe { (self.get_unchecked(..mid), self.get_unchecked(mid..)) }
1642+
unsafe { (from_raw_parts(ptr, mid), from_raw_parts(ptr.add(mid), len - mid)) }
16341643
}
16351644

16361645
/// Divides one mutable slice into two at an index, without doing bounds checking.

0 commit comments

Comments
 (0)