Skip to content

Commit b658896

Browse files
committed
Avoid miri error in slice::sort under Stacked Borrows
See comment in code. Fixes: #131065
1 parent 94a0cd1 commit b658896

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

library/alloctests/tests/sort/tests.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,13 @@ fn sort_vs_sort_by_impl<S: Sort>() {
362362
assert_eq!(input_sort_by, expected);
363363
}
364364

365+
pub fn box_value_impl<S: Sort>() {
366+
for len in [3, 9, 35, 56, 132] {
367+
test_is_sorted::<Box<i32>, S>(len, Box::new, patterns::random);
368+
test_is_sorted::<Box<i32>, S>(len, Box::new, |len| patterns::random_sorted(len, 80.0));
369+
}
370+
}
371+
365372
gen_sort_test_fns_with_default_patterns!(
366373
correct_i32,
367374
|len, pattern_fn| test_is_sorted::<i32, S>(len, |val| val, pattern_fn),
@@ -967,6 +974,7 @@ define_instantiate_sort_tests!(
967974
[miri_yes, fixed_seed_rand_vec_prefix],
968975
[miri_yes, int_edge],
969976
[miri_yes, sort_vs_sort_by],
977+
[miri_yes, box_value],
970978
[miri_yes, correct_i32_random],
971979
[miri_yes, correct_i32_random_z1],
972980
[miri_yes, correct_i32_random_d2],

library/core/src/slice/sort/stable/quicksort.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! This module contains a stable quicksort and partition implementation.
22
3-
use crate::mem::{ManuallyDrop, MaybeUninit};
3+
use crate::mem::MaybeUninit;
44
use crate::slice::sort::shared::FreezeMarker;
55
use crate::slice::sort::shared::pivot::choose_pivot;
66
use crate::slice::sort::shared::smallsort::StableSmallSortTypeImpl;
@@ -41,8 +41,10 @@ pub fn quicksort<T, F: FnMut(&T, &T) -> bool>(
4141
// SAFETY: We only access the temporary copy for Freeze types, otherwise
4242
// self-modifications via `is_less` would not be observed and this would
4343
// be unsound. Our temporary copy does not escape this scope.
44-
let pivot_copy = unsafe { ManuallyDrop::new(ptr::read(&v[pivot_pos])) };
45-
let pivot_ref = (!has_direct_interior_mutability::<T>()).then_some(&*pivot_copy);
44+
let pivot_copy = unsafe { ptr::read((&raw const v[pivot_pos]).cast::<MaybeUninit<T>>()) };
45+
// SAFETY: We created the value in an init state.
46+
let pivot_ref =
47+
(!has_direct_interior_mutability::<T>()).then_some(unsafe { &*pivot_copy.as_ptr() });
4648

4749
// We choose a pivot, and check if this pivot is equal to our left
4850
// ancestor. If true, we do a partition putting equal elements on the

0 commit comments

Comments
 (0)