• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![cfg_attr(not(feature = "full"), allow(dead_code))]
2 
3 //! An intrusive double linked list of data
4 //!
5 //! The data structure supports tracking pinned nodes. Most of the data
6 //! structure's APIs are `unsafe` as they require the caller to ensure the
7 //! specified node is actually contained by the list.
8 
9 use core::cell::UnsafeCell;
10 use core::fmt;
11 use core::marker::{PhantomData, PhantomPinned};
12 use core::mem::ManuallyDrop;
13 use core::ptr::{self, NonNull};
14 
15 /// An intrusive linked list.
16 ///
17 /// Currently, the list is not emptied on drop. It is the caller's
18 /// responsibility to ensure the list is empty before dropping it.
19 pub(crate) struct LinkedList<L, T> {
20     /// Linked list head
21     head: Option<NonNull<T>>,
22 
23     /// Linked list tail
24     tail: Option<NonNull<T>>,
25 
26     /// Node type marker.
27     _marker: PhantomData<*const L>,
28 }
29 
30 unsafe impl<L: Link> Send for LinkedList<L, L::Target> where L::Target: Send {}
31 unsafe impl<L: Link> Sync for LinkedList<L, L::Target> where L::Target: Sync {}
32 
33 /// Defines how a type is tracked within a linked list.
34 ///
35 /// In order to support storing a single type within multiple lists, accessing
36 /// the list pointers is decoupled from the entry type.
37 ///
38 /// # Safety
39 ///
40 /// Implementations must guarantee that `Target` types are pinned in memory. In
41 /// other words, when a node is inserted, the value will not be moved as long as
42 /// it is stored in the list.
43 pub(crate) unsafe trait Link {
44     /// Handle to the list entry.
45     ///
46     /// This is usually a pointer-ish type.
47     type Handle;
48 
49     /// Node type
50     type Target;
51 
52     /// Convert the handle to a raw pointer without consuming the handle
as_raw(handle: &Self::Handle) -> NonNull<Self::Target>53     fn as_raw(handle: &Self::Handle) -> NonNull<Self::Target>;
54 
55     /// Convert the raw pointer to a handle
from_raw(ptr: NonNull<Self::Target>) -> Self::Handle56     unsafe fn from_raw(ptr: NonNull<Self::Target>) -> Self::Handle;
57 
58     /// Return the pointers for a node
pointers(target: NonNull<Self::Target>) -> NonNull<Pointers<Self::Target>>59     unsafe fn pointers(target: NonNull<Self::Target>) -> NonNull<Pointers<Self::Target>>;
60 }
61 
62 /// Previous / next pointers
63 pub(crate) struct Pointers<T> {
64     inner: UnsafeCell<PointersInner<T>>,
65 }
66 /// We do not want the compiler to put the `noalias` attribute on mutable
67 /// references to this type, so the type has been made `!Unpin` with a
68 /// `PhantomPinned` field.
69 ///
70 /// Additionally, we never access the `prev` or `next` fields directly, as any
71 /// such access would implicitly involve the creation of a reference to the
72 /// field, which we want to avoid since the fields are not `!Unpin`, and would
73 /// hence be given the `noalias` attribute if we were to do such an access.
74 /// As an alternative to accessing the fields directly, the `Pointers` type
75 /// provides getters and setters for the two fields, and those are implemented
76 /// using raw pointer casts and offsets, which is valid since the struct is
77 /// #[repr(C)].
78 ///
79 /// See this link for more information:
80 /// https://github.com/rust-lang/rust/pull/82834
81 #[repr(C)]
82 struct PointersInner<T> {
83     /// The previous node in the list. null if there is no previous node.
84     ///
85     /// This field is accessed through pointer manipulation, so it is not dead code.
86     #[allow(dead_code)]
87     prev: Option<NonNull<T>>,
88 
89     /// The next node in the list. null if there is no previous node.
90     ///
91     /// This field is accessed through pointer manipulation, so it is not dead code.
92     #[allow(dead_code)]
93     next: Option<NonNull<T>>,
94 
95     /// This type is !Unpin due to the heuristic from:
96     /// https://github.com/rust-lang/rust/pull/82834
97     _pin: PhantomPinned,
98 }
99 
100 unsafe impl<T: Send> Send for Pointers<T> {}
101 unsafe impl<T: Sync> Sync for Pointers<T> {}
102 
103 // ===== impl LinkedList =====
104 
105 impl<L, T> LinkedList<L, T> {
106     /// Creates an empty linked list.
new() -> LinkedList<L, T>107     pub(crate) const fn new() -> LinkedList<L, T> {
108         LinkedList {
109             head: None,
110             tail: None,
111             _marker: PhantomData,
112         }
113     }
114 }
115 
116 impl<L: Link> LinkedList<L, L::Target> {
117     /// Adds an element first in the list.
push_front(&mut self, val: L::Handle)118     pub(crate) fn push_front(&mut self, val: L::Handle) {
119         // The value should not be dropped, it is being inserted into the list
120         let val = ManuallyDrop::new(val);
121         let ptr = L::as_raw(&*val);
122         assert_ne!(self.head, Some(ptr));
123         unsafe {
124             L::pointers(ptr).as_mut().set_next(self.head);
125             L::pointers(ptr).as_mut().set_prev(None);
126 
127             if let Some(head) = self.head {
128                 L::pointers(head).as_mut().set_prev(Some(ptr));
129             }
130 
131             self.head = Some(ptr);
132 
133             if self.tail.is_none() {
134                 self.tail = Some(ptr);
135             }
136         }
137     }
138 
139     /// Removes the last element from a list and returns it, or None if it is
140     /// empty.
pop_back(&mut self) -> Option<L::Handle>141     pub(crate) fn pop_back(&mut self) -> Option<L::Handle> {
142         unsafe {
143             let last = self.tail?;
144             self.tail = L::pointers(last).as_ref().get_prev();
145 
146             if let Some(prev) = L::pointers(last).as_ref().get_prev() {
147                 L::pointers(prev).as_mut().set_next(None);
148             } else {
149                 self.head = None
150             }
151 
152             L::pointers(last).as_mut().set_prev(None);
153             L::pointers(last).as_mut().set_next(None);
154 
155             Some(L::from_raw(last))
156         }
157     }
158 
159     /// Returns whether the linked list does not contain any node
is_empty(&self) -> bool160     pub(crate) fn is_empty(&self) -> bool {
161         if self.head.is_some() {
162             return false;
163         }
164 
165         assert!(self.tail.is_none());
166         true
167     }
168 
169     /// Removes the specified node from the list
170     ///
171     /// # Safety
172     ///
173     /// The caller **must** ensure that `node` is currently contained by
174     /// `self` or not contained by any other list.
remove(&mut self, node: NonNull<L::Target>) -> Option<L::Handle>175     pub(crate) unsafe fn remove(&mut self, node: NonNull<L::Target>) -> Option<L::Handle> {
176         if let Some(prev) = L::pointers(node).as_ref().get_prev() {
177             debug_assert_eq!(L::pointers(prev).as_ref().get_next(), Some(node));
178             L::pointers(prev)
179                 .as_mut()
180                 .set_next(L::pointers(node).as_ref().get_next());
181         } else {
182             if self.head != Some(node) {
183                 return None;
184             }
185 
186             self.head = L::pointers(node).as_ref().get_next();
187         }
188 
189         if let Some(next) = L::pointers(node).as_ref().get_next() {
190             debug_assert_eq!(L::pointers(next).as_ref().get_prev(), Some(node));
191             L::pointers(next)
192                 .as_mut()
193                 .set_prev(L::pointers(node).as_ref().get_prev());
194         } else {
195             // This might be the last item in the list
196             if self.tail != Some(node) {
197                 return None;
198             }
199 
200             self.tail = L::pointers(node).as_ref().get_prev();
201         }
202 
203         L::pointers(node).as_mut().set_next(None);
204         L::pointers(node).as_mut().set_prev(None);
205 
206         Some(L::from_raw(node))
207     }
208 }
209 
210 impl<L: Link> fmt::Debug for LinkedList<L, L::Target> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result211     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
212         f.debug_struct("LinkedList")
213             .field("head", &self.head)
214             .field("tail", &self.tail)
215             .finish()
216     }
217 }
218 
219 #[cfg(any(
220     feature = "fs",
221     all(unix, feature = "process"),
222     feature = "signal",
223     feature = "sync",
224 ))]
225 impl<L: Link> LinkedList<L, L::Target> {
last(&self) -> Option<&L::Target>226     pub(crate) fn last(&self) -> Option<&L::Target> {
227         let tail = self.tail.as_ref()?;
228         unsafe { Some(&*tail.as_ptr()) }
229     }
230 }
231 
232 impl<L: Link> Default for LinkedList<L, L::Target> {
default() -> Self233     fn default() -> Self {
234         Self::new()
235     }
236 }
237 
238 // ===== impl Iter =====
239 
240 cfg_rt_multi_thread! {
241     pub(crate) struct Iter<'a, T: Link> {
242         curr: Option<NonNull<T::Target>>,
243         _p: core::marker::PhantomData<&'a T>,
244     }
245 
246     impl<L: Link> LinkedList<L, L::Target> {
247         pub(crate) fn iter(&self) -> Iter<'_, L> {
248             Iter {
249                 curr: self.head,
250                 _p: core::marker::PhantomData,
251             }
252         }
253     }
254 
255     impl<'a, T: Link> Iterator for Iter<'a, T> {
256         type Item = &'a T::Target;
257 
258         fn next(&mut self) -> Option<&'a T::Target> {
259             let curr = self.curr?;
260             // safety: the pointer references data contained by the list
261             self.curr = unsafe { T::pointers(curr).as_ref() }.get_next();
262 
263             // safety: the value is still owned by the linked list.
264             Some(unsafe { &*curr.as_ptr() })
265         }
266     }
267 }
268 
269 // ===== impl DrainFilter =====
270 
271 cfg_io_readiness! {
272     pub(crate) struct DrainFilter<'a, T: Link, F> {
273         list: &'a mut LinkedList<T, T::Target>,
274         filter: F,
275         curr: Option<NonNull<T::Target>>,
276     }
277 
278     impl<T: Link> LinkedList<T, T::Target> {
279         pub(crate) fn drain_filter<F>(&mut self, filter: F) -> DrainFilter<'_, T, F>
280         where
281             F: FnMut(&mut T::Target) -> bool,
282         {
283             let curr = self.head;
284             DrainFilter {
285                 curr,
286                 filter,
287                 list: self,
288             }
289         }
290     }
291 
292     impl<'a, T, F> Iterator for DrainFilter<'a, T, F>
293     where
294         T: Link,
295         F: FnMut(&mut T::Target) -> bool,
296     {
297         type Item = T::Handle;
298 
299         fn next(&mut self) -> Option<Self::Item> {
300             while let Some(curr) = self.curr {
301                 // safety: the pointer references data contained by the list
302                 self.curr = unsafe { T::pointers(curr).as_ref() }.get_next();
303 
304                 // safety: the value is still owned by the linked list.
305                 if (self.filter)(unsafe { &mut *curr.as_ptr() }) {
306                     return unsafe { self.list.remove(curr) };
307                 }
308             }
309 
310             None
311         }
312     }
313 }
314 
315 // ===== impl Pointers =====
316 
317 impl<T> Pointers<T> {
318     /// Create a new set of empty pointers
new() -> Pointers<T>319     pub(crate) fn new() -> Pointers<T> {
320         Pointers {
321             inner: UnsafeCell::new(PointersInner {
322                 prev: None,
323                 next: None,
324                 _pin: PhantomPinned,
325             }),
326         }
327     }
328 
get_prev(&self) -> Option<NonNull<T>>329     fn get_prev(&self) -> Option<NonNull<T>> {
330         // SAFETY: prev is the first field in PointersInner, which is #[repr(C)].
331         unsafe {
332             let inner = self.inner.get();
333             let prev = inner as *const Option<NonNull<T>>;
334             ptr::read(prev)
335         }
336     }
get_next(&self) -> Option<NonNull<T>>337     fn get_next(&self) -> Option<NonNull<T>> {
338         // SAFETY: next is the second field in PointersInner, which is #[repr(C)].
339         unsafe {
340             let inner = self.inner.get();
341             let prev = inner as *const Option<NonNull<T>>;
342             let next = prev.add(1);
343             ptr::read(next)
344         }
345     }
346 
set_prev(&mut self, value: Option<NonNull<T>>)347     fn set_prev(&mut self, value: Option<NonNull<T>>) {
348         // SAFETY: prev is the first field in PointersInner, which is #[repr(C)].
349         unsafe {
350             let inner = self.inner.get();
351             let prev = inner as *mut Option<NonNull<T>>;
352             ptr::write(prev, value);
353         }
354     }
set_next(&mut self, value: Option<NonNull<T>>)355     fn set_next(&mut self, value: Option<NonNull<T>>) {
356         // SAFETY: next is the second field in PointersInner, which is #[repr(C)].
357         unsafe {
358             let inner = self.inner.get();
359             let prev = inner as *mut Option<NonNull<T>>;
360             let next = prev.add(1);
361             ptr::write(next, value);
362         }
363     }
364 }
365 
366 impl<T> fmt::Debug for Pointers<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result367     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
368         let prev = self.get_prev();
369         let next = self.get_next();
370         f.debug_struct("Pointers")
371             .field("prev", &prev)
372             .field("next", &next)
373             .finish()
374     }
375 }
376 
377 #[cfg(test)]
378 #[cfg(not(loom))]
379 mod tests {
380     use super::*;
381 
382     use std::pin::Pin;
383 
384     #[derive(Debug)]
385     struct Entry {
386         pointers: Pointers<Entry>,
387         val: i32,
388     }
389 
390     unsafe impl<'a> Link for &'a Entry {
391         type Handle = Pin<&'a Entry>;
392         type Target = Entry;
393 
as_raw(handle: &Pin<&'_ Entry>) -> NonNull<Entry>394         fn as_raw(handle: &Pin<&'_ Entry>) -> NonNull<Entry> {
395             NonNull::from(handle.get_ref())
396         }
397 
from_raw(ptr: NonNull<Entry>) -> Pin<&'a Entry>398         unsafe fn from_raw(ptr: NonNull<Entry>) -> Pin<&'a Entry> {
399             Pin::new_unchecked(&*ptr.as_ptr())
400         }
401 
pointers(mut target: NonNull<Entry>) -> NonNull<Pointers<Entry>>402         unsafe fn pointers(mut target: NonNull<Entry>) -> NonNull<Pointers<Entry>> {
403             NonNull::from(&mut target.as_mut().pointers)
404         }
405     }
406 
entry(val: i32) -> Pin<Box<Entry>>407     fn entry(val: i32) -> Pin<Box<Entry>> {
408         Box::pin(Entry {
409             pointers: Pointers::new(),
410             val,
411         })
412     }
413 
ptr(r: &Pin<Box<Entry>>) -> NonNull<Entry>414     fn ptr(r: &Pin<Box<Entry>>) -> NonNull<Entry> {
415         r.as_ref().get_ref().into()
416     }
417 
collect_list(list: &mut LinkedList<&'_ Entry, <&'_ Entry as Link>::Target>) -> Vec<i32>418     fn collect_list(list: &mut LinkedList<&'_ Entry, <&'_ Entry as Link>::Target>) -> Vec<i32> {
419         let mut ret = vec![];
420 
421         while let Some(entry) = list.pop_back() {
422             ret.push(entry.val);
423         }
424 
425         ret
426     }
427 
push_all<'a>( list: &mut LinkedList<&'a Entry, <&'_ Entry as Link>::Target>, entries: &[Pin<&'a Entry>], )428     fn push_all<'a>(
429         list: &mut LinkedList<&'a Entry, <&'_ Entry as Link>::Target>,
430         entries: &[Pin<&'a Entry>],
431     ) {
432         for entry in entries.iter() {
433             list.push_front(*entry);
434         }
435     }
436 
437     macro_rules! assert_clean {
438         ($e:ident) => {{
439             assert!($e.pointers.get_next().is_none());
440             assert!($e.pointers.get_prev().is_none());
441         }};
442     }
443 
444     macro_rules! assert_ptr_eq {
445         ($a:expr, $b:expr) => {{
446             // Deal with mapping a Pin<&mut T> -> Option<NonNull<T>>
447             assert_eq!(Some($a.as_ref().get_ref().into()), $b)
448         }};
449     }
450 
451     #[test]
const_new()452     fn const_new() {
453         const _: LinkedList<&Entry, <&Entry as Link>::Target> = LinkedList::new();
454     }
455 
456     #[test]
push_and_drain()457     fn push_and_drain() {
458         let a = entry(5);
459         let b = entry(7);
460         let c = entry(31);
461 
462         let mut list = LinkedList::new();
463         assert!(list.is_empty());
464 
465         list.push_front(a.as_ref());
466         assert!(!list.is_empty());
467         list.push_front(b.as_ref());
468         list.push_front(c.as_ref());
469 
470         let items: Vec<i32> = collect_list(&mut list);
471         assert_eq!([5, 7, 31].to_vec(), items);
472 
473         assert!(list.is_empty());
474     }
475 
476     #[test]
push_pop_push_pop()477     fn push_pop_push_pop() {
478         let a = entry(5);
479         let b = entry(7);
480 
481         let mut list = LinkedList::<&Entry, <&Entry as Link>::Target>::new();
482 
483         list.push_front(a.as_ref());
484 
485         let entry = list.pop_back().unwrap();
486         assert_eq!(5, entry.val);
487         assert!(list.is_empty());
488 
489         list.push_front(b.as_ref());
490 
491         let entry = list.pop_back().unwrap();
492         assert_eq!(7, entry.val);
493 
494         assert!(list.is_empty());
495         assert!(list.pop_back().is_none());
496     }
497 
498     #[test]
remove_by_address()499     fn remove_by_address() {
500         let a = entry(5);
501         let b = entry(7);
502         let c = entry(31);
503 
504         unsafe {
505             // Remove first
506             let mut list = LinkedList::new();
507 
508             push_all(&mut list, &[c.as_ref(), b.as_ref(), a.as_ref()]);
509             assert!(list.remove(ptr(&a)).is_some());
510             assert_clean!(a);
511             // `a` should be no longer there and can't be removed twice
512             assert!(list.remove(ptr(&a)).is_none());
513             assert!(!list.is_empty());
514 
515             assert!(list.remove(ptr(&b)).is_some());
516             assert_clean!(b);
517             // `b` should be no longer there and can't be removed twice
518             assert!(list.remove(ptr(&b)).is_none());
519             assert!(!list.is_empty());
520 
521             assert!(list.remove(ptr(&c)).is_some());
522             assert_clean!(c);
523             // `b` should be no longer there and can't be removed twice
524             assert!(list.remove(ptr(&c)).is_none());
525             assert!(list.is_empty());
526         }
527 
528         unsafe {
529             // Remove middle
530             let mut list = LinkedList::new();
531 
532             push_all(&mut list, &[c.as_ref(), b.as_ref(), a.as_ref()]);
533 
534             assert!(list.remove(ptr(&a)).is_some());
535             assert_clean!(a);
536 
537             assert_ptr_eq!(b, list.head);
538             assert_ptr_eq!(c, b.pointers.get_next());
539             assert_ptr_eq!(b, c.pointers.get_prev());
540 
541             let items = collect_list(&mut list);
542             assert_eq!([31, 7].to_vec(), items);
543         }
544 
545         unsafe {
546             // Remove middle
547             let mut list = LinkedList::new();
548 
549             push_all(&mut list, &[c.as_ref(), b.as_ref(), a.as_ref()]);
550 
551             assert!(list.remove(ptr(&b)).is_some());
552             assert_clean!(b);
553 
554             assert_ptr_eq!(c, a.pointers.get_next());
555             assert_ptr_eq!(a, c.pointers.get_prev());
556 
557             let items = collect_list(&mut list);
558             assert_eq!([31, 5].to_vec(), items);
559         }
560 
561         unsafe {
562             // Remove last
563             // Remove middle
564             let mut list = LinkedList::new();
565 
566             push_all(&mut list, &[c.as_ref(), b.as_ref(), a.as_ref()]);
567 
568             assert!(list.remove(ptr(&c)).is_some());
569             assert_clean!(c);
570 
571             assert!(b.pointers.get_next().is_none());
572             assert_ptr_eq!(b, list.tail);
573 
574             let items = collect_list(&mut list);
575             assert_eq!([7, 5].to_vec(), items);
576         }
577 
578         unsafe {
579             // Remove first of two
580             let mut list = LinkedList::new();
581 
582             push_all(&mut list, &[b.as_ref(), a.as_ref()]);
583 
584             assert!(list.remove(ptr(&a)).is_some());
585 
586             assert_clean!(a);
587 
588             // a should be no longer there and can't be removed twice
589             assert!(list.remove(ptr(&a)).is_none());
590 
591             assert_ptr_eq!(b, list.head);
592             assert_ptr_eq!(b, list.tail);
593 
594             assert!(b.pointers.get_next().is_none());
595             assert!(b.pointers.get_prev().is_none());
596 
597             let items = collect_list(&mut list);
598             assert_eq!([7].to_vec(), items);
599         }
600 
601         unsafe {
602             // Remove last of two
603             let mut list = LinkedList::new();
604 
605             push_all(&mut list, &[b.as_ref(), a.as_ref()]);
606 
607             assert!(list.remove(ptr(&b)).is_some());
608 
609             assert_clean!(b);
610 
611             assert_ptr_eq!(a, list.head);
612             assert_ptr_eq!(a, list.tail);
613 
614             assert!(a.pointers.get_next().is_none());
615             assert!(a.pointers.get_prev().is_none());
616 
617             let items = collect_list(&mut list);
618             assert_eq!([5].to_vec(), items);
619         }
620 
621         unsafe {
622             // Remove last item
623             let mut list = LinkedList::new();
624 
625             push_all(&mut list, &[a.as_ref()]);
626 
627             assert!(list.remove(ptr(&a)).is_some());
628             assert_clean!(a);
629 
630             assert!(list.head.is_none());
631             assert!(list.tail.is_none());
632             let items = collect_list(&mut list);
633             assert!(items.is_empty());
634         }
635 
636         unsafe {
637             // Remove missing
638             let mut list = LinkedList::<&Entry, <&Entry as Link>::Target>::new();
639 
640             list.push_front(b.as_ref());
641             list.push_front(a.as_ref());
642 
643             assert!(list.remove(ptr(&c)).is_none());
644         }
645     }
646 
647     #[test]
iter()648     fn iter() {
649         let a = entry(5);
650         let b = entry(7);
651 
652         let mut list = LinkedList::<&Entry, <&Entry as Link>::Target>::new();
653 
654         assert_eq!(0, list.iter().count());
655 
656         list.push_front(a.as_ref());
657         list.push_front(b.as_ref());
658 
659         let mut i = list.iter();
660         assert_eq!(7, i.next().unwrap().val);
661         assert_eq!(5, i.next().unwrap().val);
662         assert!(i.next().is_none());
663     }
664 
665     proptest::proptest! {
666         #[test]
667         fn fuzz_linked_list(ops: Vec<usize>) {
668             run_fuzz(ops);
669         }
670     }
671 
run_fuzz(ops: Vec<usize>)672     fn run_fuzz(ops: Vec<usize>) {
673         use std::collections::VecDeque;
674 
675         #[derive(Debug)]
676         enum Op {
677             Push,
678             Pop,
679             Remove(usize),
680         }
681 
682         let ops = ops
683             .iter()
684             .map(|i| match i % 3 {
685                 0 => Op::Push,
686                 1 => Op::Pop,
687                 2 => Op::Remove(i / 3),
688                 _ => unreachable!(),
689             })
690             .collect::<Vec<_>>();
691 
692         let mut ll = LinkedList::<&Entry, <&Entry as Link>::Target>::new();
693         let mut reference = VecDeque::new();
694 
695         let entries: Vec<_> = (0..ops.len()).map(|i| entry(i as i32)).collect();
696 
697         for (i, op) in ops.iter().enumerate() {
698             match op {
699                 Op::Push => {
700                     reference.push_front(i as i32);
701                     assert_eq!(entries[i].val, i as i32);
702 
703                     ll.push_front(entries[i].as_ref());
704                 }
705                 Op::Pop => {
706                     if reference.is_empty() {
707                         assert!(ll.is_empty());
708                         continue;
709                     }
710 
711                     let v = reference.pop_back();
712                     assert_eq!(v, ll.pop_back().map(|v| v.val));
713                 }
714                 Op::Remove(n) => {
715                     if reference.is_empty() {
716                         assert!(ll.is_empty());
717                         continue;
718                     }
719 
720                     let idx = n % reference.len();
721                     let expect = reference.remove(idx).unwrap();
722 
723                     unsafe {
724                         let entry = ll.remove(ptr(&entries[expect as usize])).unwrap();
725                         assert_eq!(expect, entry.val);
726                     }
727                 }
728             }
729         }
730     }
731 }
732