diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 8fee44d6f93..4b9bd74d392 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -590,6 +590,9 @@ pub fn with_capacity_in(capacity: usize, alloc: A) -> VecDeque { VecDeque { head: 0, len: 0, buf: RawVec::with_capacity_in(capacity, alloc) } } + /// Creates a `VecDeque` from a raw allocation, when the initialized + /// part of that allocation forms a *contiguous* subslice thereof. + /// /// For use by `vec::IntoIter::into_vecdeque` /// /// # Safety diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 41e2fb9b2f0..6bcde6d899c 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -1,6 +1,7 @@ #[cfg(not(no_global_oom_handling))] use super::AsVecIntoIter; use crate::alloc::{Allocator, Global}; +#[cfg(not(no_global_oom_handling))] use crate::collections::VecDeque; use crate::raw_vec::RawVec; use core::array; @@ -134,6 +135,7 @@ pub(crate) fn forget_remaining_elements(&mut self) { self.ptr = self.end; } + #[cfg(not(no_global_oom_handling))] #[inline] pub(crate) fn into_vecdeque(self) -> VecDeque { // Keep our `Drop` impl from dropping the elements and the allocator diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs index 823061d400f..0b8f5281b78 100644 --- a/library/alloc/tests/vec_deque.rs +++ b/library/alloc/tests/vec_deque.rs @@ -1741,22 +1741,32 @@ fn test_resize_keeps_reserved_space_from_item() { fn test_collect_from_into_iter_keeps_allocation() { let mut v = Vec::with_capacity(13); v.extend(0..7); - check(v.into_iter()); + check(v.as_ptr(), v.last().unwrap(), v.into_iter()); let mut v = VecDeque::with_capacity(13); v.extend(0..7); - check(v.into_iter()); + check(&v[0], &v[v.len() - 1], v.into_iter()); - fn check(mut it: impl Iterator) { + fn check(buf: *const i32, last: *const i32, mut it: impl Iterator) { assert_eq!(it.next(), Some(0)); assert_eq!(it.next(), Some(1)); + let mut v: VecDeque = it.collect(); assert_eq!(v.capacity(), 13); + assert_eq!(v.as_slices().0.as_ptr(), buf.wrapping_add(2)); + assert_eq!(&v[v.len() - 1] as *const _, last); + assert_eq!(v.as_slices(), ([2, 3, 4, 5, 6].as_slice(), [].as_slice())); v.push_front(7); assert_eq!(v.as_slices(), ([7, 2, 3, 4, 5, 6].as_slice(), [].as_slice())); v.push_front(8); assert_eq!(v.as_slices(), ([8, 7, 2, 3, 4, 5, 6].as_slice(), [].as_slice())); + + // Now that we've adding thing in place of the two that we removed from + // the front of the iterator, we're back to matching the buffer pointer. + assert_eq!(v.as_slices().0.as_ptr(), buf); + assert_eq!(&v[v.len() - 1] as *const _, last); + v.push_front(9); assert_eq!(v.as_slices(), ([9].as_slice(), [8, 7, 2, 3, 4, 5, 6].as_slice())); assert_eq!(v.capacity(), 13);