diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 1512235da6a81..55791008e50f2 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1336,9 +1336,10 @@ impl FromIterator for Box<[I]> { } #[stable(feature = "box_slice_clone", since = "1.3.0")] -impl Clone for Box<[T]> { +impl Clone for Box<[T], A> { fn clone(&self) -> Self { - self.to_vec().into_boxed_slice() + let alloc = Box::alloc_ref(self).clone(); + self.to_vec_in(alloc).into_boxed_slice() } fn clone_from(&mut self, other: &Self) { diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 522c5bcf5af10..d079d331fa1a9 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -233,15 +233,10 @@ impl RawVec { } /// Returns a shared reference to the allocator backing this `RawVec`. - pub fn alloc(&self) -> &A { + pub fn alloc_ref(&self) -> &A { &self.alloc } - /// Returns a mutable reference to the allocator backing this `RawVec`. - pub fn alloc_mut(&mut self) -> &mut A { - &mut self.alloc - } - fn current_memory(&self) -> Option<(NonNull, Layout)> { if mem::size_of::() == 0 || self.cap == 0 { None diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 3db66964941c3..41ebb1cf654bc 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -87,6 +87,7 @@ use core::cmp::Ordering::{self, Less}; use core::mem::{self, size_of}; use core::ptr; +use crate::alloc::{AllocRef, Global}; use crate::borrow::ToOwned; use crate::boxed::Box; use crate::vec::Vec; @@ -137,26 +138,28 @@ pub use hack::to_vec; // `core::slice::SliceExt` - we need to supply these functions for the // `test_permutations` test mod hack { + use core::alloc::AllocRef; + use crate::boxed::Box; use crate::vec::Vec; // We shouldn't add inline attribute to this since this is used in // `vec!` macro mostly and causes perf regression. See #71204 for // discussion and perf results. - pub fn into_vec(b: Box<[T]>) -> Vec { + pub fn into_vec(b: Box<[T], A>) -> Vec { unsafe { let len = b.len(); - let b = Box::into_raw(b); - Vec::from_raw_parts(b as *mut T, len, len) + let (b, alloc) = Box::into_raw_with_alloc(b); + Vec::from_raw_parts_in(b as *mut T, len, len, alloc) } } #[inline] - pub fn to_vec(s: &[T]) -> Vec + pub fn to_vec(s: &[T], alloc: A) -> Vec where T: Clone, { - let mut vec = Vec::with_capacity(s.len()); + let mut vec = Vec::with_capacity_in(s.len(), alloc); vec.extend_from_slice(s); vec } @@ -388,11 +391,33 @@ impl [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn to_vec(&self) -> Vec + where + T: Clone, + { + self.to_vec_in(Global) + } + + /// Copies `self` into a new `Vec` with an allocator. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_api)] + /// + /// use std::alloc::System; + /// + /// let s = [10, 40, 30]; + /// let x = s.to_vec_in(System); + /// // Here, `s` and `x` can be modified independently. + /// ``` + #[inline] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn to_vec_in(&self, alloc: A) -> Vec where T: Clone, { // N.B., see the `hack` module in this file for more details. - hack::to_vec(self) + hack::to_vec(self, alloc) } /// Converts `self` into a vector without clones or allocation. @@ -411,7 +436,7 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] - pub fn into_vec(self: Box) -> Vec { + pub fn into_vec(self: Box) -> Vec { // N.B., see the `hack` module in this file for more details. hack::into_vec(self) } @@ -730,7 +755,7 @@ impl ToOwned for [T] { #[cfg(test)] fn to_owned(&self) -> Vec { - hack::to_vec(self) + hack::to_vec(self, Global) } fn clone_into(&self, target: &mut Vec) { diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs index 2c8bc3d53ef76..392c16546efb0 100644 --- a/library/alloc/src/vec.rs +++ b/library/alloc/src/vec.rs @@ -68,6 +68,7 @@ use core::ops::{self, Index, IndexMut, Range, RangeBounds}; use core::ptr::{self, NonNull}; use core::slice::{self, SliceIndex}; +use crate::alloc::{AllocRef, Global}; use crate::borrow::{Cow, ToOwned}; use crate::boxed::Box; use crate::collections::TryReserveError; @@ -297,8 +298,8 @@ use crate::raw_vec::RawVec; /// [`&`]: ../../std/primitive.reference.html #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "vec_type")] -pub struct Vec { - buf: RawVec, +pub struct Vec { + buf: RawVec, len: usize, } @@ -320,7 +321,7 @@ impl Vec { #[inline] #[rustc_const_stable(feature = "const_vec_new", since = "1.39.0")] #[stable(feature = "rust1", since = "1.0.0")] - pub const fn new() -> Vec { + pub const fn new() -> Self { Vec { buf: RawVec::NEW, len: 0 } } @@ -359,49 +360,145 @@ impl Vec { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn with_capacity(capacity: usize) -> Vec { - Vec { buf: RawVec::with_capacity(capacity), len: 0 } + pub fn with_capacity(capacity: usize) -> Self { + Self::with_capacity_in(capacity, Global) } - /// Decomposes a `Vec` into its raw components. + /// Creates a `Vec` directly from the raw components of another vector. /// - /// Returns the raw pointer to the underlying data, the length of - /// the vector (in elements), and the allocated capacity of the - /// data (in elements). These are the same arguments in the same - /// order as the arguments to [`from_raw_parts`]. + /// # Safety /// - /// After calling this function, the caller is responsible for the - /// memory previously managed by the `Vec`. The only way to do - /// this is to convert the raw pointer, length, and capacity back - /// into a `Vec` with the [`from_raw_parts`] function, allowing - /// the destructor to perform the cleanup. + /// This is highly unsafe, due to the number of invariants that aren't + /// checked: /// - /// [`from_raw_parts`]: Vec::from_raw_parts + /// * `ptr` needs to have been previously allocated via [`String`]/`Vec` + /// (at least, it's highly likely to be incorrect if it wasn't). + /// * `T` needs to have the same size and alignment as what `ptr` was allocated with. + /// (`T` having a less strict alignment is not sufficient, the alignment really + /// needs to be equal to satisfy the [`dealloc`] requirement that memory must be + /// allocated and deallocated with the same layout.) + /// * `length` needs to be less than or equal to `capacity`. + /// * `capacity` needs to be the capacity that the pointer was allocated with. + /// + /// Violating these may cause problems like corrupting the allocator's + /// internal data structures. For example it is **not** safe + /// to build a `Vec` from a pointer to a C `char` array with length `size_t`. + /// It's also not safe to build one from a `Vec` and its length, because + /// the allocator cares about the alignment, and these two types have different + /// alignments. The buffer was allocated with alignment 2 (for `u16`), but after + /// turning it into a `Vec` it'll be deallocated with alignment 1. + /// + /// The ownership of `ptr` is effectively transferred to the + /// `Vec` which may then deallocate, reallocate or change the + /// contents of memory pointed to by the pointer at will. Ensure + /// that nothing else uses the pointer after calling this + /// function. + /// + /// [`String`]: crate::string::String + /// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc /// /// # Examples /// /// ``` - /// #![feature(vec_into_raw_parts)] - /// let v: Vec = vec![-1, 0, 1]; + /// use std::ptr; + /// use std::mem; /// - /// let (ptr, len, cap) = v.into_raw_parts(); + /// let v = vec![1, 2, 3]; /// - /// let rebuilt = unsafe { - /// // We can now make changes to the components, such as - /// // transmuting the raw pointer to a compatible type. - /// let ptr = ptr as *mut u32; + // FIXME Update this when vec_into_raw_parts is stabilized + /// // Prevent running `v`'s destructor so we are in complete control + /// // of the allocation. + /// let mut v = mem::ManuallyDrop::new(v); /// - /// Vec::from_raw_parts(ptr, len, cap) - /// }; - /// assert_eq!(rebuilt, [4294967295, 0, 1]); + /// // Pull out the various important pieces of information about `v` + /// let p = v.as_mut_ptr(); + /// let len = v.len(); + /// let cap = v.capacity(); + /// + /// unsafe { + /// // Overwrite memory with 4, 5, 6 + /// for i in 0..len as isize { + /// ptr::write(p.offset(i), 4 + i); + /// } + /// + /// // Put everything back together into a Vec + /// let rebuilt = Vec::from_raw_parts(p, len, cap); + /// assert_eq!(rebuilt, [4, 5, 6]); + /// } /// ``` - #[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")] - pub fn into_raw_parts(self) -> (*mut T, usize, usize) { - let mut me = ManuallyDrop::new(self); - (me.as_mut_ptr(), me.len(), me.capacity()) + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self { + unsafe { Self::from_raw_parts_in(ptr, length, capacity, Global) } } +} - /// Creates a `Vec` directly from the raw components of another vector. +impl Vec { + /// Constructs a new, empty `Vec`. + /// + /// The vector will not allocate until elements are pushed onto it. + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_api)] + /// + /// use std::alloc::System; + /// + /// # #[allow(unused_mut)] + /// let mut vec: Vec = Vec::new_in(System); + /// ``` + #[inline] + #[unstable(feature = "allocator_api", issue = "32838")] + pub const fn new_in(alloc: A) -> Self { + Vec { buf: RawVec::new_in(alloc), len: 0 } + } + + /// Constructs a new, empty `Vec` with the specified capacity with the provided + /// allocator. + /// + /// The vector will be able to hold exactly `capacity` elements without + /// reallocating. If `capacity` is 0, the vector will not allocate. + /// + /// It is important to note that although the returned vector has the + /// *capacity* specified, the vector will have a zero *length*. For an + /// explanation of the difference between length and capacity, see + /// *[Capacity and reallocation]*. + /// + /// [Capacity and reallocation]: #capacity-and-reallocation + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_api)] + /// + /// use std::alloc::System; + /// + /// let mut vec = Vec::with_capacity_in(10, System); + /// + /// // The vector contains no items, even though it has capacity for more + /// assert_eq!(vec.len(), 0); + /// assert_eq!(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); + /// + /// // ...but this may make the vector reallocate + /// vec.push(11); + /// assert_eq!(vec.len(), 11); + /// assert!(vec.capacity() >= 11); + /// ``` + #[inline] + #[unstable(feature = "allocator_api", issue = "32838")] + pub fn with_capacity_in(capacity: usize, alloc: A) -> Self { + Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 } + } + + /// Creates a `Vec` directly from the raw components of another vector. /// /// # Safety /// @@ -437,10 +534,17 @@ impl Vec { /// # Examples /// /// ``` + /// #![feature(allocator_api)] + /// + /// use std::alloc::System; + /// /// use std::ptr; /// use std::mem; /// - /// let v = vec![1, 2, 3]; + /// let mut v = Vec::with_capacity_in(3, System); + /// v.push(1); + /// v.push(2); + /// v.push(3); /// // FIXME Update this when vec_into_raw_parts is stabilized /// // Prevent running `v`'s destructor so we are in complete control @@ -451,6 +555,7 @@ impl Vec { /// let p = v.as_mut_ptr(); /// let len = v.len(); /// let cap = v.capacity(); + /// let alloc = v.alloc_ref(); /// /// unsafe { /// // Overwrite memory with 4, 5, 6 @@ -459,13 +564,100 @@ impl Vec { /// } /// /// // Put everything back together into a Vec - /// let rebuilt = Vec::from_raw_parts(p, len, cap); + /// let rebuilt = Vec::from_raw_parts_in(p, len, cap, alloc.clone()); /// assert_eq!(rebuilt, [4, 5, 6]); /// } /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Vec { - unsafe { Vec { buf: RawVec::from_raw_parts(ptr, capacity), len: length } } + #[inline] + #[unstable(feature = "allocator_api", issue = "32838")] + pub unsafe fn from_raw_parts_in(ptr: *mut T, length: usize, capacity: usize, alloc: A) -> Self { + unsafe { Vec { buf: RawVec::from_raw_parts_in(ptr, capacity, alloc), len: length } } + } + + /// Decomposes a `Vec` into its raw components. + /// + /// Returns the raw pointer to the underlying data, the length of + /// the vector (in elements), and the allocated capacity of the + /// data (in elements). These are the same arguments in the same + /// order as the arguments to [`from_raw_parts`]. + /// + /// After calling this function, the caller is responsible for the + /// memory previously managed by the `Vec`. The only way to do + /// this is to convert the raw pointer, length, and capacity back + /// into a `Vec` with the [`from_raw_parts`] function, allowing + /// the destructor to perform the cleanup. + /// + /// [`from_raw_parts`]: Vec::from_raw_parts + /// + /// # Examples + /// + /// ``` + /// #![feature(vec_into_raw_parts)] + /// let v: Vec = vec![-1, 0, 1]; + /// + /// let (ptr, len, cap) = v.into_raw_parts(); + /// + /// let rebuilt = unsafe { + /// // We can now make changes to the components, such as + /// // transmuting the raw pointer to a compatible type. + /// let ptr = ptr as *mut u32; + /// + /// Vec::from_raw_parts(ptr, len, cap) + /// }; + /// assert_eq!(rebuilt, [4294967295, 0, 1]); + /// ``` + #[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")] + pub fn into_raw_parts(self) -> (*mut T, usize, usize) { + let mut me = ManuallyDrop::new(self); + (me.as_mut_ptr(), me.len(), me.capacity()) + } + + /// Decomposes a `Vec` into its raw components. + /// + /// Returns the raw pointer to the underlying data, the length of the vector (in elements), + /// the allocated capacity of the data (in elements), and the allocator. These are the same + /// arguments in the same order as the arguments to [`from_raw_parts_in`]. + /// + /// After calling this function, the caller is responsible for the + /// memory previously managed by the `Vec`. The only way to do + /// this is to convert the raw pointer, length, and capacity back + /// into a `Vec` with the [`from_raw_parts_in`] function, allowing + /// the destructor to perform the cleanup. + /// + /// [`from_raw_parts_in`]: Vec::from_raw_parts_in + /// + /// # Examples + /// + /// ``` + /// #![feature(allocator_api, vec_into_raw_parts)] + /// + /// use std::alloc::System; + /// + /// let mut v: Vec = Vec::new_in(System); + /// v.push(-1); + /// v.push(0); + /// v.push(1); + /// + /// let (ptr, len, cap, alloc) = v.into_raw_parts_with_alloc(); + /// + /// let rebuilt = unsafe { + /// // We can now make changes to the components, such as + /// // transmuting the raw pointer to a compatible type. + /// let ptr = ptr as *mut u32; + /// + /// Vec::from_raw_parts_in(ptr, len, cap, alloc) + /// }; + /// assert_eq!(rebuilt, [4294967295, 0, 1]); + /// ``` + #[unstable(feature = "allocator_api", issue = "32838")] + // #[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")] + pub fn into_raw_parts_with_alloc(self) -> (*mut T, usize, usize, A) { + let mut me = ManuallyDrop::new(self); + let len = me.len(); + let capacity = me.capacity(); + let ptr = me.as_mut_ptr(); + let alloc = unsafe { ptr::read(me.alloc_ref()) }; + (ptr, len, capacity, alloc) } /// Returns the number of elements the vector can hold without @@ -684,7 +876,7 @@ impl Vec { /// assert_eq!(slice.into_vec().capacity(), 3); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn into_boxed_slice(mut self) -> Box<[T]> { + pub fn into_boxed_slice(mut self) -> Box<[T], A> { unsafe { self.shrink_to_fit(); let me = ManuallyDrop::new(self); @@ -863,6 +1055,13 @@ impl Vec { ptr } + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + #[inline] + pub fn alloc_ref(&self) -> &A { + self.buf.alloc_ref() + } + /// Forces the length of the vector to `new_len`. /// /// This is a low-level operation that maintains none of the normal @@ -1299,7 +1498,7 @@ impl Vec { /// assert_eq!(v, &[]); /// ``` #[stable(feature = "drain", since = "1.6.0")] - pub fn drain(&mut self, range: R) -> Drain<'_, T> + pub fn drain(&mut self, range: R) -> Drain<'_, T, A> where R: RangeBounds, { @@ -1403,7 +1602,10 @@ impl Vec { #[inline] #[must_use = "use `.truncate()` if you don't need the other half"] #[stable(feature = "split_off", since = "1.4.0")] - pub fn split_off(&mut self, at: usize) -> Self { + pub fn split_off(&mut self, at: usize) -> Self + where + A: Clone, + { #[cold] #[inline(never)] fn assert_failed(at: usize, len: usize) -> ! { @@ -1416,11 +1618,14 @@ impl Vec { if at == 0 { // the new vector can take over the original buffer and avoid the copy - return mem::replace(self, Vec::with_capacity(self.capacity())); + return mem::replace( + self, + Vec::with_capacity_in(self.capacity(), self.alloc_ref().clone()), + ); } let other_len = self.len - at; - let mut other = Vec::with_capacity(other_len); + let mut other = Vec::with_capacity_in(other_len, self.alloc_ref().clone()); // Unsafely `set_len` and copy items to `other`. unsafe { @@ -1497,7 +1702,7 @@ impl Vec { #[inline] pub fn leak<'a>(self) -> &'a mut [T] where - T: 'a, // Technically not needed, but kept to be explicit. + A: 'a, { Box::leak(self.into_boxed_slice()) } @@ -1544,7 +1749,7 @@ impl Vec { } } -impl Vec { +impl Vec { /// Resizes the `Vec` in-place so that `len` is equal to `new_len`. /// /// If `new_len` is greater than `len`, the `Vec` is extended by the @@ -1639,7 +1844,7 @@ impl T> ExtendWith for ExtendFunc { } } -impl Vec { +impl Vec { /// Extend the vector by `n` values, using the given generator. fn extend_with>(&mut self, n: usize, mut value: E) { self.reserve(n); @@ -1699,7 +1904,7 @@ impl Drop for SetLenOnDrop<'_> { } } -impl Vec { +impl Vec { /// Removes consecutive repeated elements in the vector according to the /// [`PartialEq`] trait implementation. /// @@ -1721,7 +1926,7 @@ impl Vec { } } -impl Vec { +impl Vec { /// Removes the first instance of `item` from the vector if the item exists. /// /// This method will be removed soon. @@ -1749,17 +1954,23 @@ impl Vec { #[doc(hidden)] #[stable(feature = "rust1", since = "1.0.0")] pub fn from_elem(elem: T, n: usize) -> Vec { - ::from_elem(elem, n) + ::from_elem(elem, n, Global) +} + +#[doc(hidden)] +#[unstable(feature = "allocator_api", issue = "32838")] +pub fn from_elem_in(elem: T, n: usize, alloc: A) -> Vec { + ::from_elem(elem, n, alloc) } // Specialization trait used for Vec::from_elem trait SpecFromElem: Sized { - fn from_elem(elem: Self, n: usize) -> Vec; + fn from_elem(elem: Self, n: usize, alloc: A) -> Vec; } impl SpecFromElem for T { - default fn from_elem(elem: Self, n: usize) -> Vec { - let mut v = Vec::with_capacity(n); + default fn from_elem(elem: Self, n: usize, alloc: A) -> Vec { + let mut v = Vec::with_capacity_in(n, alloc); v.extend_with(n, ExtendElement(elem)); v } @@ -1767,12 +1978,12 @@ impl SpecFromElem for T { impl SpecFromElem for i8 { #[inline] - fn from_elem(elem: i8, n: usize) -> Vec { + fn from_elem(elem: i8, n: usize, alloc: A) -> Vec { if elem == 0 { - return Vec { buf: RawVec::with_capacity_zeroed(n), len: n }; + return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n }; } unsafe { - let mut v = Vec::with_capacity(n); + let mut v = Vec::with_capacity_in(n, alloc); ptr::write_bytes(v.as_mut_ptr(), elem as u8, n); v.set_len(n); v @@ -1782,12 +1993,12 @@ impl SpecFromElem for i8 { impl SpecFromElem for u8 { #[inline] - fn from_elem(elem: u8, n: usize) -> Vec { + fn from_elem(elem: u8, n: usize, alloc: A) -> Vec { if elem == 0 { - return Vec { buf: RawVec::with_capacity_zeroed(n), len: n }; + return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n }; } unsafe { - let mut v = Vec::with_capacity(n); + let mut v = Vec::with_capacity_in(n, alloc); ptr::write_bytes(v.as_mut_ptr(), elem, n); v.set_len(n); v @@ -1797,11 +2008,11 @@ impl SpecFromElem for u8 { impl SpecFromElem for T { #[inline] - fn from_elem(elem: T, n: usize) -> Vec { + fn from_elem(elem: T, n: usize, alloc: A) -> Vec { if elem.is_zero() { - return Vec { buf: RawVec::with_capacity_zeroed(n), len: n }; + return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n }; } - let mut v = Vec::with_capacity(n); + let mut v = Vec::with_capacity_in(n, alloc); v.extend_with(n, ExtendElement(elem)); v } @@ -1882,7 +2093,7 @@ unsafe impl IsZero for Option> { //////////////////////////////////////////////////////////////////////////////// #[stable(feature = "rust1", since = "1.0.0")] -impl ops::Deref for Vec { +impl ops::Deref for Vec { type Target = [T]; fn deref(&self) -> &[T] { @@ -1891,17 +2102,18 @@ impl ops::Deref for Vec { } #[stable(feature = "rust1", since = "1.0.0")] -impl ops::DerefMut for Vec { +impl ops::DerefMut for Vec { fn deref_mut(&mut self) -> &mut [T] { unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) } } } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Vec { +impl Clone for Vec { #[cfg(not(test))] - fn clone(&self) -> Vec { - <[T]>::to_vec(&**self) + fn clone(&self) -> Self { + let alloc = self.alloc_ref().clone(); + <[T]>::to_vec_in(&**self, alloc) } // HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is @@ -1909,17 +2121,27 @@ impl Clone for Vec { // `slice::to_vec` function which is only available with cfg(test) // NB see the slice::hack module in slice.rs for more information #[cfg(test)] - fn clone(&self) -> Vec { - crate::slice::to_vec(&**self) + fn clone(&self) -> Self { + let alloc = self.alloc_ref().clone(); + crate::slice::to_vec(&**self, alloc) } - fn clone_from(&mut self, other: &Vec) { - other.as_slice().clone_into(self); + fn clone_from(&mut self, other: &Self) { + // drop anything that will not be overwritten + self.truncate(other.len()); + + // self.len <= other.len due to the truncate above, so the + // slices here are always in-bounds. + let (init, tail) = other.split_at(self.len()); + + // reuse the contained values' allocations/resources. + self.clone_from_slice(init); + self.extend_from_slice(tail); } } #[stable(feature = "rust1", since = "1.0.0")] -impl Hash for Vec { +impl Hash for Vec { #[inline] fn hash(&self, state: &mut H) { Hash::hash(&**self, state) @@ -1931,7 +2153,7 @@ impl Hash for Vec { message = "vector indices are of type `usize` or ranges of `usize`", label = "vector indices are of type `usize` or ranges of `usize`" )] -impl> Index for Vec { +impl, A: AllocRef> Index for Vec { type Output = I::Output; #[inline] @@ -1945,7 +2167,7 @@ impl> Index for Vec { message = "vector indices are of type `usize` or ranges of `usize`", label = "vector indices are of type `usize` or ranges of `usize`" )] -impl> IndexMut for Vec { +impl, A: AllocRef> IndexMut for Vec { #[inline] fn index_mut(&mut self, index: I) -> &mut Self::Output { IndexMut::index_mut(&mut **self, index) @@ -1961,9 +2183,9 @@ impl FromIterator for Vec { } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for Vec { +impl IntoIterator for Vec { type Item = T; - type IntoIter = IntoIter; + type IntoIter = IntoIter; /// Creates a consuming iterator, that is, one that moves each value out of /// the vector (from start to end). The vector cannot be used after calling @@ -1979,9 +2201,10 @@ impl IntoIterator for Vec { /// } /// ``` #[inline] - fn into_iter(self) -> IntoIter { + fn into_iter(self) -> IntoIter { unsafe { let mut me = ManuallyDrop::new(self); + let alloc = ptr::read(me.alloc_ref()); let begin = me.as_mut_ptr(); let end = if mem::size_of::() == 0 { arith_offset(begin as *const i8, me.len() as isize) as *const T @@ -1993,6 +2216,7 @@ impl IntoIterator for Vec { buf: NonNull::new_unchecked(begin), phantom: PhantomData, cap, + alloc, ptr: begin, end, } @@ -2001,7 +2225,7 @@ impl IntoIterator for Vec { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a Vec { +impl<'a, T, A: AllocRef> IntoIterator for &'a Vec { type Item = &'a T; type IntoIter = slice::Iter<'a, T>; @@ -2011,7 +2235,7 @@ impl<'a, T> IntoIterator for &'a Vec { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T> IntoIterator for &'a mut Vec { +impl<'a, T, A: AllocRef> IntoIterator for &'a mut Vec { type Item = &'a mut T; type IntoIter = slice::IterMut<'a, T>; @@ -2021,7 +2245,7 @@ impl<'a, T> IntoIterator for &'a mut Vec { } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for Vec { +impl Extend for Vec { #[inline] fn extend>(&mut self, iter: I) { >::spec_extend(self, iter.into_iter()) @@ -2303,7 +2527,7 @@ trait SpecExtend { fn spec_extend(&mut self, iter: I); } -impl SpecExtend for Vec +impl SpecExtend for Vec where I: Iterator, { @@ -2312,7 +2536,7 @@ where } } -impl SpecExtend for Vec +impl SpecExtend for Vec where I: TrustedLen, { @@ -2345,7 +2569,7 @@ where } } -impl SpecExtend> for Vec { +impl SpecExtend> for Vec { fn spec_extend(&mut self, mut iterator: IntoIter) { unsafe { self.append_elements(iterator.as_slice() as _); @@ -2354,7 +2578,7 @@ impl SpecExtend> for Vec { } } -impl<'a, T: 'a, I> SpecExtend<&'a T, I> for Vec +impl<'a, T: 'a, I, A: AllocRef + 'a> SpecExtend<&'a T, I> for Vec where I: Iterator, T: Clone, @@ -2364,7 +2588,7 @@ where } } -impl<'a, T: 'a> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec +impl<'a, T: 'a, A: AllocRef + 'a> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec where T: Copy, { @@ -2374,7 +2598,7 @@ where } } -impl Vec { +impl Vec { // leaf method to which various SpecFrom/SpecExtend implementations delegate when // they have no further optimizations to apply fn extend_desugared>(&mut self, mut iterator: I) { @@ -2434,7 +2658,7 @@ impl Vec { /// ``` #[inline] #[stable(feature = "vec_splice", since = "1.21.0")] - pub fn splice(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter> + pub fn splice(&mut self, range: R, replace_with: I) -> Splice<'_, I::IntoIter, A> where R: RangeBounds, I: IntoIterator, @@ -2487,7 +2711,7 @@ impl Vec { /// assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]); /// ``` #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] - pub fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F> + pub fn drain_filter(&mut self, filter: F) -> DrainFilter<'_, T, F, A> where F: FnMut(&mut T) -> bool, { @@ -2509,7 +2733,7 @@ impl Vec { /// /// [`copy_from_slice`]: ../../std/primitive.slice.html#method.copy_from_slice #[stable(feature = "extend_ref", since = "1.2.0")] -impl<'a, T: 'a + Copy> Extend<&'a T> for Vec { +impl<'a, T: Copy + 'a, A: AllocRef + 'a> Extend<&'a T> for Vec { fn extend>(&mut self, iter: I) { self.spec_extend(iter.into_iter()) } @@ -2528,9 +2752,9 @@ impl<'a, T: 'a + Copy> Extend<&'a T> for Vec { macro_rules! __impl_slice_eq1 { ([$($vars:tt)*] $lhs:ty, $rhs:ty $(where $ty:ty: $bound:ident)?, #[$stability:meta]) => { #[$stability] - impl PartialEq<$rhs> for $lhs + impl PartialEq<$rhs> for $lhs where - A: PartialEq, + T: PartialEq, $($ty: $bound)? { #[inline] @@ -2541,18 +2765,18 @@ macro_rules! __impl_slice_eq1 { } } -__impl_slice_eq1! { [] Vec, Vec, #[stable(feature = "rust1", since = "1.0.0")] } -__impl_slice_eq1! { [] Vec, &[B], #[stable(feature = "rust1", since = "1.0.0")] } -__impl_slice_eq1! { [] Vec, &mut [B], #[stable(feature = "rust1", since = "1.0.0")] } -__impl_slice_eq1! { [] &[A], Vec, #[stable(feature = "partialeq_vec_for_ref_slice", since = "1.46.0")] } -__impl_slice_eq1! { [] &mut [A], Vec, #[stable(feature = "partialeq_vec_for_ref_slice", since = "1.46.0")] } -__impl_slice_eq1! { [] Vec, [B], #[stable(feature = "partialeq_vec_for_slice", since = "1.48.0")] } -__impl_slice_eq1! { [] [A], Vec, #[stable(feature = "partialeq_vec_for_slice", since = "1.48.0")] } -__impl_slice_eq1! { [] Cow<'_, [A]>, Vec where A: Clone, #[stable(feature = "rust1", since = "1.0.0")] } -__impl_slice_eq1! { [] Cow<'_, [A]>, &[B] where A: Clone, #[stable(feature = "rust1", since = "1.0.0")] } -__impl_slice_eq1! { [] Cow<'_, [A]>, &mut [B] where A: Clone, #[stable(feature = "rust1", since = "1.0.0")] } -__impl_slice_eq1! { [const N: usize] Vec, [B; N], #[stable(feature = "rust1", since = "1.0.0")] } -__impl_slice_eq1! { [const N: usize] Vec, &[B; N], #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [A: AllocRef] Vec, Vec, #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [A: AllocRef] Vec, &[U], #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [A: AllocRef] Vec, &mut [U], #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [A: AllocRef] &[T], Vec, #[stable(feature = "partialeq_vec_for_ref_slice", since = "1.46.0")] } +__impl_slice_eq1! { [A: AllocRef] &mut [T], Vec, #[stable(feature = "partialeq_vec_for_ref_slice", since = "1.46.0")] } +__impl_slice_eq1! { [A: AllocRef] Vec, [U], #[stable(feature = "partialeq_vec_for_slice", since = "1.48.0")] } +__impl_slice_eq1! { [A: AllocRef] [T], Vec, #[stable(feature = "partialeq_vec_for_slice", since = "1.48.0")] } +__impl_slice_eq1! { [A: AllocRef] Cow<'_, [T]>, Vec where T: Clone, #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [] Cow<'_, [T]>, &[U] where T: Clone, #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [] Cow<'_, [T]>, &mut [U] where T: Clone, #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [A: AllocRef, const N: usize] Vec, [U; N], #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [A: AllocRef, const N: usize] Vec, &[U; N], #[stable(feature = "rust1", since = "1.0.0")] } // NOTE: some less important impls are omitted to reduce code bloat // FIXME(Centril): Reconsider this? @@ -2566,27 +2790,27 @@ __impl_slice_eq1! { [const N: usize] Vec, &[B; N], #[stable(feature = "rust1" /// Implements comparison of vectors, [lexicographically](core::cmp::Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for Vec { +impl PartialOrd for Vec { #[inline] - fn partial_cmp(&self, other: &Vec) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { PartialOrd::partial_cmp(&**self, &**other) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for Vec {} +impl Eq for Vec {} /// Implements ordering of vectors, [lexicographically](core::cmp::Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for Vec { +impl Ord for Vec { #[inline] - fn cmp(&self, other: &Vec) -> Ordering { + fn cmp(&self, other: &Self) -> Ordering { Ord::cmp(&**self, &**other) } } #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<#[may_dangle] T> Drop for Vec { +unsafe impl<#[may_dangle] T, A: AllocRef> Drop for Vec { fn drop(&mut self) { unsafe { // use drop for [T] @@ -2607,35 +2831,35 @@ impl Default for Vec { } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for Vec { +impl fmt::Debug for Vec { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] -impl AsRef> for Vec { - fn as_ref(&self) -> &Vec { +impl AsRef> for Vec { + fn as_ref(&self) -> &Vec { self } } #[stable(feature = "vec_as_mut", since = "1.5.0")] -impl AsMut> for Vec { - fn as_mut(&mut self) -> &mut Vec { +impl AsMut> for Vec { + fn as_mut(&mut self) -> &mut Vec { self } } #[stable(feature = "rust1", since = "1.0.0")] -impl AsRef<[T]> for Vec { +impl AsRef<[T]> for Vec { fn as_ref(&self) -> &[T] { self } } #[stable(feature = "vec_as_mut", since = "1.5.0")] -impl AsMut<[T]> for Vec { +impl AsMut<[T]> for Vec { fn as_mut(&mut self) -> &mut [T] { self } @@ -2649,7 +2873,7 @@ impl From<&[T]> for Vec { } #[cfg(test)] fn from(s: &[T]) -> Vec { - crate::slice::to_vec(s) + crate::slice::to_vec(s, Global) } } @@ -2661,7 +2885,7 @@ impl From<&mut [T]> for Vec { } #[cfg(test)] fn from(s: &mut [T]) -> Vec { - crate::slice::to_vec(s) + crate::slice::to_vec(s, Global) } } @@ -2690,17 +2914,18 @@ where // note: test pulls in libstd, which causes errors here #[cfg(not(test))] #[stable(feature = "vec_from_box", since = "1.18.0")] -impl From> for Vec { - fn from(s: Box<[T]>) -> Vec { - s.into_vec() +impl From> for Vec { + fn from(s: Box<[T], A>) -> Self { + let len = s.len(); + Self { buf: RawVec::from_box(s), len } } } // note: test pulls in libstd, which causes errors here #[cfg(not(test))] #[stable(feature = "box_from_vec", since = "1.20.0")] -impl From> for Box<[T]> { - fn from(v: Vec) -> Box<[T]> { +impl From> for Box<[T], A> { + fn from(v: Vec) -> Self { v.into_boxed_slice() } } @@ -2713,8 +2938,8 @@ impl From<&str> for Vec { } #[stable(feature = "array_try_from_vec", since = "1.48.0")] -impl TryFrom> for [T; N] { - type Error = Vec; +impl TryFrom> for [T; N] { + type Error = Vec; /// Gets the entire contents of the `Vec` as an array, /// if its size exactly matches that of the requested array. @@ -2745,7 +2970,7 @@ impl TryFrom> for [T; N] { /// assert_eq!(a, b' '); /// assert_eq!(b, b'd'); /// ``` - fn try_from(mut vec: Vec) -> Result<[T; N], Vec> { + fn try_from(mut vec: Vec) -> Result<[T; N], Vec> { if vec.len() != N { return Err(vec); } @@ -2814,22 +3039,24 @@ where /// let iter: std::vec::IntoIter<_> = v.into_iter(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub struct IntoIter { +pub struct IntoIter +{ buf: NonNull, phantom: PhantomData, cap: usize, + alloc: A, ptr: *const T, end: *const T, } #[stable(feature = "vec_intoiter_debug", since = "1.13.0")] -impl fmt::Debug for IntoIter { +impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("IntoIter").field(&self.as_slice()).finish() } } -impl IntoIter { +impl IntoIter { /// Returns the remaining items of this iterator as a slice. /// /// # Examples @@ -2864,6 +3091,13 @@ impl IntoIter { unsafe { &mut *self.as_raw_mut_slice() } } + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + #[inline] + pub fn alloc_ref(&self) -> &A { + &self.alloc + } + fn as_raw_mut_slice(&mut self) -> *mut [T] { ptr::slice_from_raw_parts_mut(self.ptr as *mut T, self.len()) } @@ -2886,19 +3120,19 @@ impl IntoIter { } #[stable(feature = "vec_intoiter_as_ref", since = "1.46.0")] -impl AsRef<[T]> for IntoIter { +impl AsRef<[T]> for IntoIter { fn as_ref(&self) -> &[T] { self.as_slice() } } #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl Send for IntoIter {} +unsafe impl Send for IntoIter {} #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl Sync for IntoIter {} +unsafe impl Sync for IntoIter {} #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for IntoIter { +impl Iterator for IntoIter { type Item = T; #[inline] @@ -2955,7 +3189,7 @@ impl Iterator for IntoIter { } #[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for IntoIter { +impl DoubleEndedIterator for IntoIter { #[inline] fn next_back(&mut self) -> Option { if self.end == self.ptr { @@ -2975,23 +3209,23 @@ impl DoubleEndedIterator for IntoIter { } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for IntoIter { +impl ExactSizeIterator for IntoIter { fn is_empty(&self) -> bool { self.ptr == self.end } } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for IntoIter {} +impl FusedIterator for IntoIter {} #[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for IntoIter {} +unsafe impl TrustedLen for IntoIter {} #[doc(hidden)] #[unstable(issue = "none", feature = "std_internals")] // T: Copy as approximation for !Drop since get_unchecked does not advance self.ptr // and thus we can't implement drop-handling -unsafe impl TrustedRandomAccess for IntoIter +unsafe impl TrustedRandomAccess for IntoIter where T: Copy, { @@ -3001,21 +3235,30 @@ where } #[stable(feature = "vec_into_iter_clone", since = "1.8.0")] -impl Clone for IntoIter { - fn clone(&self) -> IntoIter { - self.as_slice().to_owned().into_iter() +impl Clone for IntoIter { + #[cfg(not(test))] + fn clone(&self) -> Self { + self.as_slice().to_vec_in(self.alloc.clone()).into_iter() + } + #[cfg(test)] + fn clone(&self) -> Self { + crate::slice::to_vec(self.as_slice(), self.alloc.clone()).into_iter() } } #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<#[may_dangle] T> Drop for IntoIter { +unsafe impl<#[may_dangle] T, A: AllocRef> Drop for IntoIter { fn drop(&mut self) { - struct DropGuard<'a, T>(&'a mut IntoIter); + struct DropGuard<'a, T, A: AllocRef>(&'a mut IntoIter); - impl Drop for DropGuard<'_, T> { + impl Drop for DropGuard<'_, T, A> { fn drop(&mut self) { - // RawVec handles deallocation - let _ = unsafe { RawVec::from_raw_parts(self.0.buf.as_ptr(), self.0.cap) }; + unsafe { + // `IntoIter::alloc` is not used anymore after this + let alloc = ptr::read(&self.0.alloc); + // RawVec handles deallocation + let _ = RawVec::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc); + } } } @@ -3029,11 +3272,11 @@ unsafe impl<#[may_dangle] T> Drop for IntoIter { } #[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl InPlaceIterable for IntoIter {} +unsafe impl InPlaceIterable for IntoIter {} #[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl SourceIter for IntoIter { - type Source = IntoIter; +unsafe impl SourceIter for IntoIter { + type Source = Self; #[inline] unsafe fn as_inner(&mut self) -> &mut Self::Source { @@ -3068,24 +3311,28 @@ impl AsIntoIter for IntoIter { /// let iter: std::vec::Drain<_> = v.drain(..); /// ``` #[stable(feature = "drain", since = "1.6.0")] -pub struct Drain<'a, T: 'a> { +pub struct Drain< + 'a, + T: 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: AllocRef + 'a = Global, +> { /// Index of tail to preserve tail_start: usize, /// Length of tail tail_len: usize, /// Current remaining range to remove iter: slice::Iter<'a, T>, - vec: NonNull>, + vec: NonNull>, } #[stable(feature = "collection_debug", since = "1.17.0")] -impl fmt::Debug for Drain<'_, T> { +impl fmt::Debug for Drain<'_, T, A> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Drain").field(&self.iter.as_slice()).finish() } } -impl<'a, T> Drain<'a, T> { +impl<'a, T, A: AllocRef> Drain<'a, T, A> { /// Returns the remaining items of this iterator as a slice. /// /// # Examples @@ -3101,22 +3348,29 @@ impl<'a, T> Drain<'a, T> { pub fn as_slice(&self) -> &[T] { self.iter.as_slice() } + + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + #[inline] + pub fn alloc_ref(&self) -> &A { + unsafe { self.vec.as_ref().alloc_ref() } + } } #[stable(feature = "vec_drain_as_slice", since = "1.46.0")] -impl<'a, T> AsRef<[T]> for Drain<'a, T> { +impl<'a, T, A: AllocRef> AsRef<[T]> for Drain<'a, T, A> { fn as_ref(&self) -> &[T] { self.as_slice() } } #[stable(feature = "drain", since = "1.6.0")] -unsafe impl Sync for Drain<'_, T> {} +unsafe impl Sync for Drain<'_, T, A> {} #[stable(feature = "drain", since = "1.6.0")] -unsafe impl Send for Drain<'_, T> {} +unsafe impl Send for Drain<'_, T, A> {} #[stable(feature = "drain", since = "1.6.0")] -impl Iterator for Drain<'_, T> { +impl Iterator for Drain<'_, T, A> { type Item = T; #[inline] @@ -3130,7 +3384,7 @@ impl Iterator for Drain<'_, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl DoubleEndedIterator for Drain<'_, T> { +impl DoubleEndedIterator for Drain<'_, T, A> { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back().map(|elt| unsafe { ptr::read(elt as *const _) }) @@ -3138,13 +3392,13 @@ impl DoubleEndedIterator for Drain<'_, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl Drop for Drain<'_, T> { +impl Drop for Drain<'_, T, A> { fn drop(&mut self) { /// Continues dropping the remaining elements in the `Drain`, then moves back the /// un-`Drain`ed elements to restore the original `Vec`. - struct DropGuard<'r, 'a, T>(&'r mut Drain<'a, T>); + struct DropGuard<'r, 'a, T, A: AllocRef>(&'r mut Drain<'a, T, A>); - impl<'r, 'a, T> Drop for DropGuard<'r, 'a, T> { + impl<'r, 'a, T, A: AllocRef> Drop for DropGuard<'r, 'a, T, A> { fn drop(&mut self) { // Continue the same loop we have below. If the loop already finished, this does // nothing. @@ -3180,17 +3434,17 @@ impl Drop for Drain<'_, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl ExactSizeIterator for Drain<'_, T> { +impl ExactSizeIterator for Drain<'_, T, A> { fn is_empty(&self) -> bool { self.iter.is_empty() } } #[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for Drain<'_, T> {} +unsafe impl TrustedLen for Drain<'_, T, A> {} #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Drain<'_, T> {} +impl FusedIterator for Drain<'_, T, A> {} /// A splicing iterator for `Vec`. /// @@ -3206,13 +3460,17 @@ impl FusedIterator for Drain<'_, T> {} /// ``` #[derive(Debug)] #[stable(feature = "vec_splice", since = "1.21.0")] -pub struct Splice<'a, I: Iterator + 'a> { - drain: Drain<'a, I::Item>, +pub struct Splice< + 'a, + I: Iterator + 'a, + #[unstable(feature = "allocator_api", issue = "32838")] A: AllocRef + 'a = Global, +> { + drain: Drain<'a, I::Item, A>, replace_with: I, } #[stable(feature = "vec_splice", since = "1.21.0")] -impl Iterator for Splice<'_, I> { +impl Iterator for Splice<'_, I, A> { type Item = I::Item; fn next(&mut self) -> Option { @@ -3225,17 +3483,17 @@ impl Iterator for Splice<'_, I> { } #[stable(feature = "vec_splice", since = "1.21.0")] -impl DoubleEndedIterator for Splice<'_, I> { +impl DoubleEndedIterator for Splice<'_, I, A> { fn next_back(&mut self) -> Option { self.drain.next_back() } } #[stable(feature = "vec_splice", since = "1.21.0")] -impl ExactSizeIterator for Splice<'_, I> {} +impl ExactSizeIterator for Splice<'_, I, A> {} #[stable(feature = "vec_splice", since = "1.21.0")] -impl Drop for Splice<'_, I> { +impl Drop for Splice<'_, I, A> { fn drop(&mut self) { self.drain.by_ref().for_each(drop); @@ -3276,7 +3534,7 @@ impl Drop for Splice<'_, I> { } /// Private helper methods for `Splice::drop` -impl Drain<'_, T> { +impl Drain<'_, T, A> { /// The range from `self.vec.len` to `self.tail_start` contains elements /// that have been moved out. /// Fill that range as much as possible with new elements from the `replace_with` iterator. @@ -3331,11 +3589,15 @@ impl Drain<'_, T> { /// ``` #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] #[derive(Debug)] -pub struct DrainFilter<'a, T, F> -where +pub struct DrainFilter< + 'a, + T, + F, + #[unstable(feature = "allocator_api", issue = "32838")] A: AllocRef = Global, +> where F: FnMut(&mut T) -> bool, { - vec: &'a mut Vec, + vec: &'a mut Vec, /// The index of the item that will be inspected by the next call to `next`. idx: usize, /// The number of items that have been drained (removed) thus far. @@ -3352,8 +3614,20 @@ where panic_flag: bool, } +impl DrainFilter<'_, T, F, A> +where + F: FnMut(&mut T) -> bool, +{ + /// Returns a reference to the underlying allocator. + #[unstable(feature = "allocator_api", issue = "32838")] + #[inline] + pub fn alloc_ref(&self) -> &A { + self.vec.alloc_ref() + } +} + #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl Iterator for DrainFilter<'_, T, F> +impl Iterator for DrainFilter<'_, T, F, A> where F: FnMut(&mut T) -> bool, { @@ -3391,19 +3665,19 @@ where } #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl Drop for DrainFilter<'_, T, F> +impl Drop for DrainFilter<'_, T, F, A> where F: FnMut(&mut T) -> bool, { fn drop(&mut self) { - struct BackshiftOnDrop<'a, 'b, T, F> + struct BackshiftOnDrop<'a, 'b, T, F, A: AllocRef> where F: FnMut(&mut T) -> bool, { - drain: &'b mut DrainFilter<'a, T, F>, + drain: &'b mut DrainFilter<'a, T, F, A>, } - impl<'a, 'b, T, F> Drop for BackshiftOnDrop<'a, 'b, T, F> + impl<'a, 'b, T, F, A: AllocRef> Drop for BackshiftOnDrop<'a, 'b, T, F, A> where F: FnMut(&mut T) -> bool, { diff --git a/src/test/debuginfo/pretty-std.rs b/src/test/debuginfo/pretty-std.rs index 7ae82d522b09d..6632488171dad 100644 --- a/src/test/debuginfo/pretty-std.rs +++ b/src/test/debuginfo/pretty-std.rs @@ -13,7 +13,7 @@ // gdb-check:$1 = &[i32](len: 4) = {0, 1, 2, 3} // gdb-command: print vec -// gdb-check:$2 = Vec(len: 4, cap: [...]) = {4, 5, 6, 7} +// gdb-check:$2 = Vec(len: 4, cap: [...]) = {4, 5, 6, 7} // gdb-command: print str_slice // gdb-check:$3 = "IAMA string slice!" @@ -74,7 +74,7 @@ // NOTE: While slices have a .natvis entry that works in VS & VS Code, it fails in CDB 10.0.18362.1 // cdb-command: dx vec,d -// cdb-check:vec,d [...] : { size=4 } [Type: [...]::Vec] +// cdb-check:vec,d [...] : { size=4 } [Type: [...]::Vec] // cdb-check: [size] : 4 [Type: [...]] // cdb-check: [capacity] : [...] [Type: [...]] // cdb-check: [0] : 4 [Type: unsigned __int64] diff --git a/src/test/rustdoc/inline_cross/impl_trait.rs b/src/test/rustdoc/inline_cross/impl_trait.rs index e3a166b3d0e5f..0ab2fa99f877f 100644 --- a/src/test/rustdoc/inline_cross/impl_trait.rs +++ b/src/test/rustdoc/inline_cross/impl_trait.rs @@ -1,10 +1,11 @@ // aux-build:impl_trait_aux.rs // edition:2018 +// ignore-tidy-linelength extern crate impl_trait_aux; // @has impl_trait/fn.func.html -// @has - '//pre[@class="rust fn"]' "pub fn func<'a>(_x: impl Clone + Into> + 'a)" +// @has - '//pre[@class="rust fn"]' "pub fn func<'a>(_x: impl Clone + Into> + 'a)" // @!has - '//pre[@class="rust fn"]' 'where' pub use impl_trait_aux::func; @@ -31,7 +32,7 @@ pub use impl_trait_aux::func4; pub use impl_trait_aux::async_fn; // @has impl_trait/struct.Foo.html -// @has - '//*[@id="method.method"]//code' "pub fn method<'a>(_x: impl Clone + Into> + 'a)" +// @has - '//*[@id="method.method"]//code' "pub fn method<'a>(_x: impl Clone + Into> + 'a)" // @!has - '//*[@id="method.method"]//code' 'where' pub use impl_trait_aux::Foo; diff --git a/src/test/ui/associated-types/defaults-wf.stderr b/src/test/ui/associated-types/defaults-wf.stderr index f9044c2ea1b66..26c852601941a 100644 --- a/src/test/ui/associated-types/defaults-wf.stderr +++ b/src/test/ui/associated-types/defaults-wf.stderr @@ -6,7 +6,7 @@ LL | type Ty = Vec<[u8]>; | ::: $SRC_DIR/alloc/src/vec.rs:LL:COL | -LL | pub struct Vec { +LL | pub struct Vec { | - required by this bound in `Vec` | = help: the trait `Sized` is not implemented for `[u8]` diff --git a/src/test/ui/bad/bad-sized.stderr b/src/test/ui/bad/bad-sized.stderr index b9bce7fb5f49b..10d12a09b2579 100644 --- a/src/test/ui/bad/bad-sized.stderr +++ b/src/test/ui/bad/bad-sized.stderr @@ -17,7 +17,7 @@ LL | let x: Vec = Vec::new(); | ::: $SRC_DIR/alloc/src/vec.rs:LL:COL | -LL | pub struct Vec { +LL | pub struct Vec { | - required by this bound in `Vec` | = help: the trait `Sized` is not implemented for `dyn Trait` diff --git a/src/test/ui/const-generics/invalid-constant-in-args.rs b/src/test/ui/const-generics/invalid-constant-in-args.rs index 38ad510e5d7f0..0bd9cbf4f4708 100644 --- a/src/test/ui/const-generics/invalid-constant-in-args.rs +++ b/src/test/ui/const-generics/invalid-constant-in-args.rs @@ -1,4 +1,6 @@ +use std::cell::Cell; + fn main() { - let _: Vec<&str, "a"> = Vec::new(); + let _: Cell<&str, "a"> = Cell::new(""); //~^ ERROR wrong number of generic arguments } diff --git a/src/test/ui/const-generics/invalid-constant-in-args.stderr b/src/test/ui/const-generics/invalid-constant-in-args.stderr index 5111815e002f1..9b8a5d1ae4f20 100644 --- a/src/test/ui/const-generics/invalid-constant-in-args.stderr +++ b/src/test/ui/const-generics/invalid-constant-in-args.stderr @@ -1,8 +1,8 @@ error[E0107]: wrong number of generic arguments: expected 1, found 2 - --> $DIR/invalid-constant-in-args.rs:2:22 + --> $DIR/invalid-constant-in-args.rs:4:23 | -LL | let _: Vec<&str, "a"> = Vec::new(); - | ^^^ unexpected const argument +LL | let _: Cell<&str, "a"> = Cell::new(""); + | ^^^ unexpected const argument error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20433.stderr b/src/test/ui/issues/issue-20433.stderr index 3c14226b73472..d40946ae03f50 100644 --- a/src/test/ui/issues/issue-20433.stderr +++ b/src/test/ui/issues/issue-20433.stderr @@ -6,7 +6,7 @@ LL | fn iceman(c: Vec<[i32]>) {} | ::: $SRC_DIR/alloc/src/vec.rs:LL:COL | -LL | pub struct Vec { +LL | pub struct Vec { | - required by this bound in `Vec` | = help: the trait `Sized` is not implemented for `[i32]` diff --git a/src/test/ui/type/ascription/issue-34255-1.rs b/src/test/ui/type/ascription/issue-34255-1.rs index c0d39c59014ec..3aad085f08972 100644 --- a/src/test/ui/type/ascription/issue-34255-1.rs +++ b/src/test/ui/type/ascription/issue-34255-1.rs @@ -7,7 +7,7 @@ impl Reactor { input_cells: Vec::new() //~^ ERROR cannot find value `input_cells` in this scope //~| ERROR parenthesized type parameters may only be used with a `Fn` trait - //~| ERROR wrong number of type arguments: expected 1, found 0 + //~| ERROR wrong number of type arguments: expected at least 1, found 0 } } diff --git a/src/test/ui/type/ascription/issue-34255-1.stderr b/src/test/ui/type/ascription/issue-34255-1.stderr index 7895cf77fc0bf..402e54d2a95dd 100644 --- a/src/test/ui/type/ascription/issue-34255-1.stderr +++ b/src/test/ui/type/ascription/issue-34255-1.stderr @@ -10,11 +10,11 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait LL | input_cells: Vec::new() | ^^^^^ only `Fn` traits may use parentheses -error[E0107]: wrong number of type arguments: expected 1, found 0 +error[E0107]: wrong number of type arguments: expected at least 1, found 0 --> $DIR/issue-34255-1.rs:7:22 | LL | input_cells: Vec::new() - | ^^^^^^^^^^ expected 1 type argument + | ^^^^^^^^^^ expected at least 1 type argument error: aborting due to 3 previous errors