|
2 | 2 | //! |
3 | 3 | //! [`core::slice::sort`]: https://doc.rust-lang.org/src/core/slice/sort.rs.html |
4 | 4 |
|
5 | | -use core::{mem, ptr}; |
| 5 | +use core::{marker::PhantomData, mem, ptr}; |
6 | 6 | use ndarray::{s, ArrayViewMut1, IndexLonger}; |
7 | 7 |
|
8 | 8 | // When dropped, copies from `src` into `dest`. |
9 | | -struct InsertionHole<T> { |
10 | | - src: *const T, |
11 | | - dest: *mut T, |
| 9 | +#[must_use] |
| 10 | +pub(super) struct InsertionHole<'a, T> { |
| 11 | + pub(super) src: *const T, |
| 12 | + pub(super) dest: *mut T, |
| 13 | + /// `src` is often a local pointer here, make sure we have appropriate |
| 14 | + /// PhantomData so that dropck can protect us. |
| 15 | + marker: PhantomData<&'a mut T>, |
12 | 16 | } |
13 | 17 |
|
14 | | -impl<T> Drop for InsertionHole<T> { |
| 18 | +impl<'a, T> InsertionHole<'a, T> { |
| 19 | + /// Construct from a source pointer and a destination |
| 20 | + /// Assumes dest lives longer than src, since there is no easy way to |
| 21 | + /// copy down lifetime information from another pointer |
| 22 | + pub(super) unsafe fn new(src: &'a T, dest: *mut T) -> Self { |
| 23 | + Self { |
| 24 | + src, |
| 25 | + dest, |
| 26 | + marker: PhantomData, |
| 27 | + } |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | +impl<T> Drop for InsertionHole<'_, T> { |
15 | 32 | fn drop(&mut self) { |
16 | 33 | // SAFETY: This is a helper class. Please refer to its usage for correctness. Namely, one |
17 | 34 | // must be sure that `src` and `dst` does not overlap as required by |
|
58 | 75 | // If `is_less` panics at any point during the process, `hole` will get dropped and |
59 | 76 | // fill the hole in `v` with `tmp`, thus ensuring that `v` still holds every object it |
60 | 77 | // initially held exactly once. |
61 | | - let mut hole = InsertionHole { |
62 | | - src: &*tmp, |
63 | | - dest: v.view_mut().uget(i - 1), |
64 | | - }; |
| 78 | + let mut hole = InsertionHole::new(&*tmp, v.view_mut().uget(i - 1)); |
65 | 79 | ptr::copy_nonoverlapping(hole.dest, v.view_mut().uget(i), 1); |
66 | 80 |
|
67 | 81 | // SAFETY: We know i is at least 1. |
@@ -126,7 +140,7 @@ where |
126 | 140 | // fill the hole in `v` with `tmp`, thus ensuring that `v` still holds every object it |
127 | 141 | // initially held exactly once. |
128 | 142 | let dest = v.view_mut().uget(1); |
129 | | - let mut hole = InsertionHole { src: &*tmp, dest }; |
| 143 | + let mut hole = InsertionHole::new(&*tmp, dest); |
130 | 144 | ptr::copy_nonoverlapping(dest, v.view_mut().uget(0), 1); |
131 | 145 |
|
132 | 146 | for i in 2..v.len() { |
|
0 commit comments