From 27a545df5178eed555df8393ced9cd5798393439 Mon Sep 17 00:00:00 2001 From: Peter Kehl Date: Sun, 11 Dec 2022 11:29:17 -0800 Subject: [PATCH] Vec, VecDeque, RawVec etc. with COOP_PREFERRED. WIP: probably NOT compilable. Triggers an internal compiler error from cargo 1.68.0-nightly (f6e737b1e 2022-12-02) --- library/alloc/src/boxed.rs | 15 +- library/alloc/src/collections/binary_heap.rs | 20 +- .../alloc/src/collections/vec_deque/drain.rs | 51 ++--- .../alloc/src/collections/vec_deque/macros.rs | 4 +- .../alloc/src/collections/vec_deque/mod.rs | 107 +++++------ .../src/collections/vec_deque/spec_extend.rs | 24 +-- library/alloc/src/lib.rs | 1 + library/alloc/src/raw_vec.rs | 49 ++--- library/alloc/src/slice.rs | 8 +- library/alloc/src/vec/drain.rs | 55 +++--- library/alloc/src/vec/drain_filter.rs | 27 +-- library/alloc/src/vec/into_iter.rs | 76 ++++---- library/alloc/src/vec/mod.rs | 174 +++++++++--------- library/alloc/src/vec/partial_eq.rs | 28 +-- library/core/src/alloc/mod.rs | 11 ++ 15 files changed, 339 insertions(+), 311 deletions(-) diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index e5f6b0c0c65d2..057b46efce69a 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -146,6 +146,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use core::alloc; use core::any::Any; use core::async_iter::AsyncIterator; use core::borrow; @@ -699,7 +700,7 @@ impl Box<[T]> { Err(_) => return Err(AllocError), }; let ptr = Global.allocate(layout)?; - Ok(RawVec::from_raw_parts_in(ptr.as_mut_ptr() as *mut _, len, Global).into_box(len)) + Ok(RawVec::::from_raw_parts_in(ptr.as_mut_ptr() as *mut _, len, Global).into_box(len)) } } @@ -731,12 +732,13 @@ impl Box<[T]> { Err(_) => return Err(AllocError), }; let ptr = Global.allocate_zeroed(layout)?; - Ok(RawVec::from_raw_parts_in(ptr.as_mut_ptr() as *mut _, len, Global).into_box(len)) + Ok(RawVec::::from_raw_parts_in(ptr.as_mut_ptr() as *mut _, len, Global).into_box(len)) } } } -impl Box<[T], A> { +impl Box<[T], A> +where [(); core::alloc::co_alloc_metadata_num_slots::()]: { /// Constructs a new boxed slice with uninitialized contents in the provided allocator. /// /// # Examples @@ -764,7 +766,7 @@ impl Box<[T], A> { // #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] pub fn new_uninit_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit], A> { - unsafe { RawVec::with_capacity_in(len, alloc).into_box(len) } + unsafe { RawVec::::with_capacity_in(len, alloc).into_box(len) } } /// Constructs a new boxed slice with uninitialized contents in the provided allocator, @@ -792,7 +794,7 @@ impl Box<[T], A> { // #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit], A> { - unsafe { RawVec::with_capacity_zeroed_in(len, alloc).into_box(len) } + unsafe { RawVec::::with_capacity_zeroed_in(len, alloc).into_box(len) } } } @@ -2049,7 +2051,8 @@ impl FromIterator for Box<[I]> { #[cfg(not(no_global_oom_handling))] #[stable(feature = "box_slice_clone", since = "1.3.0")] -impl Clone for Box<[T], A> { +impl Clone for Box<[T], A> +where [(); core::alloc::co_alloc_metadata_num_slots::()]: { fn clone(&self) -> Self { let alloc = Box::allocator(self).clone(); self.to_vec_in(alloc).into_boxed_slice() diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index 4583bc9a158ef..90a952dc0df63 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -143,12 +143,14 @@ #![allow(missing_docs)] #![stable(feature = "rust1", since = "1.0.0")] -use core::fmt; +use core::{alloc, fmt}; use core::iter::{FromIterator, FusedIterator, InPlaceIterable, SourceIter, TrustedLen}; use core::mem::{self, swap, ManuallyDrop}; use core::ops::{Deref, DerefMut}; use core::ptr; +use crate::alloc::Global; + use crate::collections::TryReserveError; use crate::slice; use crate::vec::{self, AsVecIntoIter, Vec}; @@ -1196,7 +1198,7 @@ impl BinaryHeap { /// ``` #[inline] #[stable(feature = "drain", since = "1.6.0")] - pub fn drain(&mut self) -> Drain<'_, T> { + pub fn drain(&mut self) -> Drain<'_, T, {alloc::SHORT_TERM_VEC_PREFERS_COOP}> { Drain { iter: self.data.drain(..) } } @@ -1476,12 +1478,14 @@ unsafe impl TrustedLen for IntoIterSorted {} /// [`drain`]: BinaryHeap::drain #[stable(feature = "drain", since = "1.6.0")] #[derive(Debug)] -pub struct Drain<'a, T: 'a> { - iter: vec::Drain<'a, T>, +pub struct Drain<'a, T: 'a, const COOP_PREFERRED: bool> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { + iter: vec::Drain<'a, T, Global, COOP_PREFERRED>, } #[stable(feature = "drain", since = "1.6.0")] -impl Iterator for Drain<'_, T> { +impl Iterator for Drain<'_, T, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Item = T; #[inline] @@ -1496,7 +1500,7 @@ impl Iterator for Drain<'_, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl DoubleEndedIterator for Drain<'_, T> { +impl DoubleEndedIterator for Drain<'_, T, COOP_PREFERRED> { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back() @@ -1504,14 +1508,14 @@ impl DoubleEndedIterator for Drain<'_, T> { } #[stable(feature = "drain", since = "1.6.0")] -impl ExactSizeIterator for Drain<'_, T> { +impl ExactSizeIterator for Drain<'_, T, COOP_PREFERRED> { fn is_empty(&self) -> bool { self.iter.is_empty() } } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Drain<'_, T> {} +impl FusedIterator for Drain<'_, T, COOP_PREFERRED> {} /// A draining iterator over the elements of a `BinaryHeap`. /// diff --git a/library/alloc/src/collections/vec_deque/drain.rs b/library/alloc/src/collections/vec_deque/drain.rs index e4f2f80892504..bab4919eb6032 100644 --- a/library/alloc/src/collections/vec_deque/drain.rs +++ b/library/alloc/src/collections/vec_deque/drain.rs @@ -19,11 +19,12 @@ pub struct Drain< 'a, T: 'a, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, + const COOP_PREFERRED: bool = {alloc::SHORT_TERM_VEC_PREFERS_COOP} > -where [(); alloc::co_alloc_metadata_num_slots::()]: { +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { // We can't just use a &mut VecDeque, as that would make Drain invariant over T // and we want it to be covariant instead - deque: NonNull>, + deque: NonNull>, // drain_start is stored in deque.len drain_len: usize, // index into the logical array, not the physical one (always lies in [0..deque.len)) @@ -35,10 +36,10 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { _marker: PhantomData<&'a T>, } -impl<'a, T, A: Allocator> Drain<'a, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl<'a, T, A: Allocator, const COOP_PREFERRED: bool> Drain<'a, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { pub(super) unsafe fn new( - deque: &'a mut VecDeque, + deque: &'a mut VecDeque, drain_start: usize, drain_len: usize, ) -> Self { @@ -90,8 +91,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl fmt::Debug for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl fmt::Debug for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Drain") .field(&self.drain_len) @@ -103,21 +104,21 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "drain", since = "1.6.0")] -unsafe impl Sync for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: {} +unsafe impl Sync for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} #[stable(feature = "drain", since = "1.6.0")] -unsafe impl Send for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: {} +unsafe impl Send for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} #[stable(feature = "drain", since = "1.6.0")] -impl Drop for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl Drop for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn drop(&mut self) { - struct DropGuard<'r, 'a, T, A: Allocator> (&'r mut Drain<'a, T, A>) - where [(); alloc::co_alloc_metadata_num_slots::()]:; + struct DropGuard<'r, 'a, T, A: Allocator, const COOP_PREFERRED: bool> (&'r mut Drain<'a, T, A, COOP_PREFERRED>) + where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]:; - impl<'r, 'a, T, A: Allocator> Drop for DropGuard<'r, 'a, T, A> - where [(); alloc::co_alloc_metadata_num_slots::()]: { + impl<'r, 'a, T, A: Allocator, const COOP_PREFERRED: bool> Drop for DropGuard<'r, 'a, T, A, COOP_PREFERRED> + where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn drop(&mut self) { if self.0.remaining != 0 { unsafe { @@ -198,8 +199,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "drain", since = "1.6.0")] -impl Iterator for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl Iterator for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Item = T; #[inline] @@ -221,8 +222,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "drain", since = "1.6.0")] -impl DoubleEndedIterator for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl DoubleEndedIterator for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { #[inline] fn next_back(&mut self) -> Option { if self.remaining == 0 { @@ -235,9 +236,9 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "drain", since = "1.6.0")] -impl ExactSizeIterator for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: {} +impl ExactSizeIterator for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: {} +impl FusedIterator for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} diff --git a/library/alloc/src/collections/vec_deque/macros.rs b/library/alloc/src/collections/vec_deque/macros.rs index f7768f54c6225..68ee43152b5b5 100644 --- a/library/alloc/src/collections/vec_deque/macros.rs +++ b/library/alloc/src/collections/vec_deque/macros.rs @@ -1,10 +1,10 @@ macro_rules! __impl_slice_eq1 { ([$($vars:tt)*] $lhs:ty, $rhs:ty, $($constraints:tt)*) => { #[stable(feature = "vec_deque_partial_eq_slice", since = "1.17.0")] - impl PartialEq<$rhs> for $lhs + impl PartialEq<$rhs> for $lhs where T: PartialEq, - [(); core::alloc::co_alloc_metadata_num_slots::()]:, + [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]:, $($constraints)* { fn eq(&self, other: &$rhs) -> bool { diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 207ee3721fb03..ee7111b594bc8 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -97,8 +97,9 @@ mod tests; pub struct VecDeque< T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, + const COOP_PREFERRED: bool = true > -where [(); alloc::co_alloc_metadata_num_slots::()]: +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { // `self[0]`, if it exists, is `buf[head]`. // `head < buf.capacity()`, unless `buf.capacity() == 0` when `head == 0`. @@ -107,12 +108,12 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: // if `len == 0`, the exact value of `head` is unimportant. // if `T` is zero-Sized, then `self.len <= usize::MAX`, otherwise `self.len <= isize::MAX as usize`. len: usize, - buf: RawVec, + buf: RawVec, } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl Clone for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn clone(&self) -> Self { let mut deq = Self::with_capacity_in(self.len(), self.allocator().clone()); deq.extend(self.iter().cloned()); @@ -126,8 +127,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<#[may_dangle] T, A: Allocator> Drop for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +unsafe impl<#[may_dangle] T, A: Allocator, const COOP_PREFERRED: bool> Drop for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn drop(&mut self) { /// Runs the destructor for all items in the slice when it gets dropped (normally or /// during unwinding). @@ -160,8 +161,8 @@ impl Default for VecDeque { } } -impl VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Marginally more convenient #[inline] fn ptr(&self) -> *mut T { @@ -450,14 +451,14 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { mut iter: impl Iterator, len: usize, ) -> usize { - struct Guard<'a, T, A: Allocator> - where [(); alloc::co_alloc_metadata_num_slots::()]: { - deque: &'a mut VecDeque, + struct Guard<'a, T, A: Allocator, const COOP_PREFERRED: bool> + where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { + deque: &'a mut VecDeque, written: usize, } - impl<'a, T, A: Allocator> Drop for Guard<'a, T, A> - where [(); alloc::co_alloc_metadata_num_slots::()]: { + impl<'a, T, A: Allocator, const COOP_PREFERRED: bool> Drop for Guard<'a, T, A, COOP_PREFERRED> + where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn drop(&mut self) { self.deque.len += self.written; } @@ -570,8 +571,8 @@ impl VecDeque { } } -impl VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Creates an empty deque. /// /// # Examples @@ -2604,8 +2605,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } } -impl VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Modifies the deque in-place so that `len()` is equal to new_len, /// either by removing excess elements from the back or by appending clones of `value` /// to the back. @@ -2650,8 +2651,8 @@ fn wrap_index(logical_index: usize, capacity: usize) -> usize { } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl PartialEq for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn eq(&self, other: &Self) -> bool { if self.len != other.len() { return false; @@ -2690,27 +2691,27 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: {} +impl Eq for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} -__impl_slice_eq1! { [] VecDeque, Vec, } -__impl_slice_eq1! { [] VecDeque, &[U], } -__impl_slice_eq1! { [] VecDeque, &mut [U], } -__impl_slice_eq1! { [const N: usize] VecDeque, [U; N], } -__impl_slice_eq1! { [const N: usize] VecDeque, &[U; N], } -__impl_slice_eq1! { [const N: usize] VecDeque, &mut [U; N], } +__impl_slice_eq1! { [] VecDeque, Vec, } +__impl_slice_eq1! { [] VecDeque, &[U], } +__impl_slice_eq1! { [] VecDeque, &mut [U], } +__impl_slice_eq1! { [const N: usize] VecDeque, [U; N], } +__impl_slice_eq1! { [const N: usize] VecDeque, &[U; N], } +__impl_slice_eq1! { [const N: usize] VecDeque, &mut [U; N], } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl PartialOrd for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn partial_cmp(&self, other: &Self) -> Option { self.iter().partial_cmp(other.iter()) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl Ord for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { #[inline] fn cmp(&self, other: &Self) -> Ordering { self.iter().cmp(other.iter()) @@ -2718,8 +2719,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -impl Hash for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl Hash for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn hash(&self, state: &mut H) { state.write_length_prefix(self.len); // It's not possible to use Hash::hash_slice on slices @@ -2733,8 +2734,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -impl Index for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl Index for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Output = T; #[inline] @@ -2744,8 +2745,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -impl IndexMut for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl IndexMut for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { #[inline] fn index_mut(&mut self, index: usize) -> &mut T { self.get_mut(index).expect("Out of bounds access") @@ -2760,8 +2761,8 @@ impl FromIterator for VecDeque { } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl IntoIterator for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Item = T; type IntoIter = IntoIter; @@ -2773,8 +2774,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, A: Allocator> IntoIterator for &'a VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl<'a, T, A: Allocator, const COOP_PREFERRED: bool> IntoIterator for &'a VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Item = &'a T; type IntoIter = Iter<'a, T>; @@ -2784,8 +2785,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, A: Allocator> IntoIterator for &'a mut VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl<'a, T, A: Allocator, const COOP_PREFERRED: bool> IntoIterator for &'a mut VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Item = &'a mut T; type IntoIter = IterMut<'a, T>; @@ -2795,8 +2796,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl Extend for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn extend>(&mut self, iter: I) { >::spec_extend(self, iter.into_iter()); } @@ -2813,8 +2814,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "extend_ref", since = "1.2.0")] -impl<'a, T: 'a + Copy, A: Allocator> Extend<&'a T> for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl<'a, T: 'a + Copy, A: Allocator, const COOP_PREFERRED: bool> Extend<&'a T> for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn extend>(&mut self, iter: I) { self.spec_extend(iter.into_iter()); } @@ -2831,16 +2832,16 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl fmt::Debug for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.iter()).finish() } } #[stable(feature = "vecdeque_vec_conversions", since = "1.10.0")] -impl From> for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl From> for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Turn a [`Vec`] into a [`VecDeque`]. /// /// [`Vec`]: crate::vec::Vec @@ -2857,8 +2858,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "vecdeque_vec_conversions", since = "1.10.0")] -impl From> for Vec -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl From> for Vec +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Turn a [`VecDeque`] into a [`Vec`]. /// /// [`Vec`]: crate::vec::Vec diff --git a/library/alloc/src/collections/vec_deque/spec_extend.rs b/library/alloc/src/collections/vec_deque/spec_extend.rs index f6d957fdc03ba..cdeda1a57bed5 100644 --- a/library/alloc/src/collections/vec_deque/spec_extend.rs +++ b/library/alloc/src/collections/vec_deque/spec_extend.rs @@ -13,10 +13,10 @@ pub(super) trait SpecExtend { fn spec_extend(&mut self, iter: I); } -impl SpecExtend for VecDeque +impl SpecExtend for VecDeque where I: Iterator, - [(); alloc::co_alloc_metadata_num_slots::()]: + [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { default fn spec_extend(&mut self, mut iter: I) { // This function should be the moral equivalent of: @@ -26,8 +26,8 @@ where // } // May only be called if `deque.len() < deque.capacity()` - unsafe fn push_unchecked(deque: &mut VecDeque, element: T) - where [(); alloc::co_alloc_metadata_num_slots::()]: { + unsafe fn push_unchecked(deque: &mut VecDeque, element: T) + where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { // SAFETY: Because of the precondition, it's guaranteed that there is space // in the logical array after the last element. unsafe { deque.buffer_write(deque.to_physical_idx(deque.len), element) }; @@ -54,10 +54,10 @@ where } } -impl SpecExtend for VecDeque +impl SpecExtend for VecDeque where I: TrustedLen, - [(); alloc::co_alloc_metadata_num_slots::()]: + [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { default fn spec_extend(&mut self, iter: I) { // This is the case for a TrustedLen iterator. @@ -90,8 +90,8 @@ where } } -impl SpecExtend> for VecDeque -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl SpecExtend> for VecDeque +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn spec_extend(&mut self, mut iterator: vec::IntoIter) { let slice = iterator.as_slice(); self.reserve(slice.len()); @@ -104,21 +104,21 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } } -impl<'a, T: 'a, I, A: Allocator> SpecExtend<&'a T, I> for VecDeque +impl<'a, T: 'a, I, A: Allocator, const COOP_PREFERRED: bool> SpecExtend<&'a T, I> for VecDeque where I: Iterator, T: Copy, - [(); alloc::co_alloc_metadata_num_slots::()]: + [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { default fn spec_extend(&mut self, iterator: I) { self.spec_extend(iterator.copied()) } } -impl<'a, T: 'a, A: Allocator> SpecExtend<&'a T, slice::Iter<'a, T>> for VecDeque +impl<'a, T: 'a, A: Allocator, const COOP_PREFERRED: bool> SpecExtend<&'a T, slice::Iter<'a, T>> for VecDeque where T: Copy, - [(); alloc::co_alloc_metadata_num_slots::()]: + [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) { let slice = iterator.as_slice(); diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index c5f42bd84a7f3..6b41429e7eef4 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -178,6 +178,7 @@ #![feature(fundamental)] #![cfg_attr(not(test), feature(generator_trait))] #![feature(global_co_alloc)] +#![feature(global_co_alloc_short_term_pref)] #![feature(hashmap_internals)] #![feature(lang_items)] // When we used min_specialization instead of specialization, library/alloc/src/vec/mod.rs was failing with: diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 9cf96ac700f55..19f1ef0ac06e1 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -1,6 +1,6 @@ #![unstable(feature = "raw_vec_internals", reason = "unstable const warnings", issue = "none")] -use core::alloc::{self, LayoutError, GlobalCoAllocMeta}; +use core::alloc::{self, LayoutError, GlobalCoAllocMeta, PtrAndMeta}; use core::cmp; use core::intrinsics; use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; @@ -49,11 +49,9 @@ enum AllocInit { /// `usize::MAX`. This means that you need to be careful when round-tripping this type with a /// `Box<[T]>`, since `capacity()` won't yield the length. #[allow(missing_debug_implementations)] -// @TODO -// 1. make const generic _coop come from the target specification -// 2. apply `_coop` with logical && to `A::IsCoAllocator` -pub(crate) struct RawVec -where [(); alloc::co_alloc_metadata_num_slots::()]: +// @TODO apply `_coop` with logical && to `A::IsCoAllocator` +pub(crate) struct RawVec +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { ptr: Unique, cap: usize, @@ -61,7 +59,7 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: // As of v1.67.0, `cmp` for `TypeId` is not `const`, unfortunately: //pub(crate) meta: [GlobalCoAllocMeta; {if core::any::TypeId::of::()==core::any::TypeId::of::() {1} else {0}}], //pub(crate) meta: [GlobalCoAllocMeta; mem::size_of::()], - pub(crate) meta: [GlobalCoAllocMeta; alloc::co_alloc_metadata_num_slots::()], + pub(crate) metas: [GlobalCoAllocMeta; alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)], } impl RawVec { @@ -111,8 +109,8 @@ impl RawVec { } } -impl RawVec -where [(); alloc::co_alloc_metadata_num_slots::()]: +impl RawVec +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { // Tiny Vecs are dumb. Skip to: // - 8 if the element size is 1, because any heap allocators is likely @@ -131,7 +129,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: /// the returned `RawVec`. pub const fn new_in(alloc: A) -> Self { // `cap: 0` means "unallocated". zero-sized types are ignored. - Self { ptr: Unique::dangling(), cap: 0, alloc, meta: GlobalCoAllocMeta {/*one: 1*/ /* , two: 2, three: 3, four: 4*/} } + Self { ptr: Unique::dangling(), cap: 0, alloc, + metas: [GlobalCoAllocMeta {/*one: 1*/ /* , two: 2, three: 3, four: 4*/}; alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)] } } /// Like `with_capacity`, but parameterized over the choice of @@ -208,7 +207,7 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: ptr: unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) }, cap: capacity, alloc, - meta: GlobalCoAllocMeta {/*one: 1*/ /*, two: 2, three: 3, four: 4*/} + metas: [GlobalCoAllocMeta {/*one: 1*/ /*, two: 2, three: 3, four: 4*/}; alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)] } } } @@ -225,7 +224,7 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: /// guaranteed. #[inline] pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, alloc: A) -> Self { - Self { ptr: unsafe { Unique::new_unchecked(ptr) }, cap: capacity, alloc, meta: GlobalCoAllocMeta {/*one: 1*/ /*, two: 2, three: 3, four: 4*/} } + Self { ptr: unsafe { Unique::new_unchecked(ptr) }, cap: capacity, alloc, metas: [GlobalCoAllocMeta {/*one: 1*/ /*, two: 2, three: 3, four: 4*/}; alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)] } } /// Gets a raw pointer to the start of the allocation. Note that this is @@ -289,12 +288,12 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: // handle_reserve behind a call, while making sure that this function is likely to be // inlined as just a comparison and a call if the comparison fails. #[cold] - fn do_reserve_and_handle( - slf: &mut RawVec, + fn do_reserve_and_handle( + slf: &mut RawVec, len: usize, additional: usize, ) - where [(); alloc::co_alloc_metadata_num_slots::()]: + where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { handle_reserve(slf.grow_amortized(len, additional)); } @@ -368,8 +367,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: } } -impl RawVec -where [(); alloc::co_alloc_metadata_num_slots::()]: +impl RawVec +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Returns if the buffer needs to grow to fulfill the needed extra capacity. /// Mainly used to make inlining reserve-calls possible without inlining `grow`. @@ -490,19 +489,25 @@ where memory.map_err(|_| AllocError { layout: new_layout, non_exhaustive: () }.into()) } -unsafe impl<#[may_dangle] T, A: Allocator> Drop for RawVec -where [(); alloc::co_alloc_metadata_num_slots::()]: +unsafe impl<#[may_dangle] T, A: Allocator, const COOP_PREFERRED: bool> Drop for RawVec +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Frees the memory owned by the `RawVec` *without* trying to drop its contents. default fn drop(&mut self) { if let Some((ptr, layout)) = self.current_memory() { - unsafe { self.alloc.co_deallocate(ptr, layout) } + if A::IS_CO_ALLOCATOR && COOP_PREFERRED { + let meta = self.metas[0]; + unsafe { self.alloc.co_deallocate(PtrAndMeta {ptr, meta}, layout) } + } else { + unsafe { self.alloc.deallocate(ptr, layout) } + } } } } // @TODO Custom -/*unsafe impl<#[may_dangle] T> Drop for RawVec { +unsafe impl<#[may_dangle] T, const COOP_PREFERRED: bool> Drop for RawVec +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Frees the memory owned by the `RawVec` *without* trying to drop its contents. fn drop(&mut self) { // @TODO @@ -510,7 +515,7 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: unsafe { self.alloc.deallocate(ptr, layout) } } } -}*/ +} // Central function for reserve error handling. #[cfg(not(no_global_oom_handling))] diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index 49b66a4cb6988..f33e74db03641 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -773,16 +773,16 @@ impl> Join<&[T]> for [V] { //////////////////////////////////////////////////////////////////////////////// #[stable(feature = "rust1", since = "1.0.0")] -impl Borrow<[T]> for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl Borrow<[T]> for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn borrow(&self) -> &[T] { &self[..] } } #[stable(feature = "rust1", since = "1.0.0")] -impl BorrowMut<[T]> for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl BorrowMut<[T]> for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn borrow_mut(&mut self) -> &mut [T] { &mut self[..] } diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs index dfb6f3c857951..5f00774c33552 100644 --- a/library/alloc/src/vec/drain.rs +++ b/library/alloc/src/vec/drain.rs @@ -23,8 +23,9 @@ pub struct Drain< 'a, T: 'a, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + 'a = Global, + const COOP_PREFERRED: bool = {alloc::SHORT_TERM_VEC_PREFERS_COOP} > -where [(); alloc::co_alloc_metadata_num_slots::()]: { +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Index of tail to preserve pub(super) tail_start: usize, /// Length of tail @@ -35,15 +36,15 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "collection_debug", since = "1.17.0")] -impl fmt::Debug for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl fmt::Debug for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("Drain").field(&self.iter.as_slice()).finish() } } -impl<'a, T, A: Allocator> Drain<'a, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl<'a, T, A: Allocator, const COOP_PREFERRED: bool> Drain<'a, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Returns the remaining items of this iterator as a slice. /// /// # Examples @@ -142,23 +143,23 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "vec_drain_as_slice", since = "1.46.0")] -impl<'a, T, A: Allocator> AsRef<[T]> for Drain<'a, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl<'a, T, A: Allocator, const COOP_PREFERRED: bool> AsRef<[T]> for Drain<'a, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn as_ref(&self) -> &[T] { self.as_slice() } } #[stable(feature = "drain", since = "1.6.0")] -unsafe impl Sync for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: {} +unsafe impl Sync for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} #[stable(feature = "drain", since = "1.6.0")] -unsafe impl Send for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: {} +unsafe impl Send for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} #[stable(feature = "drain", since = "1.6.0")] -impl Iterator for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl Iterator for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Item = T; #[inline] @@ -172,8 +173,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "drain", since = "1.6.0")] -impl DoubleEndedIterator for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl DoubleEndedIterator for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back().map(|elt| unsafe { ptr::read(elt as *const _) }) @@ -181,15 +182,15 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "drain", since = "1.6.0")] -impl Drop for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl Drop for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn drop(&mut self) { /// Moves back the un-`Drain`ed elements to restore the original `Vec`. - struct DropGuard<'r, 'a, T, A: Allocator>(&'r mut Drain<'a, T, A>) - where [(); alloc::co_alloc_metadata_num_slots::()]: ; + struct DropGuard<'r, 'a, T, A: Allocator, const COOP_PREFERRED: bool>(&'r mut Drain<'a, T, A, COOP_PREFERRED>) + where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: ; - impl<'r, 'a, T, A: Allocator> Drop for DropGuard<'r, 'a, T, A> - where [(); alloc::co_alloc_metadata_num_slots::()]: { + impl<'r, 'a, T, A: Allocator, const COOP_PREFERRED: bool> Drop for DropGuard<'r, 'a, T, A, COOP_PREFERRED> + where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn drop(&mut self) { if self.0.tail_len > 0 { unsafe { @@ -253,17 +254,17 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "drain", since = "1.6.0")] -impl ExactSizeIterator for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl ExactSizeIterator for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn is_empty(&self) -> bool { self.iter.is_empty() } } #[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: {} +unsafe impl TrustedLen for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for Drain<'_, T, A> -where [(); alloc::co_alloc_metadata_num_slots::()]: {} +impl FusedIterator for Drain<'_, T, A, COOP_PREFERRED> +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} diff --git a/library/alloc/src/vec/drain_filter.rs b/library/alloc/src/vec/drain_filter.rs index d78a81b647d5b..7be4abacbec96 100644 --- a/library/alloc/src/vec/drain_filter.rs +++ b/library/alloc/src/vec/drain_filter.rs @@ -24,11 +24,12 @@ pub struct DrainFilter< T, F, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, + const COOP_PREFERRED: bool = true > where F: FnMut(&mut T) -> bool, - [(); alloc::co_alloc_metadata_num_slots::()]: + [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { - pub(super) vec: &'a mut Vec, + pub(super) vec: &'a mut Vec, /// The index of the item that will be inspected by the next call to `next`. pub(super) idx: usize, /// The number of items that have been drained (removed) thus far. @@ -45,10 +46,10 @@ pub struct DrainFilter< pub(super) panic_flag: bool, } -impl DrainFilter<'_, T, F, A> +impl DrainFilter<'_, T, F, A, COOP_PREFERRED> where F: FnMut(&mut T) -> bool, - [(); alloc::co_alloc_metadata_num_slots::()]: + [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Returns a reference to the underlying allocator. #[unstable(feature = "allocator_api", issue = "32838")] @@ -114,10 +115,10 @@ where } #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl Iterator for DrainFilter<'_, T, F, A> +impl Iterator for DrainFilter<'_, T, F, A, COOP_PREFERRED> where F: FnMut(&mut T) -> bool, - [(); alloc::co_alloc_metadata_num_slots::()]: + [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Item = T; @@ -153,24 +154,24 @@ where } #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] -impl Drop for DrainFilter<'_, T, F, A> +impl Drop for DrainFilter<'_, T, F, A, COOP_PREFERRED> where F: FnMut(&mut T) -> bool, - [(); alloc::co_alloc_metadata_num_slots::()]: + [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn drop(&mut self) { - struct BackshiftOnDrop<'a, 'b, T, F, A: Allocator> + struct BackshiftOnDrop<'a, 'b, T, F, A: Allocator, const COOP_PREFERRED: bool> where F: FnMut(&mut T) -> bool, - [(); alloc::co_alloc_metadata_num_slots::()]: + [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { - drain: &'b mut DrainFilter<'a, T, F, A>, + drain: &'b mut DrainFilter<'a, T, F, A, COOP_PREFERRED>, } - impl<'a, 'b, T, F, A: Allocator> Drop for BackshiftOnDrop<'a, 'b, T, F, A> + impl<'a, 'b, T, F, A: Allocator, const COOP_PREFERRED: bool> Drop for BackshiftOnDrop<'a, 'b, T, F, A, COOP_PREFERRED> where F: FnMut(&mut T) -> bool, - [(); alloc::co_alloc_metadata_num_slots::()]: + [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn drop(&mut self) { unsafe { diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 78e51bbb0a05c..0601becedfd3d 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -31,8 +31,9 @@ use core::slice::{self}; pub struct IntoIter< T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, + const COOP_PREFERRED: bool = {alloc::SHORT_TERM_VEC_PREFERS_COOP} > -where [(); alloc::co_alloc_metadata_num_slots::()]: { +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { pub(super) buf: NonNull, pub(super) phantom: PhantomData, pub(super) cap: usize, @@ -44,15 +45,15 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "vec_intoiter_debug", since = "1.13.0")] -impl fmt::Debug for IntoIter -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl fmt::Debug for IntoIter +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("IntoIter").field(&self.as_slice()).finish() } } -impl IntoIter -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl IntoIter +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Returns the remaining items of this iterator as a slice. /// /// # Examples @@ -139,8 +140,7 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { #[cfg(not(no_global_oom_handling))] #[inline] - pub(crate) fn into_vecdeque(self) -> VecDeque - where [(); alloc::co_alloc_metadata_num_slots::()]: { + pub(crate) fn into_vecdeque(self) -> VecDeque { // Keep our `Drop` impl from dropping the elements and the allocator let mut this = ManuallyDrop::new(self); @@ -167,23 +167,23 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "vec_intoiter_as_ref", since = "1.46.0")] -impl AsRef<[T]> for IntoIter -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl AsRef<[T]> for IntoIter +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn as_ref(&self) -> &[T] { self.as_slice() } } #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl Send for IntoIter -where [(); alloc::co_alloc_metadata_num_slots::()]: {} +unsafe impl Send for IntoIter +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl Sync for IntoIter -where [(); alloc::co_alloc_metadata_num_slots::()]: {} +unsafe impl Sync for IntoIter +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} #[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for IntoIter -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl Iterator for IntoIter +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Item = T; #[inline] @@ -300,8 +300,8 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for IntoIter -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl DoubleEndedIterator for IntoIter +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { #[inline] fn next_back(&mut self) -> Option { if self.end == self.ptr { @@ -342,20 +342,20 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for IntoIter -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl ExactSizeIterator for IntoIter +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn is_empty(&self) -> bool { self.ptr == self.end } } #[stable(feature = "fused", since = "1.26.0")] -impl FusedIterator for IntoIter -where [(); alloc::co_alloc_metadata_num_slots::()]: {} +impl FusedIterator for IntoIter +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} #[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for IntoIter -where [(); alloc::co_alloc_metadata_num_slots::()]: {} +unsafe impl TrustedLen for IntoIter +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} #[doc(hidden)] #[unstable(issue = "none", feature = "std_internals")] @@ -371,18 +371,18 @@ impl NonDrop for T {} #[unstable(issue = "none", feature = "std_internals")] // TrustedRandomAccess (without NoCoerce) must not be implemented because // subtypes/supertypes of `T` might not be `NonDrop` -unsafe impl TrustedRandomAccessNoCoerce for IntoIter +unsafe impl TrustedRandomAccessNoCoerce for IntoIter where T: NonDrop, - [(); alloc::co_alloc_metadata_num_slots::()]: + [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { const MAY_HAVE_SIDE_EFFECT: bool = false; } #[cfg(not(no_global_oom_handling))] #[stable(feature = "vec_into_iter_clone", since = "1.8.0")] -impl Clone for IntoIter -where [(); alloc::co_alloc_metadata_num_slots::()]: { +impl Clone for IntoIter +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { #[cfg(not(test))] fn clone(&self) -> Self { self.as_slice().to_vec_in(self.alloc.deref().clone()).into_iter() @@ -394,20 +394,20 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter -where [(); alloc::co_alloc_metadata_num_slots::()]: { +unsafe impl<#[may_dangle] T, A: Allocator, const COOP_PREFERRED: bool> Drop for IntoIter +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn drop(&mut self) { - struct DropGuard<'a, T, A: Allocator>(&'a mut IntoIter) - where [(); alloc::co_alloc_metadata_num_slots::()]: ; + struct DropGuard<'a, T, A: Allocator, const COOP_PREFERRED: bool>(&'a mut IntoIter) + where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: ; - impl Drop for DropGuard<'_, T, A> - where [(); alloc::co_alloc_metadata_num_slots::()]: { + impl Drop for DropGuard<'_, T, A, COOP_PREFERRED> + where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn drop(&mut self) { unsafe { // `IntoIter::alloc` is not used anymore after this and will be dropped by RawVec let alloc = ManuallyDrop::take(&mut self.0.alloc); // RawVec handles deallocation - let _ = RawVec::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc); + let _ = RawVec::::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc); } } } @@ -425,13 +425,13 @@ where [(); alloc::co_alloc_metadata_num_slots::()]: { // also refer to the vec::in_place_collect module documentation to get an overview #[unstable(issue = "none", feature = "inplace_iteration")] #[doc(hidden)] -unsafe impl InPlaceIterable for IntoIter -where [(); alloc::co_alloc_metadata_num_slots::()]: {} +unsafe impl InPlaceIterable for IntoIter +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} #[unstable(issue = "none", feature = "inplace_iteration")] #[doc(hidden)] -unsafe impl SourceIter for IntoIter -where [(); alloc::co_alloc_metadata_num_slots::()]: { +unsafe impl SourceIter for IntoIter +where [(); alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Source = Self; #[inline] diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 77f0e1e452791..9008b6f63e14c 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -398,10 +398,10 @@ mod spec_extend; #[cfg_attr(not(test), rustc_diagnostic_item = "Vec")] #[rustc_insignificant_dtor] // @TODO _coop -pub struct Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: +pub struct Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { - buf: RawVec, + buf: RawVec, len: usize, } @@ -606,8 +606,8 @@ impl Vec { } } -impl Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Constructs a new, empty `Vec`. /// /// The vector will not allocate until elements are pushed onto it. @@ -1618,16 +1618,16 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { // This drop guard will be invoked when predicate or `drop` of element panicked. // It shifts unchecked elements to cover holes and `set_len` to the correct length. // In cases when predicate and `drop` never panick, it will be optimized out. - struct BackshiftOnDrop<'a, T, A: Allocator> - where [(); core::alloc::co_alloc_metadata_num_slots::()]: { - v: &'a mut Vec, + struct BackshiftOnDrop<'a, T, A: Allocator, const VEC_IS_COOP: bool=true> + where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(VEC_IS_COOP)]: { + v: &'a mut Vec, processed_len: usize, deleted_cnt: usize, original_len: usize, } - impl Drop for BackshiftOnDrop<'_, T, A> - where [(); core::alloc::co_alloc_metadata_num_slots::()]: { + impl Drop for BackshiftOnDrop<'_, T, A, VEC_IS_COOP> + where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(VEC_IS_COOP)]: { fn drop(&mut self) { if self.deleted_cnt > 0 { // SAFETY: Trailing unchecked items must be valid since we never touch them. @@ -1646,15 +1646,15 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { } } - let mut g = BackshiftOnDrop { v: self, processed_len: 0, deleted_cnt: 0, original_len }; + let mut g = BackshiftOnDrop:: { v: self, processed_len: 0, deleted_cnt: 0, original_len }; - fn process_loop( + fn process_loop( original_len: usize, f: &mut F, - g: &mut BackshiftOnDrop<'_, T, A>, + g: &mut BackshiftOnDrop<'_, T, A, VEC_IS_COOP>, ) where F: FnMut(&mut T) -> bool, - [(); core::alloc::co_alloc_metadata_num_slots::()]: + [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(VEC_IS_COOP)]: { while g.processed_len != original_len { // SAFETY: Unchecked element must be valid. @@ -1685,10 +1685,10 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { } // Stage 1: Nothing was deleted. - process_loop::(original_len, &mut f, &mut g); + process_loop::(original_len, &mut f, &mut g); // Stage 2: Some elements were deleted. - process_loop::(original_len, &mut f, &mut g); + process_loop::(original_len, &mut f, &mut g); // All item are processed. This can be optimized to `set_len` by LLVM. drop(g); @@ -1747,8 +1747,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { } /* INVARIANT: vec.len() > read >= write > write-1 >= 0 */ - struct FillGapOnDrop<'a, T, A: core::alloc::Allocator> - where [(); core::alloc::co_alloc_metadata_num_slots::()]: { + struct FillGapOnDrop<'a, T, A: core::alloc::Allocator, const COOP_PREFERRED: bool> + where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /* Offset of the element we want to check if it is duplicate */ read: usize, @@ -1757,11 +1757,11 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { write: usize, /* The Vec that would need correction if `same_bucket` panicked */ - vec: &'a mut Vec, + vec: &'a mut Vec, } - impl<'a, T, A: core::alloc::Allocator> Drop for FillGapOnDrop<'a, T, A> - where [(); core::alloc::co_alloc_metadata_num_slots::()]: { + impl<'a, T, A: core::alloc::Allocator, const COOP_PREFERRED: bool> Drop for FillGapOnDrop<'a, T, A, COOP_PREFERRED> + where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn drop(&mut self) { /* This code gets executed when `same_bucket` panics */ @@ -2354,8 +2354,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { } } -impl Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// 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 @@ -2454,8 +2454,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { } } -impl Vec<[T; N], A> -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl Vec<[T; N], A, COOP_PREFERRED> +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Takes a `Vec<[T; N]>` and flattens it into a `Vec`. /// /// # Panics @@ -2516,8 +2516,8 @@ impl ExtendWith for ExtendElement { } } -impl Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { #[cfg(not(no_global_oom_handling))] /// Extend the vector by `n` values, using the given generator. fn extend_with>(&mut self, n: usize, mut value: E) { @@ -2549,8 +2549,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { } } -impl Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Removes consecutive repeated elements in the vector according to the /// [`PartialEq`] trait implementation. /// @@ -2586,8 +2586,8 @@ pub fn from_elem(elem: T, n: usize) -> Vec { #[doc(hidden)] #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] -pub fn from_elem_in(elem: T, n: usize, alloc: A) -> Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +pub fn from_elem_in(elem: T, n: usize, alloc: A) -> Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { ::from_elem(elem, n, alloc) } @@ -2599,8 +2599,8 @@ trait ExtendFromWithinSpec { unsafe fn spec_extend_from_within(&mut self, src: Range); } -impl ExtendFromWithinSpec for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl ExtendFromWithinSpec for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { default unsafe fn spec_extend_from_within(&mut self, src: Range) { // SAFETY: // - len is increased only after initializing elements @@ -2619,8 +2619,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { } } -impl ExtendFromWithinSpec for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl ExtendFromWithinSpec for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { unsafe fn spec_extend_from_within(&mut self, src: Range) { let count = src.len(); { @@ -2653,8 +2653,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { //////////////////////////////////////////////////////////////////////////////// #[stable(feature = "rust1", since = "1.0.0")] -impl ops::Deref for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl ops::Deref for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Target = [T]; #[inline] @@ -2664,8 +2664,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -impl ops::DerefMut for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl ops::DerefMut for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { #[inline] fn deref_mut(&mut self) -> &mut [T] { unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) } @@ -2678,8 +2678,8 @@ trait SpecCloneFrom { } #[cfg(not(no_global_oom_handling))] -impl SpecCloneFrom for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl SpecCloneFrom for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { default fn clone_from(this: &mut Self, other: &Self) { // drop anything that will not be overwritten this.truncate(other.len()); @@ -2695,8 +2695,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { } #[cfg(not(no_global_oom_handling))] -impl SpecCloneFrom for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl SpecCloneFrom for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn clone_from(this: &mut Self, other: &Self) { this.clear(); this.extend_from_slice(other); @@ -2705,8 +2705,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl Clone for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { #[cfg(not(test))] fn clone(&self) -> Self { let alloc = self.allocator().clone(); @@ -2741,8 +2741,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { /// assert_eq!(b.hash_one(v), b.hash_one(s)); /// ``` #[stable(feature = "rust1", since = "1.0.0")] -impl Hash for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl Hash for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { #[inline] fn hash(&self, state: &mut H) { Hash::hash(&**self, state) @@ -2754,8 +2754,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { message = "vector indices are of type `usize` or ranges of `usize`", label = "vector indices are of type `usize` or ranges of `usize`" )] -impl, A: Allocator> Index for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl, A: Allocator, const COOP_PREFERRED: bool> Index for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Output = I::Output; #[inline] @@ -2769,8 +2769,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { message = "vector indices are of type `usize` or ranges of `usize`", label = "vector indices are of type `usize` or ranges of `usize`" )] -impl, A: Allocator> IndexMut for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl, A: Allocator, const COOP_PREFERRED: bool> IndexMut for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { #[inline] fn index_mut(&mut self, index: I) -> &mut Self::Output { IndexMut::index_mut(&mut **self, index) @@ -2787,8 +2787,8 @@ impl FromIterator for Vec { } #[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl IntoIterator for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Item = T; type IntoIter = IntoIter; @@ -2833,8 +2833,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, A: Allocator> IntoIterator for &'a Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl<'a, T, A: Allocator, const COOP_PREFERRED: bool> IntoIterator for &'a Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Item = &'a T; type IntoIter = slice::Iter<'a, T>; @@ -2844,8 +2844,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -impl<'a, T, A: Allocator> IntoIterator for &'a mut Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl<'a, T, A: Allocator, const COOP_PREFERRED: bool> IntoIterator for &'a mut Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Item = &'a mut T; type IntoIter = slice::IterMut<'a, T>; @@ -2856,8 +2856,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] -impl Extend for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl Extend for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { #[inline] fn extend>(&mut self, iter: I) { >::spec_extend(self, iter.into_iter()) @@ -2874,8 +2874,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { } } -impl Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { // leaf method to which various SpecFrom/SpecExtend implementations delegate when // they have no further optimizations to apply #[cfg(not(no_global_oom_handling))] @@ -3049,8 +3049,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { /// [`copy_from_slice`]: slice::copy_from_slice #[cfg(not(no_global_oom_handling))] #[stable(feature = "extend_ref", since = "1.2.0")] -impl<'a, T: Copy + 'a, A: Allocator + 'a> Extend<&'a T> for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl<'a, T: Copy + 'a, A: Allocator + 'a, const COOP_PREFERRED: bool> Extend<&'a T> for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn extend>(&mut self, iter: I) { self.spec_extend(iter.into_iter()) } @@ -3068,8 +3068,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { /// Implements comparison of vectors, [lexicographically](core::cmp::Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl PartialOrd for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { #[inline] fn partial_cmp(&self, other: &Self) -> Option { PartialOrd::partial_cmp(&**self, &**other) @@ -3077,13 +3077,13 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: {} +impl Eq for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: {} /// Implements ordering of vectors, [lexicographically](core::cmp::Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl Ord for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { #[inline] fn cmp(&self, other: &Self) -> Ordering { Ord::cmp(&**self, &**other) @@ -3091,8 +3091,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { } #[stable(feature = "rust1", since = "1.0.0")] -unsafe impl<#[may_dangle] T, A: Allocator> Drop for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +unsafe impl<#[may_dangle] T, A: Allocator, const COOP_PREFERRED: bool> Drop for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn drop(&mut self) { unsafe { // use drop for [T] @@ -3116,40 +3116,40 @@ impl const Default for Vec { } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl fmt::Debug for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { 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 -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl AsRef> for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn as_ref(&self) -> &Vec { self } } #[stable(feature = "vec_as_mut", since = "1.5.0")] -impl AsMut> for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl AsMut> for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn as_mut(&mut self) -> &mut Vec { self } } #[stable(feature = "rust1", since = "1.0.0")] -impl AsRef<[T]> for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl AsRef<[T]> for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn as_ref(&self) -> &[T] { self } } #[stable(feature = "vec_as_mut", since = "1.5.0")] -impl AsMut<[T]> for Vec -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl AsMut<[T]> for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { fn as_mut(&mut self) -> &mut [T] { self } @@ -3246,8 +3246,8 @@ 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 -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl From> for Vec +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Convert a boxed slice into a vector by transferring ownership of /// the existing heap allocation. /// @@ -3266,8 +3266,8 @@ where [(); core::alloc::co_alloc_metadata_num_slots::()]: { #[cfg(not(no_global_oom_handling))] #[cfg(not(test))] #[stable(feature = "box_from_vec", since = "1.20.0")] -impl From> for Box<[T], A> -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl From> for Box<[T], A> +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { /// Convert a vector into a boxed slice. /// /// If `v` has excess capacity, its items will be moved into a @@ -3307,8 +3307,8 @@ impl From<&str> for Vec { } #[stable(feature = "array_try_from_vec", since = "1.48.0")] -impl TryFrom> for [T; N] -where [(); core::alloc::co_alloc_metadata_num_slots::()]: { +impl TryFrom> for [T; N] +where [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: { type Error = Vec; /// Gets the entire contents of the `Vec` as an array, diff --git a/library/alloc/src/vec/partial_eq.rs b/library/alloc/src/vec/partial_eq.rs index b50b9673e1560..bcf52b7333218 100644 --- a/library/alloc/src/vec/partial_eq.rs +++ b/library/alloc/src/vec/partial_eq.rs @@ -6,12 +6,12 @@ use crate::borrow::Cow; use super::Vec; macro_rules! __impl_slice_eq1 { - ([$($vars:tt)*] $lhs:ty, $rhs:ty $(where $ty:ty: $bound:ident)?, #[$stability:meta]) => { + ([$($vars:tt)*] $lhs:ty, $rhs:ty, #[$stability:meta], $($constraints:tt)*) => { #[$stability] impl PartialEq<$rhs> for $lhs where T: PartialEq, - $($ty: $bound)? + $($constraints)* { #[inline] fn eq(&self, other: &$rhs) -> bool { self[..] == other[..] } @@ -21,21 +21,21 @@ macro_rules! __impl_slice_eq1 { } } -__impl_slice_eq1! { [A1: Allocator, A2: Allocator] Vec, Vec, #[stable(feature = "rust1", since = "1.0.0")] } -__impl_slice_eq1! { [A: Allocator] Vec, &[U], #[stable(feature = "rust1", since = "1.0.0")] } -__impl_slice_eq1! { [A: Allocator] Vec, &mut [U], #[stable(feature = "rust1", since = "1.0.0")] } -__impl_slice_eq1! { [A: Allocator] &[T], Vec, #[stable(feature = "partialeq_vec_for_ref_slice", since = "1.46.0")] } -__impl_slice_eq1! { [A: Allocator] &mut [T], Vec, #[stable(feature = "partialeq_vec_for_ref_slice", since = "1.46.0")] } -__impl_slice_eq1! { [A: Allocator] Vec, [U], #[stable(feature = "partialeq_vec_for_slice", since = "1.48.0")] } -__impl_slice_eq1! { [A: Allocator] [T], Vec, #[stable(feature = "partialeq_vec_for_slice", since = "1.48.0")] } +__impl_slice_eq1! { [A1: Allocator, A2: Allocator, const COOP_PREFERRED1: bool, const COOP_PREFERRED2: bool] Vec, Vec, #[stable(feature = "rust1", since = "1.0.0")], [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED1)]:, [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED2)]: } +__impl_slice_eq1! { [A: Allocator, const COOP_PREFERRED: bool] Vec, &[U], #[stable(feature = "rust1", since = "1.0.0")], [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: } +__impl_slice_eq1! { [A: Allocator, const COOP_PREFERRED: bool] Vec, &mut [U], #[stable(feature = "rust1", since = "1.0.0")], [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: } +__impl_slice_eq1! { [A: Allocator, const COOP_PREFERRED: bool] &[T], Vec, #[stable(feature = "partialeq_vec_for_ref_slice", since = "1.46.0")], [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: } +__impl_slice_eq1! { [A: Allocator, const COOP_PREFERRED: bool] &mut [T], Vec, #[stable(feature = "partialeq_vec_for_ref_slice", since = "1.46.0")], [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: } +__impl_slice_eq1! { [A: Allocator, const COOP_PREFERRED: bool] Vec, [U], #[stable(feature = "partialeq_vec_for_slice", since = "1.48.0")], [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: } +__impl_slice_eq1! { [A: Allocator, const COOP_PREFERRED: bool] [T], Vec, #[stable(feature = "partialeq_vec_for_slice", since = "1.48.0")], [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: } #[cfg(not(no_global_oom_handling))] -__impl_slice_eq1! { [A: Allocator] Cow<'_, [T]>, Vec where T: Clone, #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [A: Allocator, const COOP_PREFERRED: bool] Cow<'_, [T]>, Vec, #[stable(feature = "rust1", since = "1.0.0")], T: Clone, [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: } #[cfg(not(no_global_oom_handling))] -__impl_slice_eq1! { [] Cow<'_, [T]>, &[U] where T: Clone, #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [] Cow<'_, [T]>, &[U], #[stable(feature = "rust1", since = "1.0.0")], T: Clone } #[cfg(not(no_global_oom_handling))] -__impl_slice_eq1! { [] Cow<'_, [T]>, &mut [U] where T: Clone, #[stable(feature = "rust1", since = "1.0.0")] } -__impl_slice_eq1! { [A: Allocator, const N: usize] Vec, [U; N], #[stable(feature = "rust1", since = "1.0.0")] } -__impl_slice_eq1! { [A: Allocator, const N: usize] Vec, &[U; N], #[stable(feature = "rust1", since = "1.0.0")] } +__impl_slice_eq1! { [] Cow<'_, [T]>, &mut [U], #[stable(feature = "rust1", since = "1.0.0")], T: Clone } +__impl_slice_eq1! { [A: Allocator, const COOP_PREFERRED: bool, const N: usize] Vec, [U; N], #[stable(feature = "rust1", since = "1.0.0")], [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: } +__impl_slice_eq1! { [A: Allocator, const COOP_PREFERRED: bool, const N: usize] Vec, &[U; N], #[stable(feature = "rust1", since = "1.0.0")], [(); core::alloc::co_alloc_metadata_num_slots_with_preference::(COOP_PREFERRED)]: } // NOTE: some less important impls are omitted to reduce code bloat // FIXME(Centril): Reconsider this? diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index c13975a5e2e39..d49e94402a7ed 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -29,6 +29,7 @@ use crate::ptr::{self, NonNull}; // @TODO Make this target-specific #[unstable(feature = "global_co_alloc_meta", issue = "none")] #[allow(missing_debug_implementations)] +#[derive(Clone, Copy)] pub struct GlobalCoAllocMeta { //pub one: usize, /*pub two: usize, @@ -74,6 +75,9 @@ pub struct SliceAndMeta { pub meta: GlobalCoAllocMeta, } +#[unstable(feature = "global_co_alloc_short_term_pref", issue = "none")] +pub const SHORT_TERM_VEC_PREFERS_COOP: bool = true; + #[unstable(feature = "global_co_alloc_meta", issue = "none")] #[allow(missing_debug_implementations)] pub type SliceAndMetaResult = Result; @@ -83,6 +87,13 @@ pub const fn co_alloc_metadata_num_slots() -> usize { if A::IS_CO_ALLOCATOR { 1 } else { 0 } } +#[unstable(feature = "global_co_alloc", issue = "none")] +/// Param `coop_preferred` - if false, then this returns `0`, regardless of +/// whether allocator `A` is cooperative. +pub const fn co_alloc_metadata_num_slots_with_preference(coop_preferred: bool) -> usize { + if A::IS_CO_ALLOCATOR && coop_preferred { 1 } else { 0 } +} + /// An implementation of `Allocator` can allocate, grow, shrink, and deallocate arbitrary blocks of /// data described via [`Layout`][]. ///