Skip to content

Commit

Permalink
Auto merge of #78461 - TimDiekmann:vec-alloc, r=Amanieu
Browse files Browse the repository at this point in the history
Add support for custom allocators in `Vec`

This follows the [roadmap](rust-lang/wg-allocators#7) of the allocator WG to add custom allocators to collections.

r? `@Amanieu`

This pull request requires a crater run.

### Prior work:
- #71873: Crater-test to solve rust-lang/wg-allocators#1
- [`alloc-wg`](https://github.com/TimDiekmann/alloc-wg)-crate
  • Loading branch information
bors committed Nov 21, 2020
2 parents da38469 + a600410 commit a1a13b2
Show file tree
Hide file tree
Showing 13 changed files with 504 additions and 206 deletions.
5 changes: 3 additions & 2 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1347,9 +1347,10 @@ impl<I> FromIterator<I> for Box<[I]> {
}

#[stable(feature = "box_slice_clone", since = "1.3.0")]
impl<T: Clone> Clone for Box<[T]> {
impl<T: Clone, A: AllocRef + Clone> 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) {
Expand Down
7 changes: 1 addition & 6 deletions library/alloc/src/raw_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,15 +233,10 @@ impl<T, A: AllocRef> RawVec<T, A> {
}

/// 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<u8>, Layout)> {
if mem::size_of::<T>() == 0 || self.cap == 0 {
None
Expand Down
41 changes: 33 additions & 8 deletions library/alloc/src/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<T>(b: Box<[T]>) -> Vec<T> {
pub fn into_vec<T, A: AllocRef>(b: Box<[T], A>) -> Vec<T, A> {
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<T>(s: &[T]) -> Vec<T>
pub fn to_vec<T, A: AllocRef>(s: &[T], alloc: A) -> Vec<T, A>
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
}
Expand Down Expand Up @@ -388,11 +391,33 @@ impl<T> [T] {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn to_vec(&self) -> Vec<T>
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<A: AllocRef>(&self, alloc: A) -> Vec<T, A>
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.
Expand All @@ -411,7 +436,7 @@ impl<T> [T] {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn into_vec(self: Box<Self>) -> Vec<T> {
pub fn into_vec<A: AllocRef>(self: Box<Self, A>) -> Vec<T, A> {
// N.B., see the `hack` module in this file for more details.
hack::into_vec(self)
}
Expand Down Expand Up @@ -730,7 +755,7 @@ impl<T: Clone> ToOwned for [T] {

#[cfg(test)]
fn to_owned(&self) -> Vec<T> {
hack::to_vec(self)
hack::to_vec(self, Global)
}

fn clone_into(&self, target: &mut Vec<T>) {
Expand Down
Loading

0 comments on commit a1a13b2

Please sign in to comment.