Skip to content

Commit 81d95ca

Browse files
committed
slice: Mark rotate_left, rotate_right unstably const
1 parent a84ab0c commit 81d95ca

File tree

2 files changed

+21
-9
lines changed

2 files changed

+21
-9
lines changed

library/core/src/slice/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3668,7 +3668,8 @@ impl<T> [T] {
36683668
/// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
36693669
/// ```
36703670
#[stable(feature = "slice_rotate", since = "1.26.0")]
3671-
pub fn rotate_left(&mut self, mid: usize) {
3671+
#[rustc_const_unstable(feature = "const_slice_rotate", issue = "none")]
3672+
pub const fn rotate_left(&mut self, mid: usize) {
36723673
assert!(mid <= self.len());
36733674
let k = self.len() - mid;
36743675
let p = self.as_mut_ptr();
@@ -3713,7 +3714,8 @@ impl<T> [T] {
37133714
/// assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
37143715
/// ```
37153716
#[stable(feature = "slice_rotate", since = "1.26.0")]
3716-
pub fn rotate_right(&mut self, k: usize) {
3717+
#[rustc_const_unstable(feature = "const_slice_rotate", issue = "none")]
3718+
pub const fn rotate_right(&mut self, k: usize) {
37173719
assert!(k <= self.len());
37183720
let mid = self.len() - k;
37193721
let p = self.as_mut_ptr();

library/core/src/slice/rotate.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::mem::{MaybeUninit, SizedTypeProperties};
2-
use crate::{cmp, ptr};
2+
use crate::ptr;
33

44
type BufType = [usize; 32];
55

@@ -11,7 +11,7 @@ type BufType = [usize; 32];
1111
///
1212
/// The specified range must be valid for reading and writing.
1313
#[inline]
14-
pub(super) unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) {
14+
pub(super) const unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) {
1515
if T::IS_ZST {
1616
return;
1717
}
@@ -21,7 +21,8 @@ pub(super) unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) {
2121
}
2222
// `T` is not a zero-sized type, so it's okay to divide by its size.
2323
if !cfg!(feature = "optimize_for_size")
24-
&& cmp::min(left, right) <= size_of::<BufType>() / size_of::<T>()
24+
// FIXME(const-hack): Use cmp::min when available in const
25+
&& min(left, right) <= size_of::<BufType>() / size_of::<T>()
2526
{
2627
// SAFETY: guaranteed by the caller
2728
unsafe { ptr_rotate_memmove(left, mid, right) };
@@ -45,7 +46,7 @@ pub(super) unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) {
4546
///
4647
/// The specified range must be valid for reading and writing.
4748
#[inline]
48-
unsafe fn ptr_rotate_memmove<T>(left: usize, mid: *mut T, right: usize) {
49+
const unsafe fn ptr_rotate_memmove<T>(left: usize, mid: *mut T, right: usize) {
4950
// The `[T; 0]` here is to ensure this is appropriately aligned for T
5051
let mut rawarray = MaybeUninit::<(BufType, [T; 0])>::uninit();
5152
let buf = rawarray.as_mut_ptr() as *mut T;
@@ -117,7 +118,7 @@ unsafe fn ptr_rotate_memmove<T>(left: usize, mid: *mut T, right: usize) {
117118
///
118119
/// The specified range must be valid for reading and writing.
119120
#[inline]
120-
unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
121+
const unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
121122
// Algorithm 2
122123
// Microbenchmarks indicate that the average performance for random shifts is better all
123124
// the way until about `left + right == 32`, but the worst case performance breaks even
@@ -175,7 +176,9 @@ unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
175176
}
176177
}
177178
// finish the chunk with more rounds
178-
for start in 1..gcd {
179+
// FIXME(const-hack): Use `for start in 1..gcd` when available in const
180+
let mut start = 1;
181+
while start < gcd {
179182
// SAFETY: `gcd` is at most equal to `right` so all values in `1..gcd` are valid for
180183
// reading and writing as per the function's safety contract, see [long-safety-expl]
181184
// above
@@ -201,6 +204,8 @@ unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
201204
i += right;
202205
}
203206
}
207+
208+
start += 1;
204209
}
205210
}
206211

@@ -222,7 +227,7 @@ unsafe fn ptr_rotate_gcd<T>(left: usize, mid: *mut T, right: usize) {
222227
///
223228
/// The specified range must be valid for reading and writing.
224229
#[inline]
225-
unsafe fn ptr_rotate_swap<T>(mut left: usize, mut mid: *mut T, mut right: usize) {
230+
const unsafe fn ptr_rotate_swap<T>(mut left: usize, mut mid: *mut T, mut right: usize) {
226231
loop {
227232
if left >= right {
228233
// Algorithm 3
@@ -265,3 +270,8 @@ unsafe fn ptr_rotate_swap<T>(mut left: usize, mut mid: *mut T, mut right: usize)
265270
}
266271
}
267272
}
273+
274+
// FIXME(const-hack): Use cmp::min when available in const
275+
const fn min(left: usize, right: usize) -> usize {
276+
if right < left { right } else { left }
277+
}

0 commit comments

Comments
 (0)