diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
commit | 9835e2ae736235810b4ea1c162ca5e65c547e770 (patch) | |
tree | 3fcebf40ed70e581d776a8a4c65923e8ec20e026 /library/alloc/src | |
parent | Releasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff) | |
download | rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/alloc/src')
22 files changed, 447 insertions, 251 deletions
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 6f2ba957b..01d1fdc9b 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -37,6 +37,9 @@ extern "Rust" { #[rustc_allocator_zeroed] #[rustc_nounwind] fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8; + + #[cfg(not(bootstrap))] + static __rust_no_alloc_shim_is_unstable: u8; } /// The global memory allocator. @@ -90,7 +93,14 @@ pub use std::alloc::Global; #[must_use = "losing the pointer will leak memory"] #[inline] pub unsafe fn alloc(layout: Layout) -> *mut u8 { - unsafe { __rust_alloc(layout.size(), layout.align()) } + unsafe { + // Make sure we don't accidentally allow omitting the allocator shim in + // stable code until it is actually stabilized. + #[cfg(not(bootstrap))] + core::ptr::read_volatile(&__rust_no_alloc_shim_is_unstable); + + __rust_alloc(layout.size(), layout.align()) + } } /// Deallocate memory with the global allocator. diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index 0c8c796ae..84331eba2 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -115,7 +115,7 @@ where /// ``` /// use std::borrow::Cow; /// -/// fn abs_all(input: &mut Cow<[i32]>) { +/// fn abs_all(input: &mut Cow<'_, [i32]>) { /// for i in 0..input.len() { /// let v = input[i]; /// if v < 0 { @@ -145,7 +145,7 @@ where /// ``` /// use std::borrow::Cow; /// -/// struct Items<'a, X: 'a> where [X]: ToOwned<Owned = Vec<X>> { +/// struct Items<'a, X> where [X]: ToOwned<Owned = Vec<X>> { /// values: Cow<'a, [X]>, /// } /// @@ -267,7 +267,7 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> { /// /// assert_eq!( /// cow, - /// Cow::Owned(String::from("FOO")) as Cow<str> + /// Cow::Owned(String::from("FOO")) as Cow<'_, str> /// ); /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -311,7 +311,7 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> { /// use std::borrow::Cow; /// /// let s = "Hello world!"; - /// let cow: Cow<str> = Cow::Owned(String::from(s)); + /// let cow: Cow<'_, str> = Cow::Owned(String::from(s)); /// /// assert_eq!( /// cow.into_owned(), diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 7f88327bf..1768687e8 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -576,8 +576,7 @@ impl<T, A: Allocator> Box<T, A> { /// /// This conversion does not allocate on the heap and happens in place. #[unstable(feature = "box_into_boxed_slice", issue = "71582")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] - pub const fn into_boxed_slice(boxed: Self) -> Box<[T], A> { + pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> { let (raw, alloc) = Box::into_raw_with_allocator(boxed); unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) } } @@ -809,9 +808,8 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> { /// assert_eq!(*five, 5) /// ``` #[unstable(feature = "new_uninit", issue = "63291")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const unsafe fn assume_init(self) -> Box<T, A> { + pub unsafe fn assume_init(self) -> Box<T, A> { let (raw, alloc) = Box::into_raw_with_allocator(self); unsafe { Box::from_raw_in(raw as *mut T, alloc) } } @@ -844,9 +842,8 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> { /// } /// ``` #[unstable(feature = "new_uninit", issue = "63291")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn write(mut boxed: Self, value: T) -> Box<T, A> { + pub fn write(mut boxed: Self, value: T) -> Box<T, A> { unsafe { (*boxed).write(value); boxed.assume_init() @@ -1090,9 +1087,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { /// /// [memory layout]: self#memory-layout #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A) { + pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) { let (leaked, alloc) = Box::into_unique(b); (leaked.as_ptr(), alloc) } @@ -1102,10 +1098,9 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { issue = "none", reason = "use `Box::leak(b).into()` or `Unique::from(Box::leak(b))` instead" )] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] #[doc(hidden)] - pub const fn into_unique(b: Self) -> (Unique<T>, A) { + pub fn into_unique(b: Self) -> (Unique<T>, A) { // Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a // raw pointer for the type system. Turning it directly into a raw pointer would not be // recognized as "releasing" the unique pointer to permit aliased raw accesses, @@ -1163,9 +1158,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { /// assert_eq!(*static_ref, [4, 2, 3]); /// ``` #[stable(feature = "box_leak", since = "1.26.0")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn leak<'a>(b: Self) -> &'a mut T + pub fn leak<'a>(b: Self) -> &'a mut T where A: 'a, { @@ -1234,8 +1228,7 @@ impl<T: Default> Default for Box<T> { #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for Box<[T]> { +impl<T> Default for Box<[T]> { #[inline] fn default() -> Self { let ptr: Unique<[T]> = Unique::<[T; 0]>::dangling(); @@ -1245,8 +1238,7 @@ impl<T> const Default for Box<[T]> { #[cfg(not(no_global_oom_handling))] #[stable(feature = "default_box_extra", since = "1.17.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for Box<str> { +impl Default for Box<str> { #[inline] fn default() -> Self { // SAFETY: This is the same as `Unique::cast<U>` but with an unsized `U = str`. @@ -1443,8 +1435,7 @@ impl<T> From<T> for Box<T> { } #[stable(feature = "pin", since = "1.33.0")] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] -impl<T: ?Sized, A: Allocator> const From<Box<T, A>> for Pin<Box<T, A>> +impl<T: ?Sized, A: Allocator> From<Box<T, A>> for Pin<Box<T, A>> where A: 'static, { @@ -1464,9 +1455,36 @@ where } } +/// Specialization trait used for `From<&[T]>`. +#[cfg(not(no_global_oom_handling))] +trait BoxFromSlice<T> { + fn from_slice(slice: &[T]) -> Self; +} + +#[cfg(not(no_global_oom_handling))] +impl<T: Clone> BoxFromSlice<T> for Box<[T]> { + #[inline] + default fn from_slice(slice: &[T]) -> Self { + slice.to_vec().into_boxed_slice() + } +} + +#[cfg(not(no_global_oom_handling))] +impl<T: Copy> BoxFromSlice<T> for Box<[T]> { + #[inline] + fn from_slice(slice: &[T]) -> Self { + let len = slice.len(); + let buf = RawVec::with_capacity(len); + unsafe { + ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len); + buf.into_box(slice.len()).assume_init() + } + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "box_from_slice", since = "1.17.0")] -impl<T: Copy> From<&[T]> for Box<[T]> { +impl<T: Clone> From<&[T]> for Box<[T]> { /// Converts a `&[T]` into a `Box<[T]>` /// /// This conversion allocates on the heap @@ -1480,19 +1498,15 @@ impl<T: Copy> From<&[T]> for Box<[T]> { /// /// println!("{boxed_slice:?}"); /// ``` + #[inline] fn from(slice: &[T]) -> Box<[T]> { - let len = slice.len(); - let buf = RawVec::with_capacity(len); - unsafe { - ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len); - buf.into_box(slice.len()).assume_init() - } + <Self as BoxFromSlice<T>>::from_slice(slice) } } #[cfg(not(no_global_oom_handling))] #[stable(feature = "box_from_cow", since = "1.45.0")] -impl<T: Copy> From<Cow<'_, [T]>> for Box<[T]> { +impl<T: Clone> From<Cow<'_, [T]>> for Box<[T]> { /// Converts a `Cow<'_, [T]>` into a `Box<[T]>` /// /// When `cow` is the `Cow::Borrowed` variant, this @@ -1880,8 +1894,7 @@ impl<T: ?Sized, A: Allocator> fmt::Pointer for Box<T, A> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] -impl<T: ?Sized, A: Allocator> const Deref for Box<T, A> { +impl<T: ?Sized, A: Allocator> Deref for Box<T, A> { type Target = T; fn deref(&self) -> &T { @@ -1890,8 +1903,7 @@ impl<T: ?Sized, A: Allocator> const Deref for Box<T, A> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] -impl<T: ?Sized, A: Allocator> const DerefMut for Box<T, A> { +impl<T: ?Sized, A: Allocator> DerefMut for Box<T, A> { fn deref_mut(&mut self) -> &mut T { &mut **self } diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index ad48315fd..f83c8f83c 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -7,7 +7,7 @@ use core::fmt::{self, Debug, Display, Formatter}; use core::marker::PhantomData; #[cfg(not(no_global_oom_handling))] use core::marker::Unsize; -use core::mem; +use core::mem::{self, SizedTypeProperties}; use core::ops::{Deref, DerefMut}; use core::ptr::Pointee; use core::ptr::{self, NonNull}; @@ -202,9 +202,7 @@ impl<H> WithHeader<H> { let ptr = if layout.size() == 0 { // Some paranoia checking, mostly so that the ThinBox tests are // more able to catch issues. - debug_assert!( - value_offset == 0 && mem::size_of::<T>() == 0 && mem::size_of::<H>() == 0 - ); + debug_assert!(value_offset == 0 && T::IS_ZST && H::IS_ZST); layout.dangling() } else { let ptr = alloc::alloc(layout); @@ -249,9 +247,7 @@ impl<H> WithHeader<H> { alloc::dealloc(self.ptr.as_ptr().sub(value_offset), layout); } else { debug_assert!( - value_offset == 0 - && mem::size_of::<H>() == 0 - && self.value_layout.size() == 0 + value_offset == 0 && H::IS_ZST && self.value_layout.size() == 0 ); } } diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index afdc99817..1f8a1ecba 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -1543,11 +1543,17 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> { self.next_back() } - fn min(mut self) -> Option<(&'a K, &'a V)> { + fn min(mut self) -> Option<(&'a K, &'a V)> + where + (&'a K, &'a V): Ord, + { self.next() } - fn max(mut self) -> Option<(&'a K, &'a V)> { + fn max(mut self) -> Option<(&'a K, &'a V)> + where + (&'a K, &'a V): Ord, + { self.next_back() } } @@ -1612,11 +1618,17 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> { self.next_back() } - fn min(mut self) -> Option<(&'a K, &'a mut V)> { + fn min(mut self) -> Option<(&'a K, &'a mut V)> + where + (&'a K, &'a mut V): Ord, + { self.next() } - fn max(mut self) -> Option<(&'a K, &'a mut V)> { + fn max(mut self) -> Option<(&'a K, &'a mut V)> + where + (&'a K, &'a mut V): Ord, + { self.next_back() } } @@ -1779,11 +1791,17 @@ impl<'a, K, V> Iterator for Keys<'a, K, V> { self.next_back() } - fn min(mut self) -> Option<&'a K> { + fn min(mut self) -> Option<&'a K> + where + &'a K: Ord, + { self.next() } - fn max(mut self) -> Option<&'a K> { + fn max(mut self) -> Option<&'a K> + where + &'a K: Ord, + { self.next_back() } } @@ -2008,11 +2026,17 @@ impl<'a, K, V> Iterator for Range<'a, K, V> { self.next_back() } - fn min(mut self) -> Option<(&'a K, &'a V)> { + fn min(mut self) -> Option<(&'a K, &'a V)> + where + (&'a K, &'a V): Ord, + { self.next() } - fn max(mut self) -> Option<(&'a K, &'a V)> { + fn max(mut self) -> Option<(&'a K, &'a V)> + where + (&'a K, &'a V): Ord, + { self.next_back() } } @@ -2081,11 +2105,17 @@ impl<K, V, A: Allocator + Clone> Iterator for IntoKeys<K, V, A> { self.next_back() } - fn min(mut self) -> Option<K> { + fn min(mut self) -> Option<K> + where + K: Ord, + { self.next() } - fn max(mut self) -> Option<K> { + fn max(mut self) -> Option<K> + where + K: Ord, + { self.next_back() } } @@ -2204,11 +2234,17 @@ impl<'a, K, V> Iterator for RangeMut<'a, K, V> { self.next_back() } - fn min(mut self) -> Option<(&'a K, &'a mut V)> { + fn min(mut self) -> Option<(&'a K, &'a mut V)> + where + (&'a K, &'a mut V): Ord, + { self.next() } - fn max(mut self) -> Option<(&'a K, &'a mut V)> { + fn max(mut self) -> Option<(&'a K, &'a mut V)> + where + (&'a K, &'a mut V): Ord, + { self.next_back() } } @@ -2985,7 +3021,7 @@ impl<'a, K, V, A> CursorMut<'a, K, V, A> { }) } - /// Returns a mutable reference to the of the element that the cursor is + /// Returns a mutable reference to the key of the element that the cursor is /// currently pointing to. /// /// This returns `None` if the cursor is currently pointing to the @@ -3043,8 +3079,8 @@ impl<'a, K, V, A> CursorMut<'a, K, V, A> { unsafe { self.root.reborrow() } .as_mut()? .borrow_mut() - .first_leaf_edge() - .next_kv() + .last_leaf_edge() + .next_back_kv() .ok()? .into_kv_valmut() } diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index da00d83bd..7ecffe3ee 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -8,6 +8,7 @@ use crate::testing::crash_test::{CrashTestDummy, Panic}; use crate::testing::ord_chaos::{Cyclic3, Governed, Governor}; use crate::testing::rng::DeterministicRng; use crate::vec::Vec; +use core::assert_matches::assert_matches; use std::cmp::Ordering; use std::iter; use std::mem; @@ -2448,3 +2449,21 @@ fn test_cursor_mut_insert_after_4() { let mut cur = map.upper_bound_mut(Bound::Included(&2)); cur.insert_after(4, 'd'); } + +#[test] +fn cursor_peek_prev_agrees_with_cursor_mut() { + let mut map = BTreeMap::from([(1, 1), (2, 2), (3, 3)]); + + let cursor = map.lower_bound(Bound::Excluded(&3)); + assert!(cursor.key().is_none()); + + let prev = cursor.peek_prev(); + assert_matches!(prev, Some((&3, _))); + + // Shadow names so the two parts of this test match. + let mut cursor = map.lower_bound_mut(Bound::Excluded(&3)); + assert!(cursor.key().is_none()); + + let prev = cursor.peek_prev(); + assert_matches!(prev, Some((&3, _))); +} diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index da952a13f..940fa30af 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1501,11 +1501,17 @@ impl<'a, T> Iterator for Iter<'a, T> { self.next_back() } - fn min(mut self) -> Option<&'a T> { + fn min(mut self) -> Option<&'a T> + where + &'a T: Ord, + { self.next() } - fn max(mut self) -> Option<&'a T> { + fn max(mut self) -> Option<&'a T> + where + &'a T: Ord, + { self.next_back() } } @@ -1604,11 +1610,17 @@ impl<'a, T> Iterator for Range<'a, T> { self.next_back() } - fn min(mut self) -> Option<&'a T> { + fn min(mut self) -> Option<&'a T> + where + &'a T: Ord, + { self.next() } - fn max(mut self) -> Option<&'a T> { + fn max(mut self) -> Option<&'a T> + where + &'a T: Ord, + { self.next_back() } } diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 106d05c57..4cd34ac2f 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -18,9 +18,10 @@ use core::hash::{Hash, Hasher}; use core::iter::FusedIterator; use core::marker::PhantomData; use core::mem; -use core::ptr::NonNull; +use core::ptr::{NonNull, Unique}; use super::SpecExtend; +use crate::alloc::{Allocator, Global}; use crate::boxed::Box; #[cfg(test)] @@ -47,11 +48,15 @@ mod tests; #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "LinkedList")] #[rustc_insignificant_dtor] -pub struct LinkedList<T> { +pub struct LinkedList< + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { head: Option<NonNull<Node<T>>>, tail: Option<NonNull<Node<T>>>, len: usize, - marker: PhantomData<Box<Node<T>>>, + alloc: A, + marker: PhantomData<Box<Node<T>, A>>, } struct Node<T> { @@ -81,6 +86,7 @@ impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> { head: self.head, tail: self.tail, len: self.len, + alloc: Global, marker: PhantomData, })) .field(&self.len) @@ -117,6 +123,7 @@ impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> { head: self.head, tail: self.tail, len: self.len, + alloc: Global, marker: PhantomData, })) .field(&self.len) @@ -132,12 +139,15 @@ impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> { /// [`into_iter`]: LinkedList::into_iter #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] -pub struct IntoIter<T> { - list: LinkedList<T>, +pub struct IntoIter< + T, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { + list: LinkedList<T, A>, } #[stable(feature = "collection_debug", since = "1.17.0")] -impl<T: fmt::Debug> fmt::Debug for IntoIter<T> { +impl<T: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("IntoIter").field(&self.list).finish() } @@ -148,22 +158,25 @@ impl<T> Node<T> { Node { next: None, prev: None, element } } - fn into_element(self: Box<Self>) -> T { + fn into_element<A: Allocator>(self: Box<Self, A>) -> T { self.element } } // private methods -impl<T> LinkedList<T> { +impl<T, A: Allocator> LinkedList<T, A> { /// Adds the given node to the front of the list. + /// + /// # Safety + /// `node` must point to a valid node that was boxed using the list's allocator. #[inline] - fn push_front_node(&mut self, mut node: Box<Node<T>>) { + unsafe fn push_front_node(&mut self, node: Unique<Node<T>>) { // This method takes care not to create mutable references to whole nodes, // to maintain validity of aliasing pointers into `element`. unsafe { - node.next = self.head; - node.prev = None; - let node = Some(Box::leak(node).into()); + (*node.as_ptr()).next = self.head; + (*node.as_ptr()).prev = None; + let node = Some(NonNull::from(node)); match self.head { None => self.tail = node, @@ -178,11 +191,11 @@ impl<T> LinkedList<T> { /// Removes and returns the node at the front of the list. #[inline] - fn pop_front_node(&mut self) -> Option<Box<Node<T>>> { + fn pop_front_node(&mut self) -> Option<Box<Node<T>, &A>> { // This method takes care not to create mutable references to whole nodes, // to maintain validity of aliasing pointers into `element`. self.head.map(|node| unsafe { - let node = Box::from_raw(node.as_ptr()); + let node = Box::from_raw_in(node.as_ptr(), &self.alloc); self.head = node.next; match self.head { @@ -197,14 +210,17 @@ impl<T> LinkedList<T> { } /// Adds the given node to the back of the list. + /// + /// # Safety + /// `node` must point to a valid node that was boxed using the list's allocator. #[inline] - fn push_back_node(&mut self, mut node: Box<Node<T>>) { + unsafe fn push_back_node(&mut self, node: Unique<Node<T>>) { // This method takes care not to create mutable references to whole nodes, // to maintain validity of aliasing pointers into `element`. unsafe { - node.next = None; - node.prev = self.tail; - let node = Some(Box::leak(node).into()); + (*node.as_ptr()).next = None; + (*node.as_ptr()).prev = self.tail; + let node = Some(NonNull::from(node)); match self.tail { None => self.head = node, @@ -219,11 +235,11 @@ impl<T> LinkedList<T> { /// Removes and returns the node at the back of the list. #[inline] - fn pop_back_node(&mut self) -> Option<Box<Node<T>>> { + fn pop_back_node(&mut self) -> Option<Box<Node<T>, &A>> { // This method takes care not to create mutable references to whole nodes, // to maintain validity of aliasing pointers into `element`. self.tail.map(|node| unsafe { - let node = Box::from_raw(node.as_ptr()); + let node = Box::from_raw_in(node.as_ptr(), &self.alloc); self.tail = node.prev; match self.tail { @@ -321,7 +337,10 @@ impl<T> LinkedList<T> { &mut self, split_node: Option<NonNull<Node<T>>>, at: usize, - ) -> Self { + ) -> Self + where + A: Clone, + { // The split node is the new head node of the second part if let Some(mut split_node) = split_node { let first_part_head; @@ -342,6 +361,7 @@ impl<T> LinkedList<T> { head: first_part_head, tail: first_part_tail, len: at, + alloc: self.alloc.clone(), marker: PhantomData, }; @@ -351,7 +371,7 @@ impl<T> LinkedList<T> { first_part } else { - mem::replace(self, LinkedList::new()) + mem::replace(self, LinkedList::new_in(self.alloc.clone())) } } @@ -360,7 +380,10 @@ impl<T> LinkedList<T> { &mut self, split_node: Option<NonNull<Node<T>>>, at: usize, - ) -> Self { + ) -> Self + where + A: Clone, + { // The split node is the new tail node of the first part and owns // the head of the second part. if let Some(mut split_node) = split_node { @@ -382,6 +405,7 @@ impl<T> LinkedList<T> { head: second_part_head, tail: second_part_tail, len: self.len - at, + alloc: self.alloc.clone(), marker: PhantomData, }; @@ -391,7 +415,7 @@ impl<T> LinkedList<T> { second_part } else { - mem::replace(self, LinkedList::new()) + mem::replace(self, LinkedList::new_in(self.alloc.clone())) } } } @@ -420,7 +444,7 @@ impl<T> LinkedList<T> { #[stable(feature = "rust1", since = "1.0.0")] #[must_use] pub const fn new() -> Self { - LinkedList { head: None, tail: None, len: 0, marker: PhantomData } + LinkedList { head: None, tail: None, len: 0, alloc: Global, marker: PhantomData } } /// Moves all elements from `other` to the end of the list. @@ -471,7 +495,26 @@ impl<T> LinkedList<T> { } } } +} +impl<T, A: Allocator> LinkedList<T, A> { + /// Constructs an empty `LinkedList<T, A>`. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_api)] + /// + /// use std::alloc::System; + /// use std::collections::LinkedList; + /// + /// let list: LinkedList<u32, _> = LinkedList::new_in(System); + /// ``` + #[inline] + #[unstable(feature = "allocator_api", issue = "32838")] + pub const fn new_in(alloc: A) -> Self { + LinkedList { head: None, tail: None, len: 0, alloc, marker: PhantomData } + } /// Provides a forward iterator. /// /// # Examples @@ -532,7 +575,7 @@ impl<T> LinkedList<T> { #[inline] #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn cursor_front(&self) -> Cursor<'_, T> { + pub fn cursor_front(&self) -> Cursor<'_, T, A> { Cursor { index: 0, current: self.head, list: self } } @@ -542,7 +585,7 @@ impl<T> LinkedList<T> { #[inline] #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn cursor_front_mut(&mut self) -> CursorMut<'_, T> { + pub fn cursor_front_mut(&mut self) -> CursorMut<'_, T, A> { CursorMut { index: 0, current: self.head, list: self } } @@ -552,7 +595,7 @@ impl<T> LinkedList<T> { #[inline] #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn cursor_back(&self) -> Cursor<'_, T> { + pub fn cursor_back(&self) -> Cursor<'_, T, A> { Cursor { index: self.len.checked_sub(1).unwrap_or(0), current: self.tail, list: self } } @@ -562,7 +605,7 @@ impl<T> LinkedList<T> { #[inline] #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn cursor_back_mut(&mut self) -> CursorMut<'_, T> { + pub fn cursor_back_mut(&mut self) -> CursorMut<'_, T, A> { CursorMut { index: self.len.checked_sub(1).unwrap_or(0), current: self.tail, list: self } } @@ -638,7 +681,15 @@ impl<T> LinkedList<T> { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn clear(&mut self) { - *self = Self::new(); + // We need to drop the nodes while keeping self.alloc + // We can do this by moving (head, tail, len) into a new list that borrows self.alloc + drop(LinkedList { + head: self.head.take(), + tail: self.tail.take(), + len: mem::take(&mut self.len), + alloc: &self.alloc, + marker: PhantomData, + }); } /// Returns `true` if the `LinkedList` contains an element equal to the @@ -790,7 +841,12 @@ impl<T> LinkedList<T> { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn push_front(&mut self, elt: T) { - self.push_front_node(Box::new(Node::new(elt))); + let node = Box::new_in(Node::new(elt), &self.alloc); + let node_ptr = Unique::from(Box::leak(node)); + // SAFETY: node_ptr is a unique pointer to a node we boxed with self.alloc + unsafe { + self.push_front_node(node_ptr); + } } /// Removes the first element and returns it, or `None` if the list is @@ -833,7 +889,12 @@ impl<T> LinkedList<T> { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn push_back(&mut self, elt: T) { - self.push_back_node(Box::new(Node::new(elt))); + let node = Box::new_in(Node::new(elt), &self.alloc); + let node_ptr = Unique::from(Box::leak(node)); + // SAFETY: node_ptr is a unique pointer to a node we boxed with self.alloc + unsafe { + self.push_back_node(node_ptr); + } } /// Removes the last element from a list and returns it, or `None` if @@ -883,13 +944,16 @@ impl<T> LinkedList<T> { /// assert_eq!(split.pop_front(), None); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn split_off(&mut self, at: usize) -> LinkedList<T> { + pub fn split_off(&mut self, at: usize) -> LinkedList<T, A> + where + A: Clone, + { let len = self.len(); assert!(at <= len, "Cannot split off at a nonexistent index"); if at == 0 { - return mem::take(self); + return mem::replace(self, Self::new_in(self.alloc.clone())); } else if at == len { - return Self::new(); + return Self::new_in(self.alloc.clone()); } // Below, we iterate towards the `i-1`th node, either from the start or the end, @@ -987,7 +1051,7 @@ impl<T> LinkedList<T> { /// assert_eq!(odds.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 9, 11, 13, 15]); /// ``` #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] - pub fn drain_filter<F>(&mut self, filter: F) -> DrainFilter<'_, T, F> + pub fn drain_filter<F>(&mut self, filter: F) -> DrainFilter<'_, T, F, A> where F: FnMut(&mut T) -> bool, { @@ -1000,11 +1064,11 @@ impl<T> LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<#[may_dangle] T> Drop for LinkedList<T> { +unsafe impl<#[may_dangle] T, A: Allocator> Drop for LinkedList<T, A> { fn drop(&mut self) { - struct DropGuard<'a, T>(&'a mut LinkedList<T>); + struct DropGuard<'a, T, A: Allocator>(&'a mut LinkedList<T, A>); - impl<'a, T> Drop for DropGuard<'a, T> { + impl<'a, T, A: Allocator> Drop for DropGuard<'a, T, A> { fn drop(&mut self) { // Continue the same loop we do below. This only runs when a destructor has // panicked. If another one panics this will abort. @@ -1012,11 +1076,10 @@ unsafe impl<#[may_dangle] T> Drop for LinkedList<T> { } } - while let Some(node) = self.pop_front_node() { - let guard = DropGuard(self); - drop(node); - mem::forget(guard); - } + // Wrap self so that if a destructor panics, we can try to keep looping + let guard = DropGuard(self); + while guard.0.pop_front_node().is_some() {} + mem::forget(guard); } } @@ -1159,14 +1222,18 @@ impl<T> Default for IterMut<'_, T> { /// /// When created, cursors start at the front of the list, or the "ghost" non-element if the list is empty. #[unstable(feature = "linked_list_cursors", issue = "58533")] -pub struct Cursor<'a, T: 'a> { +pub struct Cursor< + 'a, + T: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { index: usize, current: Option<NonNull<Node<T>>>, - list: &'a LinkedList<T>, + list: &'a LinkedList<T, A>, } #[unstable(feature = "linked_list_cursors", issue = "58533")] -impl<T> Clone for Cursor<'_, T> { +impl<T, A: Allocator> Clone for Cursor<'_, T, A> { fn clone(&self) -> Self { let Cursor { index, current, list } = *self; Cursor { index, current, list } @@ -1174,7 +1241,7 @@ impl<T> Clone for Cursor<'_, T> { } #[unstable(feature = "linked_list_cursors", issue = "58533")] -impl<T: fmt::Debug> fmt::Debug for Cursor<'_, T> { +impl<T: fmt::Debug, A: Allocator> fmt::Debug for Cursor<'_, T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Cursor").field(&self.list).field(&self.index()).finish() } @@ -1191,20 +1258,24 @@ impl<T: fmt::Debug> fmt::Debug for Cursor<'_, T> { /// To accommodate this, there is a "ghost" non-element that yields `None` between the head and /// tail of the list. #[unstable(feature = "linked_list_cursors", issue = "58533")] -pub struct CursorMut<'a, T: 'a> { +pub struct CursorMut< + 'a, + T: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> { index: usize, current: Option<NonNull<Node<T>>>, - list: &'a mut LinkedList<T>, + list: &'a mut LinkedList<T, A>, } #[unstable(feature = "linked_list_cursors", issue = "58533")] -impl<T: fmt::Debug> fmt::Debug for CursorMut<'_, T> { +impl<T: fmt::Debug, A: Allocator> fmt::Debug for CursorMut<'_, T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("CursorMut").field(&self.list).field(&self.index()).finish() } } -impl<'a, T> Cursor<'a, T> { +impl<'a, T, A: Allocator> Cursor<'a, T, A> { /// Returns the cursor position index within the `LinkedList`. /// /// This returns `None` if the cursor is currently pointing to the @@ -1321,7 +1392,7 @@ impl<'a, T> Cursor<'a, T> { } } -impl<'a, T> CursorMut<'a, T> { +impl<'a, T, A: Allocator> CursorMut<'a, T, A> { /// Returns the cursor position index within the `LinkedList`. /// /// This returns `None` if the cursor is currently pointing to the @@ -1426,7 +1497,7 @@ impl<'a, T> CursorMut<'a, T> { /// `CursorMut` is frozen for the lifetime of the `Cursor`. #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn as_cursor(&self) -> Cursor<'_, T> { + pub fn as_cursor(&self) -> Cursor<'_, T, A> { Cursor { list: self.list, current: self.current, index: self.index } } } @@ -1434,6 +1505,51 @@ impl<'a, T> CursorMut<'a, T> { // Now the list editing operations impl<'a, T> CursorMut<'a, T> { + /// Inserts the elements from the given `LinkedList` after the current one. + /// + /// If the cursor is pointing at the "ghost" non-element then the new elements are + /// inserted at the start of the `LinkedList`. + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn splice_after(&mut self, list: LinkedList<T>) { + unsafe { + let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() { + Some(parts) => parts, + _ => return, + }; + let node_next = match self.current { + None => self.list.head, + Some(node) => node.as_ref().next, + }; + self.list.splice_nodes(self.current, node_next, splice_head, splice_tail, splice_len); + if self.current.is_none() { + // The "ghost" non-element's index has changed. + self.index = self.list.len; + } + } + } + + /// Inserts the elements from the given `LinkedList` before the current one. + /// + /// If the cursor is pointing at the "ghost" non-element then the new elements are + /// inserted at the end of the `LinkedList`. + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn splice_before(&mut self, list: LinkedList<T>) { + unsafe { + let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() { + Some(parts) => parts, + _ => return, + }; + let node_prev = match self.current { + None => self.list.tail, + Some(node) => node.as_ref().prev, + }; + self.list.splice_nodes(node_prev, self.current, splice_head, splice_tail, splice_len); + self.index += splice_len; + } + } +} + +impl<'a, T, A: Allocator> CursorMut<'a, T, A> { /// Inserts a new element into the `LinkedList` after the current one. /// /// If the cursor is pointing at the "ghost" non-element then the new element is @@ -1441,7 +1557,7 @@ impl<'a, T> CursorMut<'a, T> { #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn insert_after(&mut self, item: T) { unsafe { - let spliced_node = Box::leak(Box::new(Node::new(item))).into(); + let spliced_node = Box::leak(Box::new_in(Node::new(item), &self.list.alloc)).into(); let node_next = match self.current { None => self.list.head, Some(node) => node.as_ref().next, @@ -1461,7 +1577,7 @@ impl<'a, T> CursorMut<'a, T> { #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn insert_before(&mut self, item: T) { unsafe { - let spliced_node = Box::leak(Box::new(Node::new(item))).into(); + let spliced_node = Box::leak(Box::new_in(Node::new(item), &self.list.alloc)).into(); let node_prev = match self.current { None => self.list.tail, Some(node) => node.as_ref().prev, @@ -1497,7 +1613,10 @@ impl<'a, T> CursorMut<'a, T> { /// If the cursor is currently pointing to the "ghost" non-element then no element /// is removed and `None` is returned. #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn remove_current_as_list(&mut self) -> Option<LinkedList<T>> { + pub fn remove_current_as_list(&mut self) -> Option<LinkedList<T, A>> + where + A: Clone, + { let mut unlinked_node = self.current?; unsafe { self.current = unlinked_node.as_ref().next; @@ -1509,54 +1628,12 @@ impl<'a, T> CursorMut<'a, T> { head: Some(unlinked_node), tail: Some(unlinked_node), len: 1, + alloc: self.list.alloc.clone(), marker: PhantomData, }) } } - /// Inserts the elements from the given `LinkedList` after the current one. - /// - /// If the cursor is pointing at the "ghost" non-element then the new elements are - /// inserted at the start of the `LinkedList`. - #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn splice_after(&mut self, list: LinkedList<T>) { - unsafe { - let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() { - Some(parts) => parts, - _ => return, - }; - let node_next = match self.current { - None => self.list.head, - Some(node) => node.as_ref().next, - }; - self.list.splice_nodes(self.current, node_next, splice_head, splice_tail, splice_len); - if self.current.is_none() { - // The "ghost" non-element's index has changed. - self.index = self.list.len; - } - } - } - - /// Inserts the elements from the given `LinkedList` before the current one. - /// - /// If the cursor is pointing at the "ghost" non-element then the new elements are - /// inserted at the end of the `LinkedList`. - #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn splice_before(&mut self, list: LinkedList<T>) { - unsafe { - let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() { - Some(parts) => parts, - _ => return, - }; - let node_prev = match self.current { - None => self.list.tail, - Some(node) => node.as_ref().prev, - }; - self.list.splice_nodes(node_prev, self.current, splice_head, splice_tail, splice_len); - self.index += splice_len; - } - } - /// Splits the list into two after the current element. This will return a /// new list consisting of everything after the cursor, with the original /// list retaining everything before. @@ -1564,7 +1641,10 @@ impl<'a, T> CursorMut<'a, T> { /// If the cursor is pointing at the "ghost" non-element then the entire contents /// of the `LinkedList` are moved. #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn split_after(&mut self) -> LinkedList<T> { + pub fn split_after(&mut self) -> LinkedList<T, A> + where + A: Clone, + { let split_off_idx = if self.index == self.list.len { 0 } else { self.index + 1 }; if self.index == self.list.len { // The "ghost" non-element's index has changed to 0. @@ -1580,7 +1660,10 @@ impl<'a, T> CursorMut<'a, T> { /// If the cursor is pointing at the "ghost" non-element then the entire contents /// of the `LinkedList` are moved. #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn split_before(&mut self) -> LinkedList<T> { + pub fn split_before(&mut self) -> LinkedList<T, A> + where + A: Clone, + { let split_off_idx = self.index; self.index = 0; unsafe { self.list.split_off_before_node(self.current, split_off_idx) } @@ -1722,11 +1805,15 @@ impl<'a, T> CursorMut<'a, T> { /// An iterator produced by calling `drain_filter` on LinkedList. #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -pub struct DrainFilter<'a, T: 'a, F: 'a> -where +pub struct DrainFilter< + 'a, + T: 'a, + F: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +> where F: FnMut(&mut T) -> bool, { - list: &'a mut LinkedList<T>, + list: &'a mut LinkedList<T, A>, it: Option<NonNull<Node<T>>>, pred: F, idx: usize, @@ -1734,7 +1821,7 @@ where } #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl<T, F> Iterator for DrainFilter<'_, T, F> +impl<T, F, A: Allocator> Iterator for DrainFilter<'_, T, F, A> where F: FnMut(&mut T) -> bool, { @@ -1763,16 +1850,16 @@ where } #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl<T, F> Drop for DrainFilter<'_, T, F> +impl<T, F, A: Allocator> Drop for DrainFilter<'_, T, F, A> where F: FnMut(&mut T) -> bool, { fn drop(&mut self) { - struct DropGuard<'r, 'a, T, F>(&'r mut DrainFilter<'a, T, F>) + struct DropGuard<'r, 'a, T, F, A: Allocator>(&'r mut DrainFilter<'a, T, F, A>) where F: FnMut(&mut T) -> bool; - impl<'r, 'a, T, F> Drop for DropGuard<'r, 'a, T, F> + impl<'r, 'a, T, F, A: Allocator> Drop for DropGuard<'r, 'a, T, F, A> where F: FnMut(&mut T) -> bool, { @@ -1800,7 +1887,7 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<T> Iterator for IntoIter<T> { +impl<T, A: Allocator> Iterator for IntoIter<T, A> { type Item = T; #[inline] @@ -1815,7 +1902,7 @@ impl<T> Iterator for IntoIter<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T> DoubleEndedIterator for IntoIter<T> { +impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> { #[inline] fn next_back(&mut self) -> Option<T> { self.list.pop_back() @@ -1823,10 +1910,10 @@ impl<T> DoubleEndedIterator for IntoIter<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T> ExactSizeIterator for IntoIter<T> {} +impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {} #[stable(feature = "fused", since = "1.26.0")] -impl<T> FusedIterator for IntoIter<T> {} +impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {} #[stable(feature = "default_iters", since = "1.70.0")] impl<T> Default for IntoIter<T> { @@ -1852,19 +1939,19 @@ impl<T> FromIterator<T> for LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T> IntoIterator for LinkedList<T> { +impl<T, A: Allocator> IntoIterator for LinkedList<T, A> { type Item = T; - type IntoIter = IntoIter<T>; + type IntoIter = IntoIter<T, A>; /// Consumes the list into an iterator yielding elements by value. #[inline] - fn into_iter(self) -> IntoIter<T> { + fn into_iter(self) -> IntoIter<T, A> { IntoIter { list: self } } } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a LinkedList<T> { +impl<'a, T, A: Allocator> IntoIterator for &'a LinkedList<T, A> { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -1874,7 +1961,7 @@ impl<'a, T> IntoIterator for &'a LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a mut LinkedList<T> { +impl<'a, T, A: Allocator> IntoIterator for &'a mut LinkedList<T, A> { type Item = &'a mut T; type IntoIter = IterMut<'a, T>; @@ -1884,7 +1971,7 @@ impl<'a, T> IntoIterator for &'a mut LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T> Extend<T> for LinkedList<T> { +impl<T, A: Allocator> Extend<T> for LinkedList<T, A> { fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { <Self as SpecExtend<I>>::spec_extend(self, iter); } @@ -1895,7 +1982,7 @@ impl<T> Extend<T> for LinkedList<T> { } } -impl<I: IntoIterator> SpecExtend<I> for LinkedList<I::Item> { +impl<I: IntoIterator, A: Allocator> SpecExtend<I> for LinkedList<I::Item, A> { default fn spec_extend(&mut self, iter: I) { iter.into_iter().for_each(move |elt| self.push_back(elt)); } @@ -1908,7 +1995,7 @@ impl<T> SpecExtend<LinkedList<T>> for LinkedList<T> { } #[stable(feature = "extend_ref", since = "1.2.0")] -impl<'a, T: 'a + Copy> Extend<&'a T> for LinkedList<T> { +impl<'a, T: 'a + Copy, A: Allocator> Extend<&'a T> for LinkedList<T, A> { fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) { self.extend(iter.into_iter().cloned()); } @@ -1920,7 +2007,7 @@ impl<'a, T: 'a + Copy> Extend<&'a T> for LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: PartialEq> PartialEq for LinkedList<T> { +impl<T: PartialEq, A: Allocator> PartialEq for LinkedList<T, A> { fn eq(&self, other: &Self) -> bool { self.len() == other.len() && self.iter().eq(other) } @@ -1931,17 +2018,17 @@ impl<T: PartialEq> PartialEq for LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Eq> Eq for LinkedList<T> {} +impl<T: Eq, A: Allocator> Eq for LinkedList<T, A> {} #[stable(feature = "rust1", since = "1.0.0")] -impl<T: PartialOrd> PartialOrd for LinkedList<T> { +impl<T: PartialOrd, A: Allocator> PartialOrd for LinkedList<T, A> { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { self.iter().partial_cmp(other) } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Ord> Ord for LinkedList<T> { +impl<T: Ord, A: Allocator> Ord for LinkedList<T, A> { #[inline] fn cmp(&self, other: &Self) -> Ordering { self.iter().cmp(other) @@ -1949,9 +2036,11 @@ impl<T: Ord> Ord for LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Clone> Clone for LinkedList<T> { +impl<T: Clone, A: Allocator + Clone> Clone for LinkedList<T, A> { fn clone(&self) -> Self { - self.iter().cloned().collect() + let mut list = Self::new_in(self.alloc.clone()); + list.extend(self.iter().cloned()); + list } fn clone_from(&mut self, other: &Self) { @@ -1969,14 +2058,14 @@ impl<T: Clone> Clone for LinkedList<T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: fmt::Debug> fmt::Debug for LinkedList<T> { +impl<T: fmt::Debug, A: Allocator> fmt::Debug for LinkedList<T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self).finish() } } #[stable(feature = "rust1", since = "1.0.0")] -impl<T: Hash> Hash for LinkedList<T> { +impl<T: Hash, A: Allocator> Hash for LinkedList<T, A> { fn hash<H: Hasher>(&self, state: &mut H) { state.write_length_prefix(self.len()); for elt in self { @@ -2016,10 +2105,10 @@ fn assert_covariance() { } #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<T: Send> Send for LinkedList<T> {} +unsafe impl<T: Send, A: Allocator + Send> Send for LinkedList<T, A> {} #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<T: Sync> Sync for LinkedList<T> {} +unsafe impl<T: Sync, A: Allocator + Sync> Sync for LinkedList<T, A> {} #[stable(feature = "rust1", since = "1.0.0")] unsafe impl<T: Sync> Send for Iter<'_, T> {} @@ -2034,13 +2123,13 @@ unsafe impl<T: Send> Send for IterMut<'_, T> {} unsafe impl<T: Sync> Sync for IterMut<'_, T> {} #[unstable(feature = "linked_list_cursors", issue = "58533")] -unsafe impl<T: Sync> Send for Cursor<'_, T> {} +unsafe impl<T: Sync, A: Allocator + Sync> Send for Cursor<'_, T, A> {} #[unstable(feature = "linked_list_cursors", issue = "58533")] -unsafe impl<T: Sync> Sync for Cursor<'_, T> {} +unsafe impl<T: Sync, A: Allocator + Sync> Sync for Cursor<'_, T, A> {} #[unstable(feature = "linked_list_cursors", issue = "58533")] -unsafe impl<T: Send> Send for CursorMut<'_, T> {} +unsafe impl<T: Send, A: Allocator + Send> Send for CursorMut<'_, T, A> {} #[unstable(feature = "linked_list_cursors", issue = "58533")] -unsafe impl<T: Sync> Sync for CursorMut<'_, T> {} +unsafe impl<T: Sync, A: Allocator + Sync> Sync for CursorMut<'_, T, A> {} diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 8916b42ed..896da37f9 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2815,7 +2815,7 @@ impl<'a, T: 'a + Copy, A: Allocator> Extend<&'a T> for VecDeque<T, A> { } #[inline] - fn extend_one(&mut self, &elem: &T) { + fn extend_one(&mut self, &elem: &'a T) { self.push_back(elem); } diff --git a/library/alloc/src/collections/vec_deque/spec_from_iter.rs b/library/alloc/src/collections/vec_deque/spec_from_iter.rs index 7650492eb..2708c7fe1 100644 --- a/library/alloc/src/collections/vec_deque/spec_from_iter.rs +++ b/library/alloc/src/collections/vec_deque/spec_from_iter.rs @@ -12,7 +12,7 @@ where default fn spec_from_iter(iterator: I) -> Self { // Since converting is O(1) now, just re-use the `Vec` logic for // anything where we can't do something extra-special for `VecDeque`, - // especially as that could save us some monomorphiziation work + // especially as that could save us some monomorphization work // if one uses the same iterators (like slice ones) with both. crate::vec::Vec::from_iter(iterator).into() } diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs index 1da86e1a4..fb8d00e8d 100644 --- a/library/alloc/src/fmt.rs +++ b/library/alloc/src/fmt.rs @@ -363,7 +363,7 @@ //! # use std::fmt; //! # struct Foo; // our custom type //! # impl fmt::Display for Foo { -//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +//! fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { //! # write!(f, "testing, testing") //! # } } //! ``` @@ -399,7 +399,7 @@ //! } //! //! impl fmt::Display for Vector2D { -//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +//! fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { //! // The `f` value implements the `Write` trait, which is what the //! // write! macro is expecting. Note that this formatting ignores the //! // various flags provided to format strings. @@ -410,7 +410,7 @@ //! // Different traits allow different forms of output of a type. The meaning //! // of this format is to print the magnitude of a vector. //! impl fmt::Binary for Vector2D { -//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +//! fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { //! let magnitude = (self.x * self.x + self.y * self.y) as f64; //! let magnitude = magnitude.sqrt(); //! @@ -517,7 +517,7 @@ //! let mut some_writer = io::stdout(); //! write!(&mut some_writer, "{}", format_args!("print with a {}", "macro")); //! -//! fn my_fmt_fn(args: fmt::Arguments) { +//! fn my_fmt_fn(args: fmt::Arguments<'_>) { //! write!(&mut io::stdout(), "{args}"); //! } //! my_fmt_fn(format_args!(", or a {} too", "function")); @@ -551,8 +551,6 @@ #![stable(feature = "rust1", since = "1.0.0")] -#[unstable(feature = "fmt_internals", issue = "none")] -pub use core::fmt::rt; #[stable(feature = "fmt_flags_align", since = "1.28.0")] pub use core::fmt::Alignment; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index aa240c37e..59fa91c10 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -101,19 +101,18 @@ #![feature(array_into_iter_constructors)] #![feature(array_methods)] #![feature(array_windows)] +#![feature(ascii_char)] #![feature(assert_matches)] #![feature(async_iterator)] #![feature(coerce_unsized)] #![feature(const_align_of_val)] #![feature(const_box)] -#![feature(const_convert)] #![feature(const_cow_is_borrowed)] #![feature(const_eval_select)] #![feature(const_maybe_uninit_as_mut_ptr)] #![feature(const_maybe_uninit_write)] #![feature(const_maybe_uninit_zeroed)] #![feature(const_pin)] -#![feature(const_ptr_read)] #![feature(const_refs_to_cell)] #![feature(const_size_of_val)] #![feature(const_waker)] @@ -174,7 +173,6 @@ #![feature(associated_type_bounds)] #![feature(c_unwind)] #![feature(cfg_sanitize)] -#![feature(const_deref)] #![feature(const_mut_refs)] #![feature(const_precise_live_drops)] #![feature(const_ptr_write)] diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index ba035fb06..38a711ac7 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2039,7 +2039,7 @@ where /// ```rust /// # use std::rc::Rc; /// # use std::borrow::Cow; - /// let cow: Cow<str> = Cow::Borrowed("eggplant"); + /// let cow: Cow<'_, str> = Cow::Borrowed("eggplant"); /// let shared: Rc<str> = Rc::from(cow); /// assert_eq!("eggplant", &shared[..]); /// ``` diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index b87ef59f6..849774099 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -404,12 +404,12 @@ impl str { // See https://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992 // for the definition of `Final_Sigma`. debug_assert!('Σ'.len_utf8() == 2); - let is_word_final = case_ignoreable_then_cased(from[..i].chars().rev()) - && !case_ignoreable_then_cased(from[i + 2..].chars()); + let is_word_final = case_ignorable_then_cased(from[..i].chars().rev()) + && !case_ignorable_then_cased(from[i + 2..].chars()); to.push_str(if is_word_final { "ς" } else { "σ" }); } - fn case_ignoreable_then_cased<I: Iterator<Item = char>>(iter: I) -> bool { + fn case_ignorable_then_cased<I: Iterator<Item = char>>(iter: I) -> bool { use core::unicode::{Case_Ignorable, Cased}; match iter.skip_while(|&c| Case_Ignorable(c)).next() { Some(c) => Cased(c), diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index be41919b9..59e3f887b 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1851,7 +1851,7 @@ impl String { } /// Consumes and leaks the `String`, returning a mutable reference to the contents, - /// `&'static mut str`. + /// `&'a mut str`. /// /// This is mainly useful for data that lives for the remainder of /// the program's life. Dropping the returned reference will cause a memory @@ -1874,7 +1874,7 @@ impl String { /// ``` #[unstable(feature = "string_leak", issue = "102929")] #[inline] - pub fn leak(self) -> &'static mut str { + pub fn leak<'a>(self) -> &'a mut str { let slice = self.vec.leak(); unsafe { from_utf8_unchecked_mut(slice) } } @@ -2247,8 +2247,7 @@ impl_eq! { Cow<'a, str>, &'b str } impl_eq! { Cow<'a, str>, String } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl const Default for String { +impl Default for String { /// Creates an empty `String`. #[inline] fn default() -> String { @@ -2528,6 +2527,15 @@ impl<T: fmt::Display + ?Sized> ToString for T { } #[cfg(not(no_global_oom_handling))] +#[unstable(feature = "ascii_char", issue = "110998")] +impl ToString for core::ascii::Char { + #[inline] + fn to_string(&self) -> String { + self.as_str().to_owned() + } +} + +#[cfg(not(no_global_oom_handling))] #[stable(feature = "char_to_string_specialization", since = "1.46.0")] impl ToString for char { #[inline] @@ -2615,6 +2623,15 @@ impl ToString for String { } } +#[cfg(not(no_global_oom_handling))] +#[stable(feature = "fmt_arguments_to_string_specialization", since = "1.71.0")] +impl ToString for fmt::Arguments<'_> { + #[inline] + fn to_string(&self) -> String { + crate::fmt::format(*self) + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl AsRef<str> for String { #[inline] @@ -2733,7 +2750,7 @@ impl<'a> From<Cow<'a, str>> for String { /// ``` /// # use std::borrow::Cow; /// // If the string is not owned... - /// let cow: Cow<str> = Cow::Borrowed("eggplant"); + /// let cow: Cow<'_, str> = Cow::Borrowed("eggplant"); /// // It will allocate on the heap and copy the string. /// let owned: String = String::from(cow); /// assert_eq!(&owned[..], "eggplant"); diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 24849d52d..bfdb7a92b 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -502,6 +502,7 @@ impl<T> Arc<T> { /// assert_eq!(*five, 5) /// ``` #[cfg(not(no_global_oom_handling))] + #[inline] #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] pub fn new_uninit() -> Arc<mem::MaybeUninit<T>> { @@ -535,6 +536,7 @@ impl<T> Arc<T> { /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] + #[inline] #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] pub fn new_zeroed() -> Arc<mem::MaybeUninit<T>> { @@ -844,6 +846,7 @@ impl<T> Arc<[T]> { /// assert_eq!(*values, [1, 2, 3]) /// ``` #[cfg(not(no_global_oom_handling))] + #[inline] #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> { @@ -871,6 +874,7 @@ impl<T> Arc<[T]> { /// /// [zeroed]: mem::MaybeUninit::zeroed #[cfg(not(no_global_oom_handling))] + #[inline] #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit<T>]> { @@ -1300,10 +1304,10 @@ impl<T: ?Sized> Arc<T> { mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>, ) -> *mut ArcInner<T> { let layout = arcinner_layout_for_value_layout(value_layout); - unsafe { - Arc::try_allocate_for_layout(value_layout, allocate, mem_to_arcinner) - .unwrap_or_else(|_| handle_alloc_error(layout)) - } + + let ptr = allocate(layout).unwrap_or_else(|_| handle_alloc_error(layout)); + + unsafe { Self::initialize_arcinner(ptr, layout, mem_to_arcinner) } } /// Allocates an `ArcInner<T>` with sufficient space for @@ -1321,7 +1325,16 @@ impl<T: ?Sized> Arc<T> { let ptr = allocate(layout)?; - // Initialize the ArcInner + let inner = unsafe { Self::initialize_arcinner(ptr, layout, mem_to_arcinner) }; + + Ok(inner) + } + + unsafe fn initialize_arcinner( + ptr: NonNull<[u8]>, + layout: Layout, + mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>, + ) -> *mut ArcInner<T> { let inner = mem_to_arcinner(ptr.as_non_null_ptr().as_ptr()); debug_assert_eq!(unsafe { Layout::for_value(&*inner) }, layout); @@ -1330,7 +1343,7 @@ impl<T: ?Sized> Arc<T> { ptr::write(&mut (*inner).weak, atomic::AtomicUsize::new(1)); } - Ok(inner) + inner } /// Allocates an `ArcInner<T>` with sufficient space for an unsized inner value. @@ -2768,7 +2781,7 @@ where /// ```rust /// # use std::sync::Arc; /// # use std::borrow::Cow; - /// let cow: Cow<str> = Cow::Borrowed("eggplant"); + /// let cow: Cow<'_, str> = Cow::Borrowed("eggplant"); /// let shared: Arc<str> = Arc::from(cow); /// assert_eq!("eggplant", &shared[..]); /// ``` diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs index 9d8e309a9..5d9772b87 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -39,6 +39,7 @@ use crate::sync::Arc; /// use std::sync::Arc; /// use std::task::{Context, Poll, Wake}; /// use std::thread::{self, Thread}; +/// use core::pin::pin; /// /// /// A waker that wakes up the current thread when called. /// struct ThreadWaker(Thread); @@ -52,7 +53,7 @@ use crate::sync::Arc; /// /// Run a future to completion on the current thread. /// fn block_on<T>(fut: impl Future<Output = T>) -> T { /// // Pin the future so it can be polled. -/// let mut fut = Box::pin(fut); +/// let mut fut = pin!(fut); /// /// // Create a new context to be passed to the future. /// let t = thread::current(); diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs index 2b1a787cc..f0b63759a 100644 --- a/library/alloc/src/vec/drain.rs +++ b/library/alloc/src/vec/drain.rs @@ -16,7 +16,7 @@ use super::Vec; /// /// ``` /// let mut v = vec![0, 1, 2]; -/// let iter: std::vec::Drain<_> = v.drain(..); +/// let iter: std::vec::Drain<'_, _> = v.drain(..); /// ``` #[stable(feature = "drain", since = "1.6.0")] pub struct Drain< @@ -112,9 +112,7 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> { let unyielded_ptr = this.iter.as_slice().as_ptr(); // ZSTs have no identity, so we don't need to move them around. - let needs_move = mem::size_of::<T>() != 0; - - if needs_move { + if !T::IS_ZST { let start_ptr = source_vec.as_mut_ptr().add(start); // memmove back unyielded elements @@ -197,7 +195,7 @@ impl<T, A: Allocator> Drop for Drain<'_, T, A> { } } - let iter = mem::replace(&mut self.iter, (&mut []).iter()); + let iter = mem::take(&mut self.iter); let drop_len = iter.len(); let mut vec = self.vec; diff --git a/library/alloc/src/vec/drain_filter.rs b/library/alloc/src/vec/drain_filter.rs index 8c03f1692..21b090234 100644 --- a/library/alloc/src/vec/drain_filter.rs +++ b/library/alloc/src/vec/drain_filter.rs @@ -1,5 +1,5 @@ use crate::alloc::{Allocator, Global}; -use core::mem::{self, ManuallyDrop}; +use core::mem::{ManuallyDrop, SizedTypeProperties}; use core::ptr; use core::slice; @@ -16,7 +16,7 @@ use super::Vec; /// #![feature(drain_filter)] /// /// let mut v = vec![0, 1, 2]; -/// let iter: std::vec::DrainFilter<_, _> = v.drain_filter(|x| *x % 2 == 0); +/// let iter: std::vec::DrainFilter<'_, _, _> = v.drain_filter(|x| *x % 2 == 0); /// ``` #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] #[derive(Debug)] @@ -96,9 +96,7 @@ where unsafe { // ZSTs have no identity, so we don't need to move them around. - let needs_move = mem::size_of::<T>() != 0; - - if needs_move && this.idx < this.old_len && this.del > 0 { + if !T::IS_ZST && this.idx < this.old_len && this.del > 0 { let ptr = this.vec.as_mut_ptr(); let src = ptr.add(this.idx); let dst = src.sub(this.del); diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs index 87d61deb1..5ecd04799 100644 --- a/library/alloc/src/vec/in_place_collect.rs +++ b/library/alloc/src/vec/in_place_collect.rs @@ -178,7 +178,8 @@ where ) }; - let len = SpecInPlaceCollect::collect_in_place(&mut iterator, dst_buf, dst_end); + // SAFETY: `dst_buf` and `dst_end` are the start and end of the buffer. + let len = unsafe { SpecInPlaceCollect::collect_in_place(&mut iterator, dst_buf, dst_end) }; let src = unsafe { iterator.as_inner().as_into_iter() }; // check if SourceIter contract was upheld @@ -201,7 +202,7 @@ where // // Note: This access to the source wouldn't be allowed by the TrustedRandomIteratorNoCoerce // contract (used by SpecInPlaceCollect below). But see the "O(1) collect" section in the - // module documenttation why this is ok anyway. + // module documentation why this is ok anyway. let dst_guard = InPlaceDstBufDrop { ptr: dst_buf, len, cap }; src.forget_allocation_drop_remaining(); mem::forget(dst_guard); @@ -239,7 +240,7 @@ trait SpecInPlaceCollect<T, I>: Iterator<Item = T> { /// `Iterator::__iterator_get_unchecked` calls with a `TrustedRandomAccessNoCoerce` bound /// on `I` which means the caller of this method must take the safety conditions /// of that trait into consideration. - fn collect_in_place(&mut self, dst: *mut T, end: *const T) -> usize; + unsafe fn collect_in_place(&mut self, dst: *mut T, end: *const T) -> usize; } impl<T, I> SpecInPlaceCollect<T, I> for I @@ -247,7 +248,7 @@ where I: Iterator<Item = T>, { #[inline] - default fn collect_in_place(&mut self, dst_buf: *mut T, end: *const T) -> usize { + default unsafe fn collect_in_place(&mut self, dst_buf: *mut T, end: *const T) -> usize { // use try-fold since // - it vectorizes better for some iterator adapters // - unlike most internal iteration methods, it only takes a &mut self @@ -265,7 +266,7 @@ where I: Iterator<Item = T> + TrustedRandomAccessNoCoerce, { #[inline] - fn collect_in_place(&mut self, dst_buf: *mut T, end: *const T) -> usize { + unsafe fn collect_in_place(&mut self, dst_buf: *mut T, end: *const T) -> usize { let len = self.size(); let mut drop_guard = InPlaceDrop { inner: dst_buf, dst: dst_buf }; for i in 0..len { diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 3736a6e0b..47661a3d3 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -646,14 +646,14 @@ impl<T, A: Allocator> Vec<T, A> { /// /// // The vector contains no items, even though it has capacity for more /// assert_eq!(vec.len(), 0); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// /// // These are all done without reallocating... /// for i in 0..10 { /// vec.push(i); /// } /// assert_eq!(vec.len(), 10); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// /// // ...but this may make the vector reallocate /// vec.push(11); @@ -877,7 +877,7 @@ impl<T, A: Allocator> Vec<T, A> { /// ``` /// let mut vec: Vec<i32> = Vec::with_capacity(10); /// vec.push(42); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -1028,7 +1028,7 @@ impl<T, A: Allocator> Vec<T, A> { /// ``` /// let mut vec = Vec::with_capacity(10); /// vec.extend([1, 2, 3]); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// vec.shrink_to_fit(); /// assert!(vec.capacity() >= 3); /// ``` @@ -1055,7 +1055,7 @@ impl<T, A: Allocator> Vec<T, A> { /// ``` /// let mut vec = Vec::with_capacity(10); /// vec.extend([1, 2, 3]); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// vec.shrink_to(4); /// assert!(vec.capacity() >= 4); /// vec.shrink_to(0); @@ -1090,7 +1090,7 @@ impl<T, A: Allocator> Vec<T, A> { /// let mut vec = Vec::with_capacity(10); /// vec.extend([1, 2, 3]); /// - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// let slice = vec.into_boxed_slice(); /// assert_eq!(slice.into_vec().capacity(), 3); /// ``` @@ -2662,7 +2662,6 @@ impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> { /// as required by the `core::borrow::Borrow` implementation. /// /// ``` -/// #![feature(build_hasher_simple_hash_one)] /// use std::hash::BuildHasher; /// /// let b = std::collections::hash_map::RandomState::new(); @@ -3022,8 +3021,7 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec<T, A> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] -impl<T> const Default for Vec<T> { +impl<T> Default for Vec<T> { /// Creates an empty `Vec<T>`. /// /// The vector will not allocate until elements are pushed onto it. @@ -3143,8 +3141,8 @@ where /// /// ``` /// # use std::borrow::Cow; - /// let o: Cow<[i32]> = Cow::Owned(vec![1, 2, 3]); - /// let b: Cow<[i32]> = Cow::Borrowed(&[1, 2, 3]); + /// let o: Cow<'_, [i32]> = Cow::Owned(vec![1, 2, 3]); + /// let b: Cow<'_, [i32]> = Cow::Borrowed(&[1, 2, 3]); /// assert_eq!(Vec::from(o), Vec::from(b)); /// ``` fn from(s: Cow<'a, [T]>) -> Vec<T> { diff --git a/library/alloc/src/vec/splice.rs b/library/alloc/src/vec/splice.rs index 1861147fe..852fdcc3f 100644 --- a/library/alloc/src/vec/splice.rs +++ b/library/alloc/src/vec/splice.rs @@ -14,7 +14,7 @@ use super::{Drain, Vec}; /// ``` /// let mut v = vec![0, 1, 2]; /// let new = [7, 8]; -/// let iter: std::vec::Splice<_> = v.splice(1.., new); +/// let iter: std::vec::Splice<'_, _> = v.splice(1.., new); /// ``` #[derive(Debug)] #[stable(feature = "vec_splice", since = "1.21.0")] |