|
1 |
| -use core::fmt; |
2 |
| -use core::mem::ManuallyDrop; |
3 |
| -use core::ptr::NonNull; |
| 1 | +use core::{fmt, marker::PhantomPinned, mem::ManuallyDrop, ptr::NonNull}; |
4 | 2 |
|
5 | 3 | pub unsafe trait Linked {
|
6 | 4 | type Handle;
|
@@ -38,6 +36,10 @@ pub struct List<T: ?Sized> {
|
38 | 36 | pub struct Links<T: ?Sized> {
|
39 | 37 | next: Option<NonNull<T>>,
|
40 | 38 | prev: Option<NonNull<T>>,
|
| 39 | + /// Linked list links must always be `!Unpin`, in order to ensure that they |
| 40 | + /// never recieve LLVM `noalias` annotations; see also |
| 41 | + /// https://github.com/rust-lang/rust/issues/63818. |
| 42 | + _unpin: PhantomPinned, |
41 | 43 | }
|
42 | 44 |
|
43 | 45 | pub struct Cursor<'a, T: ?Sized + Linked> {
|
@@ -142,7 +144,7 @@ impl<T: ?Sized + Linked> List<T> {
|
142 | 144 | pub unsafe fn remove(&mut self, item: NonNull<T>) -> Option<T::Handle> {
|
143 | 145 | let links = T::links(item).as_mut().take();
|
144 | 146 | tracing::trace!(?self, item.addr = ?item, item.links = ?links, "remove");
|
145 |
| - let Links { next, prev } = links; |
| 147 | + let Links { next, prev, .. } = links; |
146 | 148 |
|
147 | 149 | if let Some(prev) = prev {
|
148 | 150 | T::links(prev).as_mut().next = next;
|
@@ -193,13 +195,15 @@ impl<T: ?Sized> Links<T> {
|
193 | 195 | Self {
|
194 | 196 | next: None,
|
195 | 197 | prev: None,
|
| 198 | + _unpin: PhantomPinned, |
196 | 199 | }
|
197 | 200 | }
|
198 | 201 |
|
199 | 202 | fn take(&mut self) -> Self {
|
200 | 203 | Self {
|
201 | 204 | next: self.next.take(),
|
202 | 205 | prev: self.next.take(),
|
| 206 | + _unpin: PhantomPinned, |
203 | 207 | }
|
204 | 208 | }
|
205 | 209 |
|
|
0 commit comments