Skip to content

Commit

Permalink
Auto merge of #68529 - TimDiekmann:rename-alloc, r=Amanieu
Browse files Browse the repository at this point in the history
Rename `Alloc` to `AllocRef`

The allocator-wg has decided to merge this change upstream in rust-lang/wg-allocators#8 (comment).

This renames `Alloc` to `AllocRef` because types that implement `Alloc` are a reference, smart pointer, or ZSTs. It is not possible to have an allocator like `MyAlloc([u8; N])`, that owns the memory and also implements `Alloc`, since that would mean, that moving a `Vec<T, MyAlloc>` would need to correct the internal pointer, which is not possible as we don't have move constructors.

For further explanation please see rust-lang/wg-allocators#8 (comment) and the comments after that one.

Additionally it clarifies the semantics of `Clone` on an allocator. In the case of `AllocRef`, it is clear that the cloned handle still points to the same allocator instance, and that you can free data allocated from one handle with another handle.

The initial proposal was to rename `Alloc` to `AllocHandle`, but `Ref` expresses the semantics better than `Handle`. Also, the only appearance of `Handle` in `std` are for windows specific resources, which might be confusing.

Blocked on rust-lang/miri#1160
  • Loading branch information
bors committed Jan 28, 2020
2 parents 8201866 + 7ca25db commit b181835
Show file tree
Hide file tree
Showing 16 changed files with 60 additions and 45 deletions.
Expand Up @@ -9,7 +9,7 @@ The tracking issue for this feature is [#32838]
Sometimes you want the memory for one collection to use a different
allocator than the memory for another collection. In this case,
replacing the global allocator is not a workable option. Instead,
you need to pass in an instance of an `Alloc` to each collection
you need to pass in an instance of an `AllocRef` to each collection
for which you want a custom allocator.

TBD
22 changes: 11 additions & 11 deletions src/liballoc/alloc.rs
Expand Up @@ -31,14 +31,14 @@ extern "Rust" {

/// The global memory allocator.
///
/// This type implements the [`Alloc`] trait by forwarding calls
/// This type implements the [`AllocRef`] trait by forwarding calls
/// to the allocator registered with the `#[global_allocator]` attribute
/// if there is one, or the `std` crate’s default.
///
/// Note: while this type is unstable, the functionality it provides can be
/// accessed through the [free functions in `alloc`](index.html#functions).
///
/// [`Alloc`]: trait.Alloc.html
/// [`AllocRef`]: trait.AllocRef.html
#[unstable(feature = "allocator_api", issue = "32838")]
#[derive(Copy, Clone, Default, Debug)]
pub struct Global;
Expand All @@ -50,14 +50,14 @@ pub struct Global;
/// if there is one, or the `std` crate’s default.
///
/// This function is expected to be deprecated in favor of the `alloc` method
/// of the [`Global`] type when it and the [`Alloc`] trait become stable.
/// of the [`Global`] type when it and the [`AllocRef`] trait become stable.
///
/// # Safety
///
/// See [`GlobalAlloc::alloc`].
///
/// [`Global`]: struct.Global.html
/// [`Alloc`]: trait.Alloc.html
/// [`AllocRef`]: trait.AllocRef.html
/// [`GlobalAlloc::alloc`]: trait.GlobalAlloc.html#tymethod.alloc
///
/// # Examples
Expand Down Expand Up @@ -88,14 +88,14 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 {
/// if there is one, or the `std` crate’s default.
///
/// This function is expected to be deprecated in favor of the `dealloc` method
/// of the [`Global`] type when it and the [`Alloc`] trait become stable.
/// of the [`Global`] type when it and the [`AllocRef`] trait become stable.
///
/// # Safety
///
/// See [`GlobalAlloc::dealloc`].
///
/// [`Global`]: struct.Global.html
/// [`Alloc`]: trait.Alloc.html
/// [`AllocRef`]: trait.AllocRef.html
/// [`GlobalAlloc::dealloc`]: trait.GlobalAlloc.html#tymethod.dealloc
#[stable(feature = "global_alloc", since = "1.28.0")]
#[inline]
Expand All @@ -110,14 +110,14 @@ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) {
/// if there is one, or the `std` crate’s default.
///
/// This function is expected to be deprecated in favor of the `realloc` method
/// of the [`Global`] type when it and the [`Alloc`] trait become stable.
/// of the [`Global`] type when it and the [`AllocRef`] trait become stable.
///
/// # Safety
///
/// See [`GlobalAlloc::realloc`].
///
/// [`Global`]: struct.Global.html
/// [`Alloc`]: trait.Alloc.html
/// [`AllocRef`]: trait.AllocRef.html
/// [`GlobalAlloc::realloc`]: trait.GlobalAlloc.html#method.realloc
#[stable(feature = "global_alloc", since = "1.28.0")]
#[inline]
Expand All @@ -132,14 +132,14 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8
/// if there is one, or the `std` crate’s default.
///
/// This function is expected to be deprecated in favor of the `alloc_zeroed` method
/// of the [`Global`] type when it and the [`Alloc`] trait become stable.
/// of the [`Global`] type when it and the [`AllocRef`] trait become stable.
///
/// # Safety
///
/// See [`GlobalAlloc::alloc_zeroed`].
///
/// [`Global`]: struct.Global.html
/// [`Alloc`]: trait.Alloc.html
/// [`AllocRef`]: trait.AllocRef.html
/// [`GlobalAlloc::alloc_zeroed`]: trait.GlobalAlloc.html#method.alloc_zeroed
///
/// # Examples
Expand All @@ -163,7 +163,7 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
}

#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl Alloc for Global {
unsafe impl AllocRef for Global {
#[inline]
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
NonNull::new(alloc(layout)).ok_or(AllocErr)
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/boxed.rs
Expand Up @@ -145,7 +145,7 @@ use core::ptr::{self, NonNull, Unique};
use core::slice;
use core::task::{Context, Poll};

use crate::alloc::{self, Alloc, Global};
use crate::alloc::{self, AllocRef, Global};
use crate::raw_vec::RawVec;
use crate::str::from_boxed_utf8_unchecked;
use crate::vec::Vec;
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/collections/btree/node.rs
Expand Up @@ -36,7 +36,7 @@ use core::mem::{self, MaybeUninit};
use core::ptr::{self, NonNull, Unique};
use core::slice;

use crate::alloc::{Alloc, Global, Layout};
use crate::alloc::{AllocRef, Global, Layout};
use crate::boxed::Box;

const B: usize = 6;
Expand Down
16 changes: 8 additions & 8 deletions src/liballoc/raw_vec.rs
Expand Up @@ -7,7 +7,7 @@ use core::ops::Drop;
use core::ptr::{self, NonNull, Unique};
use core::slice;

use crate::alloc::{handle_alloc_error, Alloc, AllocErr, Global, Layout};
use crate::alloc::{handle_alloc_error, AllocErr, AllocRef, Global, Layout};
use crate::boxed::Box;
use crate::collections::TryReserveError::{self, *};

Expand Down Expand Up @@ -42,13 +42,13 @@ mod tests;
/// field. This allows zero-sized types to not be special-cased by consumers of
/// this type.
#[allow(missing_debug_implementations)]
pub struct RawVec<T, A: Alloc = Global> {
pub struct RawVec<T, A: AllocRef = Global> {
ptr: Unique<T>,
cap: usize,
a: A,
}

impl<T, A: Alloc> RawVec<T, A> {
impl<T, A: AllocRef> RawVec<T, A> {
/// Like `new`, but parameterized over the choice of allocator for
/// the returned `RawVec`.
pub const fn new_in(a: A) -> Self {
Expand Down Expand Up @@ -147,7 +147,7 @@ impl<T> RawVec<T, Global> {
}
}

impl<T, A: Alloc> RawVec<T, A> {
impl<T, A: AllocRef> RawVec<T, A> {
/// Reconstitutes a `RawVec` from a pointer, capacity, and allocator.
///
/// # Undefined Behavior
Expand Down Expand Up @@ -182,7 +182,7 @@ impl<T> RawVec<T, Global> {
}
}

impl<T, A: Alloc> RawVec<T, A> {
impl<T, A: AllocRef> RawVec<T, A> {
/// Gets a raw pointer to the start of the allocation. Note that this is
/// `Unique::empty()` if `capacity == 0` or `T` is zero-sized. In the former case, you must
/// be careful.
Expand Down Expand Up @@ -622,7 +622,7 @@ enum ReserveStrategy {

use ReserveStrategy::*;

impl<T, A: Alloc> RawVec<T, A> {
impl<T, A: AllocRef> RawVec<T, A> {
fn reserve_internal(
&mut self,
used_capacity: usize,
Expand Down Expand Up @@ -700,7 +700,7 @@ impl<T> RawVec<T, Global> {
}
}

impl<T, A: Alloc> RawVec<T, A> {
impl<T, A: AllocRef> RawVec<T, A> {
/// Frees the memory owned by the `RawVec` *without* trying to drop its contents.
pub unsafe fn dealloc_buffer(&mut self) {
let elem_size = mem::size_of::<T>();
Expand All @@ -712,7 +712,7 @@ impl<T, A: Alloc> RawVec<T, A> {
}
}

unsafe impl<#[may_dangle] T, A: Alloc> Drop for RawVec<T, A> {
unsafe impl<#[may_dangle] T, A: AllocRef> Drop for RawVec<T, A> {
/// Frees the memory owned by the `RawVec` *without* trying to drop its contents.
fn drop(&mut self) {
unsafe {
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/raw_vec/tests.rs
Expand Up @@ -19,7 +19,7 @@ fn allocator_param() {
struct BoundedAlloc {
fuel: usize,
}
unsafe impl Alloc for BoundedAlloc {
unsafe impl AllocRef for BoundedAlloc {
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
let size = layout.size();
if size > self.fuel {
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/rc.rs
Expand Up @@ -252,7 +252,7 @@ use core::ptr::{self, NonNull};
use core::slice::{self, from_raw_parts_mut};
use core::usize;

use crate::alloc::{box_free, handle_alloc_error, Alloc, Global, Layout};
use crate::alloc::{box_free, handle_alloc_error, AllocRef, Global, Layout};
use crate::string::String;
use crate::vec::Vec;

Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/sync.rs
Expand Up @@ -25,7 +25,7 @@ use core::sync::atomic;
use core::sync::atomic::Ordering::{Acquire, Relaxed, Release, SeqCst};
use core::{isize, usize};

use crate::alloc::{box_free, handle_alloc_error, Alloc, Global, Layout};
use crate::alloc::{box_free, handle_alloc_error, AllocRef, Global, Layout};
use crate::boxed::Box;
use crate::rc::is_dangling;
use crate::string::String;
Expand Down
4 changes: 2 additions & 2 deletions src/liballoc/tests/heap.rs
@@ -1,4 +1,4 @@
use std::alloc::{Alloc, Global, Layout, System};
use std::alloc::{AllocRef, Global, Layout, System};

/// Issue #45955 and #62251.
#[test]
Expand All @@ -11,7 +11,7 @@ fn std_heap_overaligned_request() {
check_overalign_requests(Global)
}

fn check_overalign_requests<T: Alloc>(mut allocator: T) {
fn check_overalign_requests<T: AllocRef>(mut allocator: T) {
for &align in &[4, 8, 16, 32] {
// less than and bigger than `MIN_ALIGN`
for &size in &[align / 2, align - 1] {
Expand Down
37 changes: 26 additions & 11 deletions src/libcore/alloc.rs
Expand Up @@ -31,7 +31,7 @@ const fn size_align<T>() -> (usize, usize) {
///
/// (Note however that layouts are *not* required to have positive
/// size, even though many allocators require that all memory
/// requests have positive size. A caller to the `Alloc::alloc`
/// requests have positive size. A caller to the `AllocRef::alloc`
/// method must either ensure that conditions like this are met, or
/// use specific allocators with looser requirements.)
#[stable(feature = "alloc_layout", since = "1.28.0")]
Expand Down Expand Up @@ -364,8 +364,8 @@ impl fmt::Display for AllocErr {
/// [`shrink_in_place`] were unable to reuse the given memory block for
/// a requested layout.
///
/// [`grow_in_place`]: ./trait.Alloc.html#method.grow_in_place
/// [`shrink_in_place`]: ./trait.Alloc.html#method.shrink_in_place
/// [`grow_in_place`]: ./trait.AllocRef.html#method.grow_in_place
/// [`shrink_in_place`]: ./trait.AllocRef.html#method.shrink_in_place
#[unstable(feature = "allocator_api", issue = "32838")]
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct CannotReallocInPlace;
Expand Down Expand Up @@ -580,9 +580,14 @@ pub unsafe trait GlobalAlloc {
}
}

/// An implementation of `Alloc` can allocate, reallocate, and
/// An implementation of `AllocRef` can allocate, reallocate, and
/// deallocate arbitrary blocks of data described via `Layout`.
///
/// `AllocRef` is designed to be implemented on ZSTs, references, or
/// smart pointers because having an allocator like `MyAlloc([u8; N])`
/// cannot be moved, without updating the pointers to the allocated
/// memory.
///
/// Some of the methods require that a memory block be *currently
/// allocated* via an allocator. This means that:
///
Expand All @@ -598,15 +603,15 @@ pub unsafe trait GlobalAlloc {
/// passed to a reallocation method (see above) that returns `Ok`.
///
/// A note regarding zero-sized types and zero-sized layouts: many
/// methods in the `Alloc` trait state that allocation requests
/// methods in the `AllocRef` trait state that allocation requests
/// must be non-zero size, or else undefined behavior can result.
///
/// * However, some higher-level allocation methods (`alloc_one`,
/// `alloc_array`) are well-defined on zero-sized types and can
/// optionally support them: it is left up to the implementor
/// whether to return `Err`, or to return `Ok` with some pointer.
///
/// * If an `Alloc` implementation chooses to return `Ok` in this
/// * If an `AllocRef` implementation chooses to return `Ok` in this
/// case (i.e., the pointer denotes a zero-sized inaccessible block)
/// then that returned pointer must be considered "currently
/// allocated". On such an allocator, *all* methods that take
Expand Down Expand Up @@ -646,21 +651,24 @@ pub unsafe trait GlobalAlloc {
///
/// # Safety
///
/// The `Alloc` trait is an `unsafe` trait for a number of reasons, and
/// The `AllocRef` trait is an `unsafe` trait for a number of reasons, and
/// implementors must ensure that they adhere to these contracts:
///
/// * Pointers returned from allocation functions must point to valid memory and
/// retain their validity until at least the instance of `Alloc` is dropped
/// retain their validity until at least one instance of `AllocRef` is dropped
/// itself.
///
/// * Cloning or moving the allocator must not invalidate pointers returned
/// from this allocator. Cloning must return a reference to the same allocator.
///
/// * `Layout` queries and calculations in general must be correct. Callers of
/// this trait are allowed to rely on the contracts defined on each method,
/// and implementors must ensure such contracts remain true.
///
/// Note that this list may get tweaked over time as clarifications are made in
/// the future.
#[unstable(feature = "allocator_api", issue = "32838")]
pub unsafe trait Alloc {
pub unsafe trait AllocRef {
// (Note: some existing allocators have unspecified but well-defined
// behavior in response to a zero size allocation request ;
// e.g., in C, `malloc` of 0 will either return a null pointer or a
Expand Down Expand Up @@ -1042,7 +1050,7 @@ pub unsafe trait Alloc {
/// must be considered "currently allocated" and must be
/// acceptable input to methods such as `realloc` or `dealloc`,
/// *even if* `T` is a zero-sized type. In other words, if your
/// `Alloc` implementation overrides this method in a manner
/// `AllocRef` implementation overrides this method in a manner
/// that can return a zero-sized `ptr`, then all reallocation and
/// deallocation methods need to be similarly overridden to accept
/// such values as input.
Expand Down Expand Up @@ -1106,7 +1114,7 @@ pub unsafe trait Alloc {
/// must be considered "currently allocated" and must be
/// acceptable input to methods such as `realloc` or `dealloc`,
/// *even if* `T` is a zero-sized type. In other words, if your
/// `Alloc` implementation overrides this method in a manner
/// `AllocRef` implementation overrides this method in a manner
/// that can return a zero-sized `ptr`, then all reallocation and
/// deallocation methods need to be similarly overridden to accept
/// such values as input.
Expand Down Expand Up @@ -1219,3 +1227,10 @@ pub unsafe trait Alloc {
}
}
}

// In order to rename `Alloc` to `AllocRef`, some submoduleshas to be updated as well. The CI fails
// if either of the submodules fails to compile. The submodules have their own CI depending on a
// specific Rust version, which don't have `AllocRef` yet. This alias is used to make the submodules
// compile and pass the CI.
#[unstable(feature = "allocator_api", issue = "32838")]
pub use self::AllocRef as Alloc;
4 changes: 2 additions & 2 deletions src/libstd/alloc.rs
Expand Up @@ -133,9 +133,9 @@ pub use alloc_crate::alloc::*;
#[derive(Debug, Default, Copy, Clone)]
pub struct System;

// The Alloc impl just forwards to the GlobalAlloc impl, which is in `std::sys::*::alloc`.
// The AllocRef impl just forwards to the GlobalAlloc impl, which is in `std::sys::*::alloc`.
#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl Alloc for System {
unsafe impl AllocRef for System {
#[inline]
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
NonNull::new(GlobalAlloc::alloc(self, layout)).ok_or(AllocErr)
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/allocator-alloc-one.rs
Expand Up @@ -4,7 +4,7 @@

#![feature(allocator_api, nonnull)]

use std::alloc::{Alloc, Global, Layout, handle_alloc_error};
use std::alloc::{AllocRef, Global, Layout, handle_alloc_error};

fn main() {
unsafe {
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/allocator/custom.rs
Expand Up @@ -7,7 +7,7 @@

extern crate helper;

use std::alloc::{self, Global, Alloc, System, Layout};
use std::alloc::{self, Global, AllocRef, System, Layout};
use std::sync::atomic::{AtomicUsize, Ordering};

static HITS: AtomicUsize = AtomicUsize::new(0);
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/allocator/xcrate-use.rs
Expand Up @@ -9,7 +9,7 @@
extern crate custom;
extern crate helper;

use std::alloc::{Global, Alloc, System, Layout};
use std::alloc::{Global, AllocRef, System, Layout};
use std::sync::atomic::{Ordering, AtomicUsize};

#[global_allocator]
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/realloc-16687.rs
Expand Up @@ -6,7 +6,7 @@

#![feature(allocator_api)]

use std::alloc::{Global, Alloc, Layout, handle_alloc_error};
use std::alloc::{Global, AllocRef, Layout, handle_alloc_error};
use std::ptr::{self, NonNull};

fn main() {
Expand Down

0 comments on commit b181835

Please sign in to comment.