Skip to content

Commit 20f0301

Browse files
CoAlloc: Vec, related + vec! macro: Separated co-alloc-aware functions to have unique names, so we have no conflicts, but source code backward-compatibility.
1 parent 3528115 commit 20f0301

File tree

6 files changed

+73
-7
lines changed

6 files changed

+73
-7
lines changed

library/alloc/src/macros.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
#[allow_internal_unstable(rustc_attrs, liballoc_internals)]
4242
macro_rules! vec {
4343
() => (
44-
$crate::__rust_force_expr!($crate::vec::Vec::new_co())
44+
$crate::__rust_force_expr!($crate::vec::Vec::new())
4545
);
4646
($elem:expr; $n:expr) => (
4747
$crate::__rust_force_expr!($crate::vec::from_elem($elem, $n))

library/alloc/src/str.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ where
144144
// the first slice is the only one without a separator preceding it
145145
let first = match iter.next() {
146146
Some(first) => first,
147-
None => return vec![],
147+
None => return Vec::new_co(),
148148
};
149149

150150
// compute the exact total length of the joined Vec
@@ -159,7 +159,7 @@ where
159159
.expect("attempt to join into collection with len > usize::MAX");
160160

161161
// prepare an uninitialized buffer
162-
let mut result = Vec::with_capacity(reserved_len);
162+
let mut result = Vec::with_capacity_co(reserved_len);
163163
debug_assert!(result.capacity() >= reserved_len);
164164

165165
result.extend_from_slice(first.borrow().as_ref());

library/alloc/src/vec/mod.rs

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,10 @@ pub type DefVec<T, A = Global> = Vec<T, A, { DEFAULT_COOP_PREFERRED!() }>;
444444
pub type WeVec<T, const WEIGHT: u8> = Vec<T, Global, { WEIGHT > 127 }>;
445445

446446
impl<T> Vec<T> {
447+
/*impl<T, const COOP_PREFERRED: bool> Vec<T, Global, COOP_PREFERRED>
448+
where
449+
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
450+
{*/
447451
/// Constructs a new, empty `Vec<T>`.
448452
///
449453
/// The vector will not allocate until elements are pushed onto it.
@@ -461,13 +465,73 @@ impl<T> Vec<T> {
461465
pub const fn new() -> Self {
462466
#[allow(unused_braces)]
463467
Vec::<T, Global, { DEFAULT_COOP_PREFERRED!() }>::new_co()
468+
//Self::new_co()
469+
}
470+
471+
/// Constructs a new, empty `Vec<T>` with at least the specified capacity.
472+
///
473+
/// The vector will be able to hold at least `capacity` elements without
474+
/// reallocating. This method is allowed to allocate for more elements than
475+
/// `capacity`. If `capacity` is 0, the vector will not allocate.
476+
///
477+
/// It is important to note that although the returned vector has the
478+
/// minimum *capacity* specified, the vector will have a zero *length*. For
479+
/// an explanation of the difference between length and capacity, see
480+
/// *[Capacity and reallocation]*.
481+
///
482+
/// If it is important to know the exact allocated capacity of a `Vec`,
483+
/// always use the [`capacity`] method after construction.
484+
///
485+
/// For `Vec<T>` where `T` is a zero-sized type, there will be no allocation
486+
/// and the capacity will always be `usize::MAX`.
487+
///
488+
/// [Capacity and reallocation]: #capacity-and-reallocation
489+
/// [`capacity`]: Vec::capacity
490+
///
491+
/// # Panics
492+
///
493+
/// Panics if the new capacity exceeds `isize::MAX` bytes.
494+
///
495+
/// # Examples
496+
///
497+
/// ```
498+
/// let mut vec = Vec::with_capacity(10);
499+
///
500+
/// // The vector contains no items, even though it has capacity for more
501+
/// assert_eq!(vec.len(), 0);
502+
/// assert!(vec.capacity() >= 10);
503+
///
504+
/// // These are all done without reallocating...
505+
/// for i in 0..10 {
506+
/// vec.push(i);
507+
/// }
508+
/// assert_eq!(vec.len(), 10);
509+
/// assert!(vec.capacity() >= 10);
510+
///
511+
/// // ...but this may make the vector reallocate
512+
/// vec.push(11);
513+
/// assert_eq!(vec.len(), 11);
514+
/// assert!(vec.capacity() >= 11);
515+
///
516+
/// // A vector of a zero-sized type will always over-allocate, since no
517+
/// // allocation is necessary
518+
/// let vec_units = Vec::<()>::with_capacity(10);
519+
/// assert_eq!(vec_units.capacity(), usize::MAX);
520+
/// ``` #[cfg(not(no_global_oom_handling))]
521+
#[inline]
522+
#[stable(feature = "rust1", since = "1.0.0")]
523+
#[must_use]
524+
pub fn with_capacity(capacity: usize) -> Self {
525+
Self::with_capacity_in(capacity, Global)
464526
}
527+
465528
}
466529

467530
////////////////////////////////////////////////////////////////////////////////
468531
// Inherent methods
469532
////////////////////////////////////////////////////////////////////////////////
470533

534+
/**/
471535
impl<T, const COOP_PREFERRED: bool> Vec<T, Global, COOP_PREFERRED>
472536
where
473537
[(); core::alloc::co_alloc_metadata_num_slots_with_preference::<Global>(COOP_PREFERRED)]:,
@@ -481,6 +545,7 @@ where
481545
Vec { buf: RawVec::NEW, len: 0 }
482546
}
483547

548+
// TODO @FIXME document co-allocation
484549
/// Constructs a new, empty `Vec<T>` with at least the specified capacity.
485550
///
486551
/// The vector will be able to hold at least `capacity` elements without
@@ -533,9 +598,9 @@ where
533598
/// ```
534599
#[cfg(not(no_global_oom_handling))]
535600
#[inline]
536-
#[stable(feature = "rust1", since = "1.0.0")]
601+
#[unstable(feature = "vec_new_co", reason = "confirm_or_fix_the_function_name", issue = "none")]
537602
#[must_use]
538-
pub fn with_capacity(capacity: usize) -> Self {
603+
pub fn with_capacity_co(capacity: usize) -> Self {
539604
Self::with_capacity_in(capacity, Global)
540605
}
541606

library/alloc/src/vec/spec_from_iter_nested.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ where
3434
let (lower, _) = iterator.size_hint();
3535
let initial_capacity =
3636
cmp::max(RawVec::<T>::MIN_NON_ZERO_CAP, lower.saturating_add(1));
37-
let mut vector = Vec::with_capacity(initial_capacity);
37+
let mut vector = Vec::with_capacity_co(initial_capacity);
3838
unsafe {
3939
// SAFETY: We requested capacity at least 1
4040
ptr::write(vector.as_mut_ptr(), element);

library/std/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@
329329
#![feature(try_reserve_kind)]
330330
#![feature(vec_into_raw_parts)]
331331
#![feature(slice_concat_trait)]
332+
#![feature(vec_new_co)]
332333
//
333334
// Library features (unwind):
334335
#![feature(panic_unwind)]

library/std/src/sys_common/thread_local_dtor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub unsafe fn register_dtor_fallback(t: *mut u8, dtor: unsafe extern "C" fn(*mut
3131
static DTORS: StaticKey = StaticKey::new(Some(run_dtors));
3232
type List = PlVec<(*mut u8, unsafe extern "C" fn(*mut u8))>;
3333
if DTORS.get().is_null() {
34-
let v: Box<List> = Box::new(Vec::new());
34+
let v: Box<List> = Box::new(Vec::new_co());
3535
DTORS.set(Box::into_raw(v) as *mut u8);
3636
}
3737
let list: &mut List = &mut *(DTORS.get() as *mut List);

0 commit comments

Comments
 (0)