1#![doc = include_str!("../README.md")]
16#![cfg_attr(feature = "nightly", feature(allocator_api))]
17#![cfg_attr(feature = "nightly", feature(box_into_inner))]
18#![cfg_attr(feature = "nightly", feature(coerce_unsized))]
19#![cfg_attr(feature = "nightly", feature(doc_cfg))]
20#![cfg_attr(feature = "nightly", feature(once_cell_try_insert))]
21#![cfg_attr(feature = "nightly", feature(ptr_metadata))]
22#![cfg_attr(feature = "nightly", feature(unsize))]
23
24use ::allocator_api2::alloc;
25use ::allocator_api2::alloc::{Allocator, Global};
26use ::allocator_api2::boxed::Box;
27use ::std::any::Any;
28use ::std::fmt::Debug;
29use ::std::hash::Hash;
30#[cfg(feature = "nightly")]
31use ::std::marker::Unsize;
32use ::std::ops::DerefMut;
33
34#[cfg(not(feature = "sync"))]
35use ::std::cell::OnceCell;
36use ::std::ptr::NonNull;
37#[cfg(feature = "sync")]
38use ::std::sync::OnceLock as OnceCell;
39
40#[derive(Clone)]
118pub struct OnceList<T: ?Sized, A: Allocator = Global> {
119 head: OnceCell<Box<Cons<T, T, A>, A>>,
120 alloc: A,
121}
122
123#[derive(Clone)]
129struct Cons<T: ?Sized, U: ?Sized, A: Allocator> {
130 next: OnceCell<Box<Cons<U, U, A>, A>>,
131 val: T,
132}
133
134impl<T: ?Sized> OnceList<T, Global> {
135 pub fn new() -> Self {
137 Self {
138 head: OnceCell::new(),
139 alloc: Global,
140 }
141 }
142}
143impl<T: ?Sized, A: Allocator> OnceList<T, A> {
144 pub fn new_in(alloc: A) -> Self {
146 Self {
147 head: OnceCell::new(),
148 alloc,
149 }
150 }
151
152 pub fn len(&self) -> usize {
154 self.iter().count()
155 }
156
157 pub fn is_empty(&self) -> bool {
159 self.head.get().is_none()
160 }
161
162 pub fn contains(&self, val: &T) -> bool
164 where
165 T: PartialEq,
166 {
167 self.iter().any(|v| v == val)
168 }
169
170 pub fn first(&self) -> Option<&T> {
172 self.head.get().map(|c| &c.val)
173 }
174
175 pub fn first_mut(&mut self) -> Option<&mut T> {
177 self.head.get_mut().map(|c| &mut c.val)
178 }
179
180 pub fn last(&self) -> Option<&T> {
183 let mut last_opt = None;
184 let mut next_cell = &self.head;
185 while let Some(next_box) = next_cell.get() {
186 last_opt = Some(&next_box.val);
187 next_cell = &next_box.next;
188 }
189 last_opt
190 }
191
192 pub fn last_mut(&mut self) -> Option<&mut T> {
195 let mut last_opt = None;
196 let mut next_cell = &mut self.head;
197 while let Some(next_box) = next_cell.get_mut() {
198 let next_cons = Box::deref_mut(next_box);
199 last_opt = Some(&mut next_cons.val);
200 next_cell = &mut next_cons.next;
201 }
202 last_opt
203 }
204
205 fn last_cell(&self) -> &OnceCell<Box<Cons<T, T, A>, A>> {
206 let mut next_cell = &self.head;
207 while let Some(next_box) = next_cell.get() {
208 next_cell = &next_box.next;
209 }
210 next_cell
211 }
212
213 pub fn iter(&self) -> impl Iterator<Item = &T> {
215 let mut next_cell = &self.head;
216 ::std::iter::from_fn(move || match next_cell.get() {
217 Some(c) => {
218 next_cell = &c.next;
219 Some(&c.val)
220 }
221 None => None,
222 })
223 }
224
225 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
227 struct Iter<'a, T: ?Sized, A: Allocator> {
228 next_cell: &'a mut OnceCell<Box<Cons<T, T, A>, A>>,
229 }
230 impl<'a, T: ?Sized, A: Allocator> Iterator for Iter<'a, T, A> {
231 type Item = &'a mut T;
232 fn next(&mut self) -> Option<Self::Item> {
233 let next_box = self.next_cell.get_mut()?;
234 let next_cons = unsafe { &mut *::std::ptr::from_mut(next_box.as_mut()) };
236 self.next_cell = &mut next_cons.next;
237 Some(&mut next_cons.val)
238 }
239 }
240 Iter {
241 next_cell: &mut self.head,
242 }
243 }
244
245 pub fn clear(&mut self) {
247 self.head = OnceCell::new();
248 }
249
250 pub fn allocator(&self) -> &A {
252 &self.alloc
253 }
254}
255
256impl<T: ?Sized, A: Allocator> OnceList<T, A> {
257 #[cfg(feature = "nightly")]
264 #[cfg_attr(feature = "nightly", doc(cfg(feature = "nightly")))]
265 pub fn remove_into_box<P>(&mut self, pred: P) -> Option<Box<T, A>>
266 where
267 P: FnMut(&T) -> bool,
268 {
269 self.remove_inner(pred, |boxed_cons| boxed_cons.box_into_inner_box())
270 }
271
272 #[cfg(feature = "nightly")]
280 #[cfg_attr(feature = "nightly", doc(cfg(feature = "nightly")))]
281 pub unsafe fn remove_unsized_as<P, U>(&mut self, mut pred: P) -> Option<U>
282 where
283 P: FnMut(&T) -> Option<&U>,
284 {
285 let found_sized_ptr: OnceCell<*const U> = OnceCell::new();
286 self.remove_inner(
287 |val| {
288 if let Some(val) = pred(val) {
289 found_sized_ptr.set(val as *const U).unwrap();
291 true
292 } else {
293 false
294 }
295 },
296 |boxed_cons| -> U {
297 let found_sized_ptr: *const U = *found_sized_ptr.get().unwrap();
302
303 let cons_layout = alloc::Layout::for_value::<Cons<T, T, A>>(&boxed_cons);
304 let (cons_ptr, alloc) = Box::into_non_null_with_allocator(boxed_cons);
305 let val_ptr = &unsafe { cons_ptr.as_ref() }.val as *const T;
306
307 debug_assert_eq!(val_ptr as *const U, found_sized_ptr);
309
310 let result = unsafe { ::std::ptr::read(val_ptr as *const U) };
312
313 unsafe { alloc.deallocate(cons_ptr.cast(), cons_layout) };
315
316 result
317 },
318 )
319 }
320
321 fn remove_inner<P, F, U>(&mut self, mut pred: P, mut f: F) -> Option<U>
323 where
324 P: FnMut(&T) -> bool,
325 F: FnMut(Box<Cons<T, T, A>, A>) -> U,
326 {
327 let mut next_cell = &mut self.head;
328 while let Some(next_ref) = next_cell.get() {
329 if pred(&next_ref.val) {
330 let mut next_box = next_cell.take().unwrap();
332
333 if let Some(next_next) = next_box.next.take() {
335 let _ = next_cell.set(next_next);
336 }
337
338 return Some(f(next_box));
339 }
340 next_cell = &mut next_cell.get_mut().unwrap().next;
342 }
343 None
344 }
345}
346
347impl<T: ?Sized, A: Allocator + Clone> OnceList<T, A> {
348 #[cfg(feature = "nightly")]
352 #[cfg_attr(feature = "nightly", doc(cfg(feature = "nightly")))]
353 pub fn push_unsized<U: Unsize<T>>(&self, val: U) -> &U {
354 let boxed_cons = Cons::new_boxed(val, self.alloc.clone());
355 self.push_inner(boxed_cons, |c| unsafe { &*(c as *const T as *const U) })
356 }
357
358 fn push_inner<F, U>(&self, mut new_cons: Box<Cons<T, T, A>, A>, f: F) -> &U
360 where
361 F: FnOnce(&T) -> &U,
362 {
363 let mut next_cell = &self.head;
364 loop {
365 match next_cell.try_insert2(new_cons) {
366 Ok(new_cons) => {
367 return f(&new_cons.val);
368 }
369 Err((cur_cons, new_cons2)) => {
370 next_cell = &cur_cons.next;
371 new_cons = new_cons2;
372 }
373 }
374 }
375 }
376}
377
378impl<T, A: Allocator> OnceList<T, A> {
379 pub fn remove<P>(&mut self, mut pred: P) -> Option<T>
382 where
383 P: FnMut(&T) -> bool,
384 {
385 self.remove_inner(&mut pred, |boxed_cons| Box::into_inner(boxed_cons).val)
386 }
387}
388
389impl<T, A: Allocator + Clone> OnceList<T, A> {
390 pub fn push(&self, val: T) -> &T {
394 let boxed_cons = Box::new_in(Cons::new(val), self.alloc.clone());
395 self.push_inner(boxed_cons, |c| c)
396 }
397
398 pub fn extend<U: IntoIterator<Item = T>>(&self, iter: U) {
403 let mut last_cell = self.last_cell();
404 let alloc = self.allocator();
405 for val in iter {
406 let _ = last_cell.set(Box::new_in(Cons::new(val), A::clone(alloc)));
407 last_cell = &unsafe { &last_cell.get().unwrap_unchecked() }.next;
408 }
409 }
410}
411
412impl<A: Allocator + Clone> OnceList<dyn Any, A> {
413 pub fn push_any<T: Any>(&self, val: T) -> &T {
427 let sized_box = Box::new_in(Cons::<T, dyn Any, A>::new(val), A::clone(&self.alloc));
428 let unsized_box = unsafe {
432 let (sized_ptr, alloc) = Box::into_raw_with_allocator(sized_box);
433 let unsized_ptr: *mut Cons<dyn Any, dyn Any, A> = sized_ptr;
435 Box::from_raw_in(unsized_ptr, alloc)
436 };
437 self.push_inner(
438 unsized_box,
439 |c| c.downcast_ref::<T>().unwrap(),
441 )
442 }
443}
444
445impl<A: Allocator> OnceList<dyn Any, A> {
446 pub fn find_by_type<T: Any>(&self) -> Option<&T> {
461 self.iter().find_map(|val| val.downcast_ref())
462 }
463
464 pub fn remove_by_type<T: Any>(&mut self) -> Option<T> {
480 self.remove_inner(
481 |v| v.is::<T>(),
482 |boxed_cons| {
483 let cons_layout = alloc::Layout::for_value::<Cons<_, _, _>>(&boxed_cons);
484 let (cons_ptr, alloc) = Box::into_raw_with_allocator(boxed_cons);
485
486 let Cons {
487 next: next_ref,
488 val: val_any_ref,
489 } = unsafe { &*cons_ptr };
490 unsafe { ::std::ptr::read(next_ref) };
492
493 let val_ref = <dyn Any>::downcast_ref::<T>(val_any_ref).unwrap();
494 let val = unsafe { ::std::ptr::read(val_ref) };
495
496 unsafe {
497 alloc.deallocate(NonNull::new_unchecked(cons_ptr as *mut u8), cons_layout);
498 }
499
500 val
501 },
502 )
503 }
504}
505
506impl<T: ?Sized> Default for OnceList<T, Global> {
507 fn default() -> Self {
508 Self::new()
509 }
510}
511
512impl<T: ?Sized + Debug, A: Allocator> Debug for OnceList<T, A> {
513 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
514 f.debug_list().entries(self.iter()).finish()
515 }
516}
517
518impl<T: ?Sized + PartialEq, A: Allocator> PartialEq for OnceList<T, A> {
519 fn eq(&self, other: &Self) -> bool {
520 self.iter().eq(other.iter())
521 }
522}
523
524impl<T: ?Sized + Eq, A: Allocator> Eq for OnceList<T, A> {}
525
526impl<T: ?Sized + Hash, A: Allocator> Hash for OnceList<T, A> {
527 fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
528 state.write_usize(self.len());
529 for val in self.iter() {
530 val.hash(state);
531 }
532 }
533}
534
535impl<T> FromIterator<T> for OnceList<T, Global> {
536 fn from_iter<U: IntoIterator<Item = T>>(iter: U) -> Self {
537 let list = Self::new();
538 let mut last_cell = &list.head;
539 for val in iter {
540 let _ = last_cell.set(Box::new(Cons::new(val)));
541 last_cell = &unsafe { &last_cell.get().unwrap_unchecked() }.next;
542 }
543 list
544 }
545}
546
547impl<T, A: Allocator> IntoIterator for OnceList<T, A> {
548 type Item = T;
549 type IntoIter = IntoIter<T, A>;
550 fn into_iter(self) -> Self::IntoIter {
551 IntoIter(self.head)
552 }
553}
554
555pub struct IntoIter<T, A: Allocator>(OnceCell<Box<Cons<T, T, A>, A>>);
556
557impl<T, A: Allocator> Iterator for IntoIter<T, A> {
558 type Item = T;
559 fn next(&mut self) -> Option<Self::Item> {
560 let next_cell = self.0.take()?;
561 let next_cons = Box::into_inner(next_cell);
562 self.0 = next_cons.next;
563 Some(next_cons.val)
564 }
565}
566
567impl<T, A: Allocator + Clone> Extend<T> for OnceList<T, A> {
568 fn extend<U: IntoIterator<Item = T>>(&mut self, iter: U) {
571 <OnceList<T, A>>::extend(self, iter);
572 }
573}
574
575impl<T, U: ?Sized, A: Allocator> Cons<T, U, A> {
576 fn new(val: T) -> Self {
577 Self {
578 next: OnceCell::new(),
579 val,
580 }
581 }
582}
583
584#[cfg(feature = "nightly")]
585impl<T: ?Sized, A: Allocator> Cons<T, T, A> {
586 fn new_boxed<U>(val: U, alloc: A) -> Box<Self, A>
587 where
588 U: Unsize<T>,
589 {
590 Box::<Cons<U, T, A>, A>::new_in(
592 Cons::<U, T, A> {
593 next: OnceCell::new(),
594 val: val,
595 },
596 alloc,
597 )
598 }
599
600 fn box_into_inner_box(self: Box<Self, A>) -> Box<T, A> {
601 use ::std::ptr::{metadata, NonNull};
602
603 let cons_layout = alloc::Layout::for_value::<Cons<T, T, A>>(&self);
604 let layout = alloc::Layout::for_value::<T>(&self.val);
605 let metadata = metadata(&self.val);
606 let (raw_cons, alloc) = Box::into_raw_with_allocator(self);
607 let dst = alloc.allocate(layout).unwrap();
608
609 let Cons { next, val } = unsafe { &*raw_cons };
611 let _ = unsafe { ::std::ptr::read(next) };
612 let raw_src = val as *const T;
613
614 unsafe {
616 ::std::ptr::copy_nonoverlapping(
617 raw_src.cast::<u8>(),
618 dst.cast::<u8>().as_ptr(),
619 layout.size(),
620 );
621 }
622
623 unsafe {
625 alloc.deallocate(NonNull::new(raw_cons).unwrap().cast(), cons_layout);
626 }
627
628 let dst = NonNull::<T>::from_raw_parts(dst.cast::<u8>(), metadata);
630
631 unsafe { Box::from_non_null_in(dst, alloc) }
632 }
633}
634
635trait OnceCellExt<T> {
637 fn try_insert2(&self, value: T) -> Result<&T, (&T, T)>;
638}
639#[cfg(not(feature = "nightly"))]
640impl<T> OnceCellExt<T> for OnceCell<T> {
641 fn try_insert2(&self, value: T) -> Result<&T, (&T, T)> {
642 match self.set(value) {
644 Ok(()) => Ok(unsafe { self.get().unwrap_unchecked() }),
645 Err(value) => Err((unsafe { self.get().unwrap_unchecked() }, value)),
646 }
647 }
648}
649#[cfg(feature = "nightly")]
650impl<T> OnceCellExt<T> for OnceCell<T> {
651 fn try_insert2(&self, value: T) -> Result<&T, (&T, T)> {
652 self.try_insert(value)
653 }
654}
655
656#[cfg(test)]
657mod tests {
658 use super::*;
659
660 #[test]
661 fn test_new() {
662 let list = OnceList::<i32>::new();
663 assert!(list.is_empty());
664 assert_eq!(list.len(), 0);
665 assert_eq!(list.iter().next(), None);
666 }
667
668 #[test]
669 fn test_default() {
670 let list = OnceList::<i32>::default();
671 assert!(list.is_empty());
672 assert_eq!(list.len(), 0);
673 assert_eq!(list.iter().next(), None);
674 }
675
676 #[test]
677 fn test_push() {
678 let list = OnceList::new();
679 let val = list.push(42);
680 assert_eq!(val, &42);
681 assert_eq!(list.len(), 1);
682 assert_eq!(list.clone().into_iter().collect::<Vec<_>>(), vec![42]);
683
684 list.push(100);
685 list.push(3);
686 assert_eq!(list.len(), 3);
687 assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![42, 100, 3]);
688 }
689
690 #[test]
691 fn test_from_iter() {
692 let list = [1, 2, 3].into_iter().collect::<OnceList<_>>();
693 assert_eq!(list.len(), 3);
694 assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![1, 2, 3]);
695 }
696
697 #[test]
698 fn test_extend() {
699 let list = [1, 2, 3].into_iter().collect::<OnceList<_>>();
700 list.extend([4, 5, 6]);
701 assert_eq!(list.len(), 6);
702 assert_eq!(list.into_iter().collect::<Vec<_>>(), vec![1, 2, 3, 4, 5, 6]);
703 }
704
705 #[test]
706 fn test_clear() {
707 let mut list = [1, 2, 3].into_iter().collect::<OnceList<_>>();
708 list.clear();
709 assert!(list.is_empty());
710 assert_eq!(list.len(), 0);
711 assert_eq!(list.iter().next(), None);
712 }
713
714 #[test]
715 fn test_first_last() {
716 let empty_list = OnceList::<i32>::new();
717 assert_eq!(empty_list.first(), None);
718 assert_eq!(empty_list.last(), None);
719
720 let single_list = [42].into_iter().collect::<OnceList<_>>();
721 assert_eq!(single_list.first(), Some(&42));
722 assert_eq!(single_list.last(), Some(&42));
723
724 let multiple_list = [1, 2, 3].into_iter().collect::<OnceList<_>>();
725 assert_eq!(multiple_list.first(), Some(&1));
726 assert_eq!(multiple_list.last(), Some(&3));
727 }
728
729 #[test]
730 fn test_contains() {
731 let list = [1, 2, 3].into_iter().collect::<OnceList<_>>();
732 assert!(list.contains(&1));
733 assert!(list.contains(&2));
734 assert!(list.contains(&3));
735 assert!(!list.contains(&0));
736 assert!(!list.contains(&4));
737
738 let empty_list = OnceList::<i32>::new();
739 assert!(!empty_list.contains(&1));
740 }
741
742 #[test]
743 fn test_remove() {
744 let mut list = [1, 2, 3].into_iter().collect::<OnceList<_>>();
745 assert_eq!(list.remove(|&v| v == 2), Some(2));
746 assert_eq!(list.iter().collect::<Vec<_>>(), vec![&1, &3]);
747
748 assert_eq!(list.remove(|&v| v == 0), None);
749 assert_eq!(list.iter().collect::<Vec<_>>(), vec![&1, &3]);
750
751 assert_eq!(list.remove(|&v| v == 1), Some(1));
752 assert_eq!(list.iter().collect::<Vec<_>>(), vec![&3]);
753
754 assert_eq!(list.remove(|&v| v == 3), Some(3));
755 assert!(list.is_empty());
756 }
757
758 #[test]
759 fn test_eq() {
760 let list1 = [1, 2, 3].into_iter().collect::<OnceList<_>>();
761 let list2 = [1, 2, 3].into_iter().collect::<OnceList<_>>();
762 assert_eq!(list1, list2);
763
764 let list3 = [1, 2, 4].into_iter().collect::<OnceList<_>>();
765 assert_ne!(list1, list3);
766
767 let list4 = OnceList::<i32>::new();
768 assert_eq!(list4, list4);
769 assert_ne!(list1, list4);
770 }
771
772 #[test]
773 fn test_hash() {
774 use ::std::hash::{DefaultHasher, Hasher};
775 let mut hasher1 = DefaultHasher::new();
776 let mut hasher2 = DefaultHasher::new();
777
778 let list1 = [1, 2, 3].into_iter().collect::<OnceList<_>>();
779 let list2 = [1, 2, 3].into_iter().collect::<OnceList<_>>();
780 list1.hash(&mut hasher1);
781 list2.hash(&mut hasher2);
782 assert_eq!(hasher1.finish(), hasher2.finish());
783
784 let list3 = [1, 2, 4].into_iter().collect::<OnceList<_>>();
785 let mut hasher3 = DefaultHasher::new();
786 list3.hash(&mut hasher3);
787 assert_ne!(hasher1.finish(), hasher3.finish());
788
789 let tuple1 = (
792 [1, 2].into_iter().collect::<OnceList<_>>(),
793 [3].into_iter().collect::<OnceList<_>>(),
794 );
795 let tuple2 = (
796 [1].into_iter().collect::<OnceList<_>>(),
797 [2, 3].into_iter().collect::<OnceList<_>>(),
798 );
799 let mut hasher4 = DefaultHasher::new();
800 let mut hasher5 = DefaultHasher::new();
801 tuple1.hash(&mut hasher4);
802 tuple2.hash(&mut hasher5);
803 assert_ne!(hasher4.finish(), hasher5.finish());
804 }
805
806 #[test]
807 #[cfg(feature = "nightly")]
808 fn test_unsized_slice_push() {
809 let list: OnceList<[i32]> = OnceList::new();
810 let first = list.push_unsized([1]);
811 let second = list.push_unsized([2, 3]);
812 assert_eq!(first, &[1]);
813 assert_eq!(second, &[2, 3]);
814
815 assert_eq!(list.iter().nth(0), Some(&[1] as &[i32]));
816 assert_eq!(list.iter().nth(1), Some(&[2, 3] as &[i32]));
817 }
818
819 #[test]
820 #[cfg(feature = "nightly")]
821 fn test_unsized_dyn_push() {
822 let list: OnceList<dyn ToString> = OnceList::new();
823 let first = list.push_unsized(1);
824 let second = list.push_unsized("hello");
825 assert_eq!(first.to_string(), "1");
826 assert_eq!(second.to_string(), "hello");
827
828 assert_eq!(
829 list.iter().nth(0).map(<dyn ToString>::to_string),
830 Some("1".to_string())
831 );
832 assert_eq!(
833 list.iter().nth(1).map(<dyn ToString>::to_string),
834 Some("hello".to_string())
835 );
836 }
837
838 #[test]
839 #[cfg(feature = "nightly")]
840 fn test_unsized_slice_remove_into_box() {
841 let list = OnceList::<[i32]>::new();
842 list.push_unsized([1]);
843 list.push_unsized([2, 3]);
844 list.push_unsized([4, 5, 6]);
845
846 let mut list = list;
847 let removed = list.remove_into_box(|s| s.len() == 2);
848 assert_eq!(removed, Some(Box::new([2, 3]) as Box<[i32]>));
849 assert_eq!(list.len(), 2);
850 assert_eq!(list.iter().nth(0), Some(&[1] as &[i32]));
851 assert_eq!(list.iter().nth(1), Some(&[4, 5, 6] as &[i32]));
852 }
853
854 #[test]
855 #[cfg(feature = "nightly")]
856 fn test_unsized_dyn_remove_into_box() {
857 let list = OnceList::<dyn ToString>::new();
858 list.push_unsized(1);
859 list.push_unsized("hello");
860 list.push_unsized(42);
861
862 let mut list = list;
863 let removed = list.remove_into_box(|s| s.to_string() == "hello");
864 assert_eq!(removed.map(|s| s.to_string()), Some("hello".to_string()));
865 assert_eq!(list.len(), 2);
866 assert_eq!(
867 list.iter().nth(0).map(|s| s.to_string()),
868 Some("1".to_string())
869 );
870 assert_eq!(
871 list.iter().nth(1).map(|s| s.to_string()),
872 Some("42".to_string())
873 );
874 }
875
876 #[test]
877 #[cfg(feature = "nightly")]
878 fn test_unsized_slice_remove_as() {
879 let list = OnceList::<[i32]>::new();
880 list.push_unsized([1]);
881 list.push_unsized([2, 3]);
882 list.push_unsized([4, 5, 6]);
883
884 let mut list = list;
885 let removed: Option<[i32; 2]> = unsafe { list.remove_unsized_as(|s| s.try_into().ok()) };
886 assert_eq!(removed, Some([2, 3]));
887 assert_eq!(list.len(), 2);
888 assert_eq!(list.iter().nth(0), Some(&[1] as &[i32]));
889 assert_eq!(list.iter().nth(1), Some(&[4, 5, 6] as &[i32]));
890 }
891}