Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 34136ab

Browse files
committedApr 25, 2023
Add support for allocators in LinkedList
1 parent ab9bb3e commit 34136ab

File tree

2 files changed

+226
-137
lines changed

2 files changed

+226
-137
lines changed
 

‎library/alloc/src/collections/linked_list.rs

Lines changed: 224 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ use core::hash::{Hash, Hasher};
1818
use core::iter::{FromIterator, FusedIterator};
1919
use core::marker::PhantomData;
2020
use core::mem;
21-
use core::ptr::NonNull;
21+
use core::ptr::{NonNull, Unique};
2222

2323
use super::SpecExtend;
24+
use crate::alloc::{Allocator, Global};
2425
use crate::boxed::Box;
2526

2627
#[cfg(test)]
@@ -47,11 +48,15 @@ mod tests;
4748
#[stable(feature = "rust1", since = "1.0.0")]
4849
#[cfg_attr(not(test), rustc_diagnostic_item = "LinkedList")]
4950
#[rustc_insignificant_dtor]
50-
pub struct LinkedList<T> {
51+
pub struct LinkedList<
52+
T,
53+
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
54+
> {
5155
head: Option<NonNull<Node<T>>>,
5256
tail: Option<NonNull<Node<T>>>,
5357
len: usize,
54-
marker: PhantomData<Box<Node<T>>>,
58+
alloc: A,
59+
marker: PhantomData<Box<Node<T>, A>>,
5560
}
5661

5762
struct Node<T> {
@@ -81,6 +86,7 @@ impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
8186
head: self.head,
8287
tail: self.tail,
8388
len: self.len,
89+
alloc: Global,
8490
marker: PhantomData,
8591
}))
8692
.field(&self.len)
@@ -117,6 +123,7 @@ impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> {
117123
head: self.head,
118124
tail: self.tail,
119125
len: self.len,
126+
alloc: Global,
120127
marker: PhantomData,
121128
}))
122129
.field(&self.len)
@@ -133,12 +140,15 @@ impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> {
133140
/// [`IntoIterator`]: core::iter::IntoIterator
134141
#[derive(Clone)]
135142
#[stable(feature = "rust1", since = "1.0.0")]
136-
pub struct IntoIter<T> {
137-
list: LinkedList<T>,
143+
pub struct IntoIter<
144+
T,
145+
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
146+
> {
147+
list: LinkedList<T, A>,
138148
}
139149

140150
#[stable(feature = "collection_debug", since = "1.17.0")]
141-
impl<T: fmt::Debug> fmt::Debug for IntoIter<T> {
151+
impl<T: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<T, A> {
142152
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143153
f.debug_tuple("IntoIter").field(&self.list).finish()
144154
}
@@ -149,22 +159,25 @@ impl<T> Node<T> {
149159
Node { next: None, prev: None, element }
150160
}
151161

152-
fn into_element(self: Box<Self>) -> T {
162+
fn into_element<A: Allocator>(self: Box<Self, A>) -> T {
153163
self.element
154164
}
155165
}
156166

157167
// private methods
158-
impl<T> LinkedList<T> {
168+
impl<T, A: Allocator> LinkedList<T, A> {
159169
/// Adds the given node to the front of the list.
170+
///
171+
/// # Safety
172+
/// `node` must point to a valid node that was boxed using the list's allocator.
160173
#[inline]
161-
fn push_front_node(&mut self, mut node: Box<Node<T>>) {
174+
unsafe fn push_front_node(&mut self, node: Unique<Node<T>>) {
162175
// This method takes care not to create mutable references to whole nodes,
163176
// to maintain validity of aliasing pointers into `element`.
164177
unsafe {
165-
node.next = self.head;
166-
node.prev = None;
167-
let node = Some(Box::leak(node).into());
178+
(*node.as_ptr()).next = self.head;
179+
(*node.as_ptr()).prev = None;
180+
let node = Some(NonNull::from(node));
168181

169182
match self.head {
170183
None => self.tail = node,
@@ -179,11 +192,11 @@ impl<T> LinkedList<T> {
179192

180193
/// Removes and returns the node at the front of the list.
181194
#[inline]
182-
fn pop_front_node(&mut self) -> Option<Box<Node<T>>> {
195+
fn pop_front_node(&mut self) -> Option<Box<Node<T>, &A>> {
183196
// This method takes care not to create mutable references to whole nodes,
184197
// to maintain validity of aliasing pointers into `element`.
185198
self.head.map(|node| unsafe {
186-
let node = Box::from_raw(node.as_ptr());
199+
let node = Box::from_raw_in(node.as_ptr(), &self.alloc);
187200
self.head = node.next;
188201

189202
match self.head {
@@ -198,14 +211,17 @@ impl<T> LinkedList<T> {
198211
}
199212

200213
/// Adds the given node to the back of the list.
214+
///
215+
/// # Safety
216+
/// `node` must point to a valid node that was boxed using the list's allocator.
201217
#[inline]
202-
fn push_back_node(&mut self, mut node: Box<Node<T>>) {
218+
unsafe fn push_back_node(&mut self, node: Unique<Node<T>>) {
203219
// This method takes care not to create mutable references to whole nodes,
204220
// to maintain validity of aliasing pointers into `element`.
205221
unsafe {
206-
node.next = None;
207-
node.prev = self.tail;
208-
let node = Some(Box::leak(node).into());
222+
(*node.as_ptr()).next = None;
223+
(*node.as_ptr()).prev = self.tail;
224+
let node = Some(NonNull::from(node));
209225

210226
match self.tail {
211227
None => self.head = node,
@@ -220,11 +236,11 @@ impl<T> LinkedList<T> {
220236

221237
/// Removes and returns the node at the back of the list.
222238
#[inline]
223-
fn pop_back_node(&mut self) -> Option<Box<Node<T>>> {
239+
fn pop_back_node(&mut self) -> Option<Box<Node<T>, &A>> {
224240
// This method takes care not to create mutable references to whole nodes,
225241
// to maintain validity of aliasing pointers into `element`.
226242
self.tail.map(|node| unsafe {
227-
let node = Box::from_raw(node.as_ptr());
243+
let node = Box::from_raw_in(node.as_ptr(), &self.alloc);
228244
self.tail = node.prev;
229245

230246
match self.tail {
@@ -322,7 +338,10 @@ impl<T> LinkedList<T> {
322338
&mut self,
323339
split_node: Option<NonNull<Node<T>>>,
324340
at: usize,
325-
) -> Self {
341+
) -> Self
342+
where
343+
A: Clone,
344+
{
326345
// The split node is the new head node of the second part
327346
if let Some(mut split_node) = split_node {
328347
let first_part_head;
@@ -343,6 +362,7 @@ impl<T> LinkedList<T> {
343362
head: first_part_head,
344363
tail: first_part_tail,
345364
len: at,
365+
alloc: self.alloc.clone(),
346366
marker: PhantomData,
347367
};
348368

@@ -352,7 +372,7 @@ impl<T> LinkedList<T> {
352372

353373
first_part
354374
} else {
355-
mem::replace(self, LinkedList::new())
375+
mem::replace(self, LinkedList::new_in(self.alloc.clone()))
356376
}
357377
}
358378

@@ -361,7 +381,10 @@ impl<T> LinkedList<T> {
361381
&mut self,
362382
split_node: Option<NonNull<Node<T>>>,
363383
at: usize,
364-
) -> Self {
384+
) -> Self
385+
where
386+
A: Clone,
387+
{
365388
// The split node is the new tail node of the first part and owns
366389
// the head of the second part.
367390
if let Some(mut split_node) = split_node {
@@ -383,6 +406,7 @@ impl<T> LinkedList<T> {
383406
head: second_part_head,
384407
tail: second_part_tail,
385408
len: self.len - at,
409+
alloc: self.alloc.clone(),
386410
marker: PhantomData,
387411
};
388412

@@ -392,7 +416,7 @@ impl<T> LinkedList<T> {
392416

393417
second_part
394418
} else {
395-
mem::replace(self, LinkedList::new())
419+
mem::replace(self, LinkedList::new_in(self.alloc.clone()))
396420
}
397421
}
398422
}
@@ -421,7 +445,7 @@ impl<T> LinkedList<T> {
421445
#[stable(feature = "rust1", since = "1.0.0")]
422446
#[must_use]
423447
pub const fn new() -> Self {
424-
LinkedList { head: None, tail: None, len: 0, marker: PhantomData }
448+
LinkedList { head: None, tail: None, len: 0, alloc: Global, marker: PhantomData }
425449
}
426450

427451
/// Moves all elements from `other` to the end of the list.
@@ -472,7 +496,26 @@ impl<T> LinkedList<T> {
472496
}
473497
}
474498
}
499+
}
475500

501+
impl<T, A: Allocator> LinkedList<T, A> {
502+
/// Constructs an empty `LinkedList<T, A>`.
503+
///
504+
/// # Examples
505+
///
506+
/// ```
507+
/// #![feature(allocator_api)]
508+
///
509+
/// use std::alloc::System;
510+
/// use std::collections::LinkedList;
511+
///
512+
/// let list: LinkedList<u32, _> = LinkedList::new_in(System);
513+
/// ```
514+
#[inline]
515+
#[unstable(feature = "allocator_api", issue = "32838")]
516+
pub const fn new_in(alloc: A) -> Self {
517+
LinkedList { head: None, tail: None, len: 0, alloc, marker: PhantomData }
518+
}
476519
/// Provides a forward iterator.
477520
///
478521
/// # Examples
@@ -533,7 +576,7 @@ impl<T> LinkedList<T> {
533576
#[inline]
534577
#[must_use]
535578
#[unstable(feature = "linked_list_cursors", issue = "58533")]
536-
pub fn cursor_front(&self) -> Cursor<'_, T> {
579+
pub fn cursor_front(&self) -> Cursor<'_, T, A> {
537580
Cursor { index: 0, current: self.head, list: self }
538581
}
539582

@@ -543,7 +586,7 @@ impl<T> LinkedList<T> {
543586
#[inline]
544587
#[must_use]
545588
#[unstable(feature = "linked_list_cursors", issue = "58533")]
546-
pub fn cursor_front_mut(&mut self) -> CursorMut<'_, T> {
589+
pub fn cursor_front_mut(&mut self) -> CursorMut<'_, T, A> {
547590
CursorMut { index: 0, current: self.head, list: self }
548591
}
549592

@@ -553,7 +596,7 @@ impl<T> LinkedList<T> {
553596
#[inline]
554597
#[must_use]
555598
#[unstable(feature = "linked_list_cursors", issue = "58533")]
556-
pub fn cursor_back(&self) -> Cursor<'_, T> {
599+
pub fn cursor_back(&self) -> Cursor<'_, T, A> {
557600
Cursor { index: self.len.checked_sub(1).unwrap_or(0), current: self.tail, list: self }
558601
}
559602

@@ -563,7 +606,7 @@ impl<T> LinkedList<T> {
563606
#[inline]
564607
#[must_use]
565608
#[unstable(feature = "linked_list_cursors", issue = "58533")]
566-
pub fn cursor_back_mut(&mut self) -> CursorMut<'_, T> {
609+
pub fn cursor_back_mut(&mut self) -> CursorMut<'_, T, A> {
567610
CursorMut { index: self.len.checked_sub(1).unwrap_or(0), current: self.tail, list: self }
568611
}
569612

@@ -639,7 +682,15 @@ impl<T> LinkedList<T> {
639682
#[inline]
640683
#[stable(feature = "rust1", since = "1.0.0")]
641684
pub fn clear(&mut self) {
642-
*self = Self::new();
685+
// We need to drop the nodes while keeping self.alloc
686+
// We can do this by moving (head, tail, len) into a new list that borrows self.alloc
687+
drop(LinkedList {
688+
head: self.head.take(),
689+
tail: self.tail.take(),
690+
len: mem::take(&mut self.len),
691+
alloc: &self.alloc,
692+
marker: PhantomData,
693+
});
643694
}
644695

645696
/// Returns `true` if the `LinkedList` contains an element equal to the
@@ -791,7 +842,12 @@ impl<T> LinkedList<T> {
791842
/// ```
792843
#[stable(feature = "rust1", since = "1.0.0")]
793844
pub fn push_front(&mut self, elt: T) {
794-
self.push_front_node(Box::new(Node::new(elt)));
845+
let node = Box::new_in(Node::new(elt), &self.alloc);
846+
let node_ptr = Unique::from(Box::leak(node));
847+
// SAFETY: node_ptr is a unique pointer to a node we boxed with self.alloc
848+
unsafe {
849+
self.push_front_node(node_ptr);
850+
}
795851
}
796852

797853
/// Removes the first element and returns it, or `None` if the list is
@@ -834,7 +890,12 @@ impl<T> LinkedList<T> {
834890
/// ```
835891
#[stable(feature = "rust1", since = "1.0.0")]
836892
pub fn push_back(&mut self, elt: T) {
837-
self.push_back_node(Box::new(Node::new(elt)));
893+
let node = Box::new_in(Node::new(elt), &self.alloc);
894+
let node_ptr = Unique::from(Box::leak(node));
895+
// SAFETY: node_ptr is a unique pointer to a node we boxed with self.alloc
896+
unsafe {
897+
self.push_back_node(node_ptr);
898+
}
838899
}
839900

840901
/// Removes the last element from a list and returns it, or `None` if
@@ -884,13 +945,16 @@ impl<T> LinkedList<T> {
884945
/// assert_eq!(split.pop_front(), None);
885946
/// ```
886947
#[stable(feature = "rust1", since = "1.0.0")]
887-
pub fn split_off(&mut self, at: usize) -> LinkedList<T> {
948+
pub fn split_off(&mut self, at: usize) -> LinkedList<T, A>
949+
where
950+
A: Clone,
951+
{
888952
let len = self.len();
889953
assert!(at <= len, "Cannot split off at a nonexistent index");
890954
if at == 0 {
891-
return mem::take(self);
955+
return mem::replace(self, Self::new_in(self.alloc.clone()));
892956
} else if at == len {
893-
return Self::new();
957+
return Self::new_in(self.alloc.clone());
894958
}
895959

896960
// Below, we iterate towards the `i-1`th node, either from the start or the end,
@@ -988,7 +1052,7 @@ impl<T> LinkedList<T> {
9881052
/// assert_eq!(odds.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 9, 11, 13, 15]);
9891053
/// ```
9901054
#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")]
991-
pub fn drain_filter<F>(&mut self, filter: F) -> DrainFilter<'_, T, F>
1055+
pub fn drain_filter<F>(&mut self, filter: F) -> DrainFilter<'_, T, F, A>
9921056
where
9931057
F: FnMut(&mut T) -> bool,
9941058
{
@@ -1001,23 +1065,22 @@ impl<T> LinkedList<T> {
10011065
}
10021066

10031067
#[stable(feature = "rust1", since = "1.0.0")]
1004-
unsafe impl<#[may_dangle] T> Drop for LinkedList<T> {
1068+
unsafe impl<#[may_dangle] T, A: Allocator> Drop for LinkedList<T, A> {
10051069
fn drop(&mut self) {
1006-
struct DropGuard<'a, T>(&'a mut LinkedList<T>);
1070+
struct DropGuard<'a, T, A: Allocator>(&'a mut LinkedList<T, A>);
10071071

1008-
impl<'a, T> Drop for DropGuard<'a, T> {
1072+
impl<'a, T, A: Allocator> Drop for DropGuard<'a, T, A> {
10091073
fn drop(&mut self) {
10101074
// Continue the same loop we do below. This only runs when a destructor has
10111075
// panicked. If another one panics this will abort.
10121076
while self.0.pop_front_node().is_some() {}
10131077
}
10141078
}
10151079

1016-
while let Some(node) = self.pop_front_node() {
1017-
let guard = DropGuard(self);
1018-
drop(node);
1019-
mem::forget(guard);
1020-
}
1080+
// Wrap self so that if a destructor panics, we can try to keep looping
1081+
let guard = DropGuard(self);
1082+
while guard.0.pop_front_node().is_some() {}
1083+
mem::forget(guard);
10211084
}
10221085
}
10231086

@@ -1139,22 +1202,26 @@ impl<T> FusedIterator for IterMut<'_, T> {}
11391202
///
11401203
/// When created, cursors start at the front of the list, or the "ghost" non-element if the list is empty.
11411204
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1142-
pub struct Cursor<'a, T: 'a> {
1205+
pub struct Cursor<
1206+
'a,
1207+
T: 'a,
1208+
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1209+
> {
11431210
index: usize,
11441211
current: Option<NonNull<Node<T>>>,
1145-
list: &'a LinkedList<T>,
1212+
list: &'a LinkedList<T, A>,
11461213
}
11471214

11481215
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1149-
impl<T> Clone for Cursor<'_, T> {
1216+
impl<T, A: Allocator> Clone for Cursor<'_, T, A> {
11501217
fn clone(&self) -> Self {
11511218
let Cursor { index, current, list } = *self;
11521219
Cursor { index, current, list }
11531220
}
11541221
}
11551222

11561223
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1157-
impl<T: fmt::Debug> fmt::Debug for Cursor<'_, T> {
1224+
impl<T: fmt::Debug, A: Allocator> fmt::Debug for Cursor<'_, T, A> {
11581225
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11591226
f.debug_tuple("Cursor").field(&self.list).field(&self.index()).finish()
11601227
}
@@ -1171,20 +1238,24 @@ impl<T: fmt::Debug> fmt::Debug for Cursor<'_, T> {
11711238
/// To accommodate this, there is a "ghost" non-element that yields `None` between the head and
11721239
/// tail of the list.
11731240
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1174-
pub struct CursorMut<'a, T: 'a> {
1241+
pub struct CursorMut<
1242+
'a,
1243+
T: 'a,
1244+
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1245+
> {
11751246
index: usize,
11761247
current: Option<NonNull<Node<T>>>,
1177-
list: &'a mut LinkedList<T>,
1248+
list: &'a mut LinkedList<T, A>,
11781249
}
11791250

11801251
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1181-
impl<T: fmt::Debug> fmt::Debug for CursorMut<'_, T> {
1252+
impl<T: fmt::Debug, A: Allocator> fmt::Debug for CursorMut<'_, T, A> {
11821253
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11831254
f.debug_tuple("CursorMut").field(&self.list).field(&self.index()).finish()
11841255
}
11851256
}
11861257

1187-
impl<'a, T> Cursor<'a, T> {
1258+
impl<'a, T, A: Allocator> Cursor<'a, T, A> {
11881259
/// Returns the cursor position index within the `LinkedList`.
11891260
///
11901261
/// This returns `None` if the cursor is currently pointing to the
@@ -1301,7 +1372,7 @@ impl<'a, T> Cursor<'a, T> {
13011372
}
13021373
}
13031374

1304-
impl<'a, T> CursorMut<'a, T> {
1375+
impl<'a, T, A: Allocator> CursorMut<'a, T, A> {
13051376
/// Returns the cursor position index within the `LinkedList`.
13061377
///
13071378
/// This returns `None` if the cursor is currently pointing to the
@@ -1406,22 +1477,67 @@ impl<'a, T> CursorMut<'a, T> {
14061477
/// `CursorMut` is frozen for the lifetime of the `Cursor`.
14071478
#[must_use]
14081479
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1409-
pub fn as_cursor(&self) -> Cursor<'_, T> {
1480+
pub fn as_cursor(&self) -> Cursor<'_, T, A> {
14101481
Cursor { list: self.list, current: self.current, index: self.index }
14111482
}
14121483
}
14131484

14141485
// Now the list editing operations
14151486

14161487
impl<'a, T> CursorMut<'a, T> {
1488+
/// Inserts the elements from the given `LinkedList` after the current one.
1489+
///
1490+
/// If the cursor is pointing at the "ghost" non-element then the new elements are
1491+
/// inserted at the start of the `LinkedList`.
1492+
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1493+
pub fn splice_after(&mut self, list: LinkedList<T>) {
1494+
unsafe {
1495+
let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() {
1496+
Some(parts) => parts,
1497+
_ => return,
1498+
};
1499+
let node_next = match self.current {
1500+
None => self.list.head,
1501+
Some(node) => node.as_ref().next,
1502+
};
1503+
self.list.splice_nodes(self.current, node_next, splice_head, splice_tail, splice_len);
1504+
if self.current.is_none() {
1505+
// The "ghost" non-element's index has changed.
1506+
self.index = self.list.len;
1507+
}
1508+
}
1509+
}
1510+
1511+
/// Inserts the elements from the given `LinkedList` before the current one.
1512+
///
1513+
/// If the cursor is pointing at the "ghost" non-element then the new elements are
1514+
/// inserted at the end of the `LinkedList`.
1515+
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1516+
pub fn splice_before(&mut self, list: LinkedList<T>) {
1517+
unsafe {
1518+
let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() {
1519+
Some(parts) => parts,
1520+
_ => return,
1521+
};
1522+
let node_prev = match self.current {
1523+
None => self.list.tail,
1524+
Some(node) => node.as_ref().prev,
1525+
};
1526+
self.list.splice_nodes(node_prev, self.current, splice_head, splice_tail, splice_len);
1527+
self.index += splice_len;
1528+
}
1529+
}
1530+
}
1531+
1532+
impl<'a, T, A: Allocator> CursorMut<'a, T, A> {
14171533
/// Inserts a new element into the `LinkedList` after the current one.
14181534
///
14191535
/// If the cursor is pointing at the "ghost" non-element then the new element is
14201536
/// inserted at the front of the `LinkedList`.
14211537
#[unstable(feature = "linked_list_cursors", issue = "58533")]
14221538
pub fn insert_after(&mut self, item: T) {
14231539
unsafe {
1424-
let spliced_node = Box::leak(Box::new(Node::new(item))).into();
1540+
let spliced_node = Box::leak(Box::new_in(Node::new(item), &self.list.alloc)).into();
14251541
let node_next = match self.current {
14261542
None => self.list.head,
14271543
Some(node) => node.as_ref().next,
@@ -1441,7 +1557,7 @@ impl<'a, T> CursorMut<'a, T> {
14411557
#[unstable(feature = "linked_list_cursors", issue = "58533")]
14421558
pub fn insert_before(&mut self, item: T) {
14431559
unsafe {
1444-
let spliced_node = Box::leak(Box::new(Node::new(item))).into();
1560+
let spliced_node = Box::leak(Box::new_in(Node::new(item), &self.list.alloc)).into();
14451561
let node_prev = match self.current {
14461562
None => self.list.tail,
14471563
Some(node) => node.as_ref().prev,
@@ -1477,7 +1593,10 @@ impl<'a, T> CursorMut<'a, T> {
14771593
/// If the cursor is currently pointing to the "ghost" non-element then no element
14781594
/// is removed and `None` is returned.
14791595
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1480-
pub fn remove_current_as_list(&mut self) -> Option<LinkedList<T>> {
1596+
pub fn remove_current_as_list(&mut self) -> Option<LinkedList<T, A>>
1597+
where
1598+
A: Clone,
1599+
{
14811600
let mut unlinked_node = self.current?;
14821601
unsafe {
14831602
self.current = unlinked_node.as_ref().next;
@@ -1489,62 +1608,23 @@ impl<'a, T> CursorMut<'a, T> {
14891608
head: Some(unlinked_node),
14901609
tail: Some(unlinked_node),
14911610
len: 1,
1611+
alloc: self.list.alloc.clone(),
14921612
marker: PhantomData,
14931613
})
14941614
}
14951615
}
14961616

1497-
/// Inserts the elements from the given `LinkedList` after the current one.
1498-
///
1499-
/// If the cursor is pointing at the "ghost" non-element then the new elements are
1500-
/// inserted at the start of the `LinkedList`.
1501-
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1502-
pub fn splice_after(&mut self, list: LinkedList<T>) {
1503-
unsafe {
1504-
let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() {
1505-
Some(parts) => parts,
1506-
_ => return,
1507-
};
1508-
let node_next = match self.current {
1509-
None => self.list.head,
1510-
Some(node) => node.as_ref().next,
1511-
};
1512-
self.list.splice_nodes(self.current, node_next, splice_head, splice_tail, splice_len);
1513-
if self.current.is_none() {
1514-
// The "ghost" non-element's index has changed.
1515-
self.index = self.list.len;
1516-
}
1517-
}
1518-
}
1519-
1520-
/// Inserts the elements from the given `LinkedList` before the current one.
1521-
///
1522-
/// If the cursor is pointing at the "ghost" non-element then the new elements are
1523-
/// inserted at the end of the `LinkedList`.
1524-
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1525-
pub fn splice_before(&mut self, list: LinkedList<T>) {
1526-
unsafe {
1527-
let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() {
1528-
Some(parts) => parts,
1529-
_ => return,
1530-
};
1531-
let node_prev = match self.current {
1532-
None => self.list.tail,
1533-
Some(node) => node.as_ref().prev,
1534-
};
1535-
self.list.splice_nodes(node_prev, self.current, splice_head, splice_tail, splice_len);
1536-
self.index += splice_len;
1537-
}
1538-
}
1539-
15401617
/// Splits the list into two after the current element. This will return a
15411618
/// new list consisting of everything after the cursor, with the original
15421619
/// list retaining everything before.
15431620
///
15441621
/// If the cursor is pointing at the "ghost" non-element then the entire contents
15451622
/// of the `LinkedList` are moved.
15461623
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1547-
pub fn split_after(&mut self) -> LinkedList<T> {
1624+
pub fn split_after(&mut self) -> LinkedList<T, A>
1625+
where
1626+
A: Clone,
1627+
{
15481628
let split_off_idx = if self.index == self.list.len { 0 } else { self.index + 1 };
15491629
if self.index == self.list.len {
15501630
// The "ghost" non-element's index has changed to 0.
@@ -1560,7 +1640,10 @@ impl<'a, T> CursorMut<'a, T> {
15601640
/// If the cursor is pointing at the "ghost" non-element then the entire contents
15611641
/// of the `LinkedList` are moved.
15621642
#[unstable(feature = "linked_list_cursors", issue = "58533")]
1563-
pub fn split_before(&mut self) -> LinkedList<T> {
1643+
pub fn split_before(&mut self) -> LinkedList<T, A>
1644+
where
1645+
A: Clone,
1646+
{
15641647
let split_off_idx = self.index;
15651648
self.index = 0;
15661649
unsafe { self.list.split_off_before_node(self.current, split_off_idx) }
@@ -1702,19 +1785,23 @@ impl<'a, T> CursorMut<'a, T> {
17021785

17031786
/// An iterator produced by calling `drain_filter` on LinkedList.
17041787
#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")]
1705-
pub struct DrainFilter<'a, T: 'a, F: 'a>
1706-
where
1788+
pub struct DrainFilter<
1789+
'a,
1790+
T: 'a,
1791+
F: 'a,
1792+
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
1793+
> where
17071794
F: FnMut(&mut T) -> bool,
17081795
{
1709-
list: &'a mut LinkedList<T>,
1796+
list: &'a mut LinkedList<T, A>,
17101797
it: Option<NonNull<Node<T>>>,
17111798
pred: F,
17121799
idx: usize,
17131800
old_len: usize,
17141801
}
17151802

17161803
#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")]
1717-
impl<T, F> Iterator for DrainFilter<'_, T, F>
1804+
impl<T, F, A: Allocator> Iterator for DrainFilter<'_, T, F, A>
17181805
where
17191806
F: FnMut(&mut T) -> bool,
17201807
{
@@ -1743,16 +1830,16 @@ where
17431830
}
17441831

17451832
#[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")]
1746-
impl<T, F> Drop for DrainFilter<'_, T, F>
1833+
impl<T, F, A: Allocator> Drop for DrainFilter<'_, T, F, A>
17471834
where
17481835
F: FnMut(&mut T) -> bool,
17491836
{
17501837
fn drop(&mut self) {
1751-
struct DropGuard<'r, 'a, T, F>(&'r mut DrainFilter<'a, T, F>)
1838+
struct DropGuard<'r, 'a, T, F, A: Allocator>(&'r mut DrainFilter<'a, T, F, A>)
17521839
where
17531840
F: FnMut(&mut T) -> bool;
17541841

1755-
impl<'r, 'a, T, F> Drop for DropGuard<'r, 'a, T, F>
1842+
impl<'r, 'a, T, F, A: Allocator> Drop for DropGuard<'r, 'a, T, F, A>
17561843
where
17571844
F: FnMut(&mut T) -> bool,
17581845
{
@@ -1780,7 +1867,7 @@ where
17801867
}
17811868

17821869
#[stable(feature = "rust1", since = "1.0.0")]
1783-
impl<T> Iterator for IntoIter<T> {
1870+
impl<T, A: Allocator> Iterator for IntoIter<T, A> {
17841871
type Item = T;
17851872

17861873
#[inline]
@@ -1795,18 +1882,18 @@ impl<T> Iterator for IntoIter<T> {
17951882
}
17961883

17971884
#[stable(feature = "rust1", since = "1.0.0")]
1798-
impl<T> DoubleEndedIterator for IntoIter<T> {
1885+
impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
17991886
#[inline]
18001887
fn next_back(&mut self) -> Option<T> {
18011888
self.list.pop_back()
18021889
}
18031890
}
18041891

18051892
#[stable(feature = "rust1", since = "1.0.0")]
1806-
impl<T> ExactSizeIterator for IntoIter<T> {}
1893+
impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {}
18071894

18081895
#[stable(feature = "fused", since = "1.26.0")]
1809-
impl<T> FusedIterator for IntoIter<T> {}
1896+
impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
18101897

18111898
#[stable(feature = "rust1", since = "1.0.0")]
18121899
impl<T> FromIterator<T> for LinkedList<T> {
@@ -1818,19 +1905,19 @@ impl<T> FromIterator<T> for LinkedList<T> {
18181905
}
18191906

18201907
#[stable(feature = "rust1", since = "1.0.0")]
1821-
impl<T> IntoIterator for LinkedList<T> {
1908+
impl<T, A: Allocator> IntoIterator for LinkedList<T, A> {
18221909
type Item = T;
1823-
type IntoIter = IntoIter<T>;
1910+
type IntoIter = IntoIter<T, A>;
18241911

18251912
/// Consumes the list into an iterator yielding elements by value.
18261913
#[inline]
1827-
fn into_iter(self) -> IntoIter<T> {
1914+
fn into_iter(self) -> IntoIter<T, A> {
18281915
IntoIter { list: self }
18291916
}
18301917
}
18311918

18321919
#[stable(feature = "rust1", since = "1.0.0")]
1833-
impl<'a, T> IntoIterator for &'a LinkedList<T> {
1920+
impl<'a, T, A: Allocator> IntoIterator for &'a LinkedList<T, A> {
18341921
type Item = &'a T;
18351922
type IntoIter = Iter<'a, T>;
18361923

@@ -1840,7 +1927,7 @@ impl<'a, T> IntoIterator for &'a LinkedList<T> {
18401927
}
18411928

18421929
#[stable(feature = "rust1", since = "1.0.0")]
1843-
impl<'a, T> IntoIterator for &'a mut LinkedList<T> {
1930+
impl<'a, T, A: Allocator> IntoIterator for &'a mut LinkedList<T, A> {
18441931
type Item = &'a mut T;
18451932
type IntoIter = IterMut<'a, T>;
18461933

@@ -1850,7 +1937,7 @@ impl<'a, T> IntoIterator for &'a mut LinkedList<T> {
18501937
}
18511938

18521939
#[stable(feature = "rust1", since = "1.0.0")]
1853-
impl<T> Extend<T> for LinkedList<T> {
1940+
impl<T, A: Allocator> Extend<T> for LinkedList<T, A> {
18541941
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
18551942
<Self as SpecExtend<I>>::spec_extend(self, iter);
18561943
}
@@ -1861,7 +1948,7 @@ impl<T> Extend<T> for LinkedList<T> {
18611948
}
18621949
}
18631950

1864-
impl<I: IntoIterator> SpecExtend<I> for LinkedList<I::Item> {
1951+
impl<I: IntoIterator, A: Allocator> SpecExtend<I> for LinkedList<I::Item, A> {
18651952
default fn spec_extend(&mut self, iter: I) {
18661953
iter.into_iter().for_each(move |elt| self.push_back(elt));
18671954
}
@@ -1874,7 +1961,7 @@ impl<T> SpecExtend<LinkedList<T>> for LinkedList<T> {
18741961
}
18751962

18761963
#[stable(feature = "extend_ref", since = "1.2.0")]
1877-
impl<'a, T: 'a + Copy> Extend<&'a T> for LinkedList<T> {
1964+
impl<'a, T: 'a + Copy, A: Allocator> Extend<&'a T> for LinkedList<T, A> {
18781965
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
18791966
self.extend(iter.into_iter().cloned());
18801967
}
@@ -1886,7 +1973,7 @@ impl<'a, T: 'a + Copy> Extend<&'a T> for LinkedList<T> {
18861973
}
18871974

18881975
#[stable(feature = "rust1", since = "1.0.0")]
1889-
impl<T: PartialEq> PartialEq for LinkedList<T> {
1976+
impl<T: PartialEq, A: Allocator> PartialEq for LinkedList<T, A> {
18901977
fn eq(&self, other: &Self) -> bool {
18911978
self.len() == other.len() && self.iter().eq(other)
18921979
}
@@ -1897,27 +1984,29 @@ impl<T: PartialEq> PartialEq for LinkedList<T> {
18971984
}
18981985

18991986
#[stable(feature = "rust1", since = "1.0.0")]
1900-
impl<T: Eq> Eq for LinkedList<T> {}
1987+
impl<T: Eq, A: Allocator> Eq for LinkedList<T, A> {}
19011988

19021989
#[stable(feature = "rust1", since = "1.0.0")]
1903-
impl<T: PartialOrd> PartialOrd for LinkedList<T> {
1990+
impl<T: PartialOrd, A: Allocator> PartialOrd for LinkedList<T, A> {
19041991
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
19051992
self.iter().partial_cmp(other)
19061993
}
19071994
}
19081995

19091996
#[stable(feature = "rust1", since = "1.0.0")]
1910-
impl<T: Ord> Ord for LinkedList<T> {
1997+
impl<T: Ord, A: Allocator> Ord for LinkedList<T, A> {
19111998
#[inline]
19121999
fn cmp(&self, other: &Self) -> Ordering {
19132000
self.iter().cmp(other)
19142001
}
19152002
}
19162003

19172004
#[stable(feature = "rust1", since = "1.0.0")]
1918-
impl<T: Clone> Clone for LinkedList<T> {
2005+
impl<T: Clone, A: Allocator + Clone> Clone for LinkedList<T, A> {
19192006
fn clone(&self) -> Self {
1920-
self.iter().cloned().collect()
2007+
let mut list = Self::new_in(self.alloc.clone());
2008+
list.extend(self.iter().cloned());
2009+
list
19212010
}
19222011

19232012
fn clone_from(&mut self, other: &Self) {
@@ -1935,14 +2024,14 @@ impl<T: Clone> Clone for LinkedList<T> {
19352024
}
19362025

19372026
#[stable(feature = "rust1", since = "1.0.0")]
1938-
impl<T: fmt::Debug> fmt::Debug for LinkedList<T> {
2027+
impl<T: fmt::Debug, A: Allocator> fmt::Debug for LinkedList<T, A> {
19392028
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19402029
f.debug_list().entries(self).finish()
19412030
}
19422031
}
19432032

19442033
#[stable(feature = "rust1", since = "1.0.0")]
1945-
impl<T: Hash> Hash for LinkedList<T> {
2034+
impl<T: Hash, A: Allocator> Hash for LinkedList<T, A> {
19462035
fn hash<H: Hasher>(&self, state: &mut H) {
19472036
state.write_length_prefix(self.len());
19482037
for elt in self {
@@ -1982,10 +2071,10 @@ fn assert_covariance() {
19822071
}
19832072

19842073
#[stable(feature = "rust1", since = "1.0.0")]
1985-
unsafe impl<T: Send> Send for LinkedList<T> {}
2074+
unsafe impl<T: Send, A: Allocator + Send> Send for LinkedList<T, A> {}
19862075

19872076
#[stable(feature = "rust1", since = "1.0.0")]
1988-
unsafe impl<T: Sync> Sync for LinkedList<T> {}
2077+
unsafe impl<T: Sync, A: Allocator + Sync> Sync for LinkedList<T, A> {}
19892078

19902079
#[stable(feature = "rust1", since = "1.0.0")]
19912080
unsafe impl<T: Sync> Send for Iter<'_, T> {}
@@ -2000,13 +2089,13 @@ unsafe impl<T: Send> Send for IterMut<'_, T> {}
20002089
unsafe impl<T: Sync> Sync for IterMut<'_, T> {}
20012090

20022091
#[unstable(feature = "linked_list_cursors", issue = "58533")]
2003-
unsafe impl<T: Sync> Send for Cursor<'_, T> {}
2092+
unsafe impl<T: Sync, A: Allocator + Sync> Send for Cursor<'_, T, A> {}
20042093

20052094
#[unstable(feature = "linked_list_cursors", issue = "58533")]
2006-
unsafe impl<T: Sync> Sync for Cursor<'_, T> {}
2095+
unsafe impl<T: Sync, A: Allocator + Sync> Sync for Cursor<'_, T, A> {}
20072096

20082097
#[unstable(feature = "linked_list_cursors", issue = "58533")]
2009-
unsafe impl<T: Send> Send for CursorMut<'_, T> {}
2098+
unsafe impl<T: Send, A: Allocator + Send> Send for CursorMut<'_, T, A> {}
20102099

20112100
#[unstable(feature = "linked_list_cursors", issue = "58533")]
2012-
unsafe impl<T: Sync> Sync for CursorMut<'_, T> {}
2101+
unsafe impl<T: Sync, A: Allocator + Sync> Sync for CursorMut<'_, T, A> {}

‎tests/debuginfo/pretty-std.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@
130130
// cdb-check: [+0x000] __0 : "IAMA optional string!" [Type: alloc::string::String]
131131

132132
// cdb-command: dx linkedlist
133-
// cdb-check:linkedlist : { len=0x2 } [Type: alloc::collections::linked_list::LinkedList<i32>]
134-
// cdb-check: [<Raw View>] [Type: alloc::collections::linked_list::LinkedList<i32>]
133+
// cdb-check:linkedlist : { len=0x2 } [Type: alloc::collections::linked_list::LinkedList<i32,alloc::alloc::Global>]
134+
// cdb-check: [<Raw View>] [Type: alloc::collections::linked_list::LinkedList<i32,alloc::alloc::Global>]
135135
// cdb-check: [0x0] : 128 [Type: int]
136136
// cdb-check: [0x1] : 42 [Type: int]
137137

0 commit comments

Comments
 (0)
Please sign in to comment.