diff --git a/cordyceps/src/list.rs b/cordyceps/src/list.rs index 4695ae7c..9555bc1f 100644 --- a/cordyceps/src/list.rs +++ b/cordyceps/src/list.rs @@ -259,7 +259,7 @@ pub struct Iter<'list, T: Linked> + ?Sized> { /// the returned `NonNull` nodes. See [`List::iter_raw()`] for /// more details on safety invariants. pub struct IterRaw<'list, T: Linked> + ?Sized> { - _list: &'list List, + _list: &'list mut List, /// The current node when iterating head -> tail. curr: Link, @@ -963,10 +963,10 @@ impl> + ?Sized> List { #[must_use] pub fn iter_raw(&mut self) -> IterRaw<'_, T> { IterRaw { - _list: self, + len: self.len(), curr: self.head, curr_back: self.tail, - len: self.len(), + _list: self, } } @@ -1451,7 +1451,13 @@ impl> + ?Sized> DoubleEndedIterator for IterMut<'_, T> { impl> + ?Sized> iter::FusedIterator for IterMut<'_, T> {} -// === impl RawIter ==== +// === impl IterRaw ==== + +/// ## SAFETY +/// +/// IterRaw contains an exclusive reference to the given List, and objects +/// within the list are pinned. Therefore, `Send`-ing the iterator is sound. +unsafe impl> + ?Sized> Send for IterRaw<'_, T> {} impl> + ?Sized> Iterator for IterRaw<'_, T> { type Item = NonNull; @@ -1496,7 +1502,7 @@ impl> + ?Sized> DoubleEndedIterator for IterRaw<'_, T> { let curr = self.curr_back.take()?; self.len -= 1; unsafe { - // safety: it is safe for us to borrow `curr`, because the iterator + // safety: it is safe for us to borrow `curr_back`, because the iterator // borrows the `List`, ensuring that the list will not be dropped // while the iterator exists. the returned item will not outlive the // iterator. diff --git a/cordyceps/src/list/tests/iter_raw.rs b/cordyceps/src/list/tests/iter_raw.rs index c276ef64..c106a5da 100644 --- a/cordyceps/src/list/tests/iter_raw.rs +++ b/cordyceps/src/list/tests/iter_raw.rs @@ -129,3 +129,8 @@ fn smoke() { drop(list); } + +#[test] +fn assert_send() { + crate::util::assert_send::>(); +} diff --git a/cordyceps/src/util.rs b/cordyceps/src/util.rs index d3b58aa6..9442fcb9 100644 --- a/cordyceps/src/util.rs +++ b/cordyceps/src/util.rs @@ -150,3 +150,6 @@ impl fmt::Display for FmtOption<'_, T> { #[cfg(test)] pub(crate) fn assert_send_sync() {} + +#[cfg(test)] +pub(crate) fn assert_send() {}