From fae54bc7fdd248cb1174c18e545c46d197d90362 Mon Sep 17 00:00:00 2001 From: Eliza Weisman Date: Sun, 28 Mar 2021 10:12:07 -0700 Subject: [PATCH] fix(util): make intrusive list links never Unpin In light of rust-lang/rust#82834, we must ensure that the intrusive linked list pointers never get mutable-noalias optimizations (see also rust-lang/rust#63818). Adding a `PhantomPinned` to the `Links` struct ensures it will always be `!Unpin`, disabling mutable-noalias. Signed-off-by: Eliza Weisman --- util/src/intrusive/list.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/util/src/intrusive/list.rs b/util/src/intrusive/list.rs index 54e1af1f..fd736a70 100644 --- a/util/src/intrusive/list.rs +++ b/util/src/intrusive/list.rs @@ -1,6 +1,4 @@ -use core::fmt; -use core::mem::ManuallyDrop; -use core::ptr::NonNull; +use core::{fmt, marker::PhantomPinned, mem::ManuallyDrop, ptr::NonNull}; pub unsafe trait Linked { type Handle; @@ -38,6 +36,10 @@ pub struct List { pub struct Links { next: Option>, prev: Option>, + /// Linked list links must always be `!Unpin`, in order to ensure that they + /// never recieve LLVM `noalias` annotations; see also + /// https://github.com/rust-lang/rust/issues/63818. + _unpin: PhantomPinned, } pub struct Cursor<'a, T: ?Sized + Linked> { @@ -142,7 +144,7 @@ impl List { pub unsafe fn remove(&mut self, item: NonNull) -> Option { let links = T::links(item).as_mut().take(); tracing::trace!(?self, item.addr = ?item, item.links = ?links, "remove"); - let Links { next, prev } = links; + let Links { next, prev, .. } = links; if let Some(prev) = prev { T::links(prev).as_mut().next = next; @@ -193,6 +195,7 @@ impl Links { Self { next: None, prev: None, + _unpin: PhantomPinned, } } @@ -200,6 +203,7 @@ impl Links { Self { next: self.next.take(), prev: self.next.take(), + _unpin: PhantomPinned, } }