diff options
Diffstat (limited to 'vendor/rayon/src/slice')
-rw-r--r-- | vendor/rayon/src/slice/quicksort.rs | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/vendor/rayon/src/slice/quicksort.rs b/vendor/rayon/src/slice/quicksort.rs index d71079ec3..2bfc35032 100644 --- a/vendor/rayon/src/slice/quicksort.rs +++ b/vendor/rayon/src/slice/quicksort.rs @@ -5,16 +5,34 @@ //! `rayon_core::join`. use std::cmp; +use std::marker::PhantomData; use std::mem::{self, MaybeUninit}; use std::ptr; /// When dropped, copies from `src` into `dest`. -struct CopyOnDrop<T> { +#[must_use] +struct CopyOnDrop<'a, T> { src: *const T, dest: *mut T, + /// `src` is often a local pointer here, make sure we have appropriate + /// PhantomData so that dropck can protect us. + marker: PhantomData<&'a mut T>, } -impl<T> Drop for CopyOnDrop<T> { +impl<'a, T> CopyOnDrop<'a, T> { + /// Construct from a source pointer and a destination + /// Assumes dest lives longer than src, since there is no easy way to + /// copy down lifetime information from another pointer + unsafe fn new(src: &'a T, dest: *mut T) -> Self { + CopyOnDrop { + src, + dest, + marker: PhantomData, + } + } +} + +impl<T> Drop for CopyOnDrop<'_, T> { fn drop(&mut self) { // SAFETY: This is a helper class. // Please refer to its usage for correctness. @@ -54,10 +72,7 @@ where // into the slice. let tmp = mem::ManuallyDrop::new(ptr::read(v.get_unchecked(0))); let v = v.as_mut_ptr(); - let mut hole = CopyOnDrop { - src: &*tmp, - dest: v.add(1), - }; + let mut hole = CopyOnDrop::new(&*tmp, v.add(1)); ptr::copy_nonoverlapping(v.add(1), v.add(0), 1); for i in 2..len { @@ -103,10 +118,7 @@ where // into the slice. let tmp = mem::ManuallyDrop::new(ptr::read(v.get_unchecked(len - 1))); let v = v.as_mut_ptr(); - let mut hole = CopyOnDrop { - src: &*tmp, - dest: v.add(len - 2), - }; + let mut hole = CopyOnDrop::new(&*tmp, v.add(len - 2)); ptr::copy_nonoverlapping(v.add(len - 2), v.add(len - 1), 1); for i in (0..len - 2).rev() { @@ -510,10 +522,7 @@ where // SAFETY: `pivot` is a reference to the first element of `v`, so `ptr::read` is safe. let tmp = mem::ManuallyDrop::new(unsafe { ptr::read(pivot) }); - let _pivot_guard = CopyOnDrop { - src: &*tmp, - dest: pivot, - }; + let _pivot_guard = unsafe { CopyOnDrop::new(&*tmp, pivot) }; let pivot = &*tmp; // Find the first pair of out-of-order elements. @@ -569,10 +578,7 @@ where // operation panics, the pivot will be automatically written back into the slice. // SAFETY: The pointer here is valid because it is obtained from a reference to a slice. let tmp = mem::ManuallyDrop::new(unsafe { ptr::read(pivot) }); - let _pivot_guard = CopyOnDrop { - src: &*tmp, - dest: pivot, - }; + let _pivot_guard = unsafe { CopyOnDrop::new(&*tmp, pivot) }; let pivot = &*tmp; // Now partition the slice. |