about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTim Diekmann <tim.diekmann@3dvision.de>2020-10-06 16:37:23 +0200
committerTim Diekmann <tim.diekmann@3dvision.de>2020-10-07 03:07:02 +0200
commitf288cd2e179f600fa00c2a407206a12f6c5a91e0 (patch)
tree17d8a9240d44b2e34d96e63c4368778748cee14b
parent59dafb876e125c49fca93820c5ef22da3fcb8644 (diff)
downloadrust-f288cd2e179f600fa00c2a407206a12f6c5a91e0.tar.gz
rust-f288cd2e179f600fa00c2a407206a12f6c5a91e0.zip
Support custom allocators in `Box`
Remove `Box::leak_with_alloc`


Add leak-test for box with allocator


Rename `AllocErr` to `AllocError` in leak-test


Add `Box::alloc` and adjust examples to use the new API
-rw-r--r--library/alloc/src/alloc.rs19
-rw-r--r--library/alloc/src/boxed.rs490
-rw-r--r--library/alloc/src/collections/btree/node.rs2
-rw-r--r--library/alloc/src/raw_vec.rs60
-rw-r--r--library/alloc/src/rc.rs4
-rw-r--r--library/alloc/src/sync.rs4
-rw-r--r--src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff4
-rw-r--r--src/test/ui/box/alloc-unstable-fail.rs6
-rw-r--r--src/test/ui/box/alloc-unstable-fail.stderr12
-rw-r--r--src/test/ui/box/alloc-unstable.rs8
-rw-r--r--src/test/ui/box/into-boxed-slice-fail.rs (renamed from src/test/ui/box-into-boxed-slice-fail.rs)0
-rw-r--r--src/test/ui/box/into-boxed-slice-fail.stderr (renamed from src/test/ui/box-into-boxed-slice-fail.stderr)12
-rw-r--r--src/test/ui/box/into-boxed-slice.rs (renamed from src/test/ui/box-into-boxed-slice.rs)0
-rw-r--r--src/test/ui/box/leak-alloc.rs29
-rw-r--r--src/test/ui/box/leak-alloc.stderr15
-rw-r--r--src/test/ui/box/new.rs (renamed from src/test/ui/box-new.rs)0
-rw-r--r--src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr14
-rw-r--r--src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr3
-rw-r--r--src/test/ui/error-codes/e0119/conflict-with-std.stderr4
-rw-r--r--src/test/ui/issues/issue-14092.rs2
-rw-r--r--src/test/ui/issues/issue-14092.stderr4
-rw-r--r--src/test/ui/issues/issue-3601.stderr4
-rw-r--r--src/test/ui/issues/issue-41974.stderr8
-rw-r--r--src/test/ui/privacy/privacy-ns1.rs2
-rw-r--r--src/test/ui/privacy/privacy-ns1.stderr4
-rw-r--r--src/test/ui/privacy/privacy-ns2.rs4
-rw-r--r--src/test/ui/privacy/privacy-ns2.stderr8
-rw-r--r--src/test/ui/unique-object-noncopyable.stderr35
-rw-r--r--src/test/ui/unique-pinned-nocopy.stderr29
29 files changed, 574 insertions, 212 deletions
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index ce70de6ebdd..4b8300f1862 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -2,8 +2,13 @@
 
 #![stable(feature = "alloc_module", since = "1.28.0")]
 
-use core::intrinsics::{self, min_align_of_val, size_of_val};
-use core::ptr::{self, NonNull, Unique};
+#[cfg(not(test))]
+use core::intrinsics;
+use core::intrinsics::{min_align_of_val, size_of_val};
+
+use core::ptr::Unique;
+#[cfg(not(test))]
+use core::ptr::{self, NonNull};
 
 #[stable(feature = "alloc_module", since = "1.28.0")]
 #[doc(inline)]
@@ -40,8 +45,12 @@ extern "Rust" {
 /// accessed through the [free functions in `alloc`](index.html#functions).
 #[unstable(feature = "allocator_api", issue = "32838")]
 #[derive(Copy, Clone, Default, Debug)]
+#[cfg(not(test))]
 pub struct Global;
 
+#[cfg(test)]
+pub use std::alloc::Global;
+
 /// Allocate memory with the global allocator.
 ///
 /// This function forwards calls to the [`GlobalAlloc::alloc`] method
@@ -145,6 +154,7 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
     unsafe { __rust_alloc_zeroed(layout.size(), layout.align()) }
 }
 
+#[cfg(not(test))]
 impl Global {
     #[inline]
     fn alloc_impl(&self, layout: Layout, zeroed: bool) -> Result<NonNull<[u8]>, AllocError> {
@@ -208,6 +218,7 @@ impl Global {
 }
 
 #[unstable(feature = "allocator_api", issue = "32838")]
+#[cfg(not(test))]
 unsafe impl AllocRef for Global {
     #[inline]
     fn alloc(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
@@ -314,12 +325,12 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
 // well.
 // For example if `Box` is changed to  `struct Box<T: ?Sized, A: AllocRef>(Unique<T>, A)`,
 // this function has to be changed to `fn box_free<T: ?Sized, A: AllocRef>(Unique<T>, A)` as well.
-pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
+pub(crate) unsafe fn box_free<T: ?Sized, A: AllocRef>(ptr: Unique<T>, alloc: A) {
     unsafe {
         let size = size_of_val(ptr.as_ref());
         let align = min_align_of_val(ptr.as_ref());
         let layout = Layout::from_size_align_unchecked(size, align);
-        Global.dealloc(ptr.cast().into(), layout)
+        alloc.dealloc(ptr.cast().into(), layout)
     }
 }
 
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 5c8c2c5a5a8..d6d09b68a61 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -145,7 +145,7 @@ use core::pin::Pin;
 use core::ptr::{self, Unique};
 use core::task::{Context, Poll};
 
-use crate::alloc::{self, AllocRef, Global};
+use crate::alloc::{handle_alloc_error, AllocRef, Global, Layout};
 use crate::borrow::Cow;
 use crate::raw_vec::RawVec;
 use crate::str::from_boxed_utf8_unchecked;
@@ -157,7 +157,10 @@ use crate::vec::Vec;
 #[lang = "owned_box"]
 #[fundamental]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct Box<T: ?Sized>(Unique<T>);
+pub struct Box<
+    T: ?Sized,
+    #[unstable(feature = "allocator_api", issue = "32838")] A: AllocRef = Global,
+>(Unique<T>, A);
 
 impl<T> Box<T> {
     /// Allocates memory on the heap and then places `x` into it.
@@ -171,7 +174,7 @@ impl<T> Box<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline(always)]
-    pub fn new(x: T) -> Box<T> {
+    pub fn new(x: T) -> Self {
         box x
     }
 
@@ -194,10 +197,9 @@ impl<T> Box<T> {
     /// assert_eq!(*five, 5)
     /// ```
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[inline]
     pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
-        let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
-        let ptr = Global.alloc(layout).unwrap_or_else(|_| alloc::handle_alloc_error(layout)).cast();
-        unsafe { Box::from_raw(ptr.as_ptr()) }
+        Self::new_uninit_in(Global)
     }
 
     /// Constructs a new `Box` with uninitialized contents, with the memory
@@ -219,13 +221,9 @@ impl<T> Box<T> {
     ///
     /// [zeroed]: mem::MaybeUninit::zeroed
     #[unstable(feature = "new_uninit", issue = "63291")]
+    #[inline]
     pub fn new_zeroed() -> Box<mem::MaybeUninit<T>> {
-        let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
-        let ptr = Global
-            .alloc_zeroed(layout)
-            .unwrap_or_else(|_| alloc::handle_alloc_error(layout))
-            .cast();
-        unsafe { Box::from_raw(ptr.as_ptr()) }
+        Self::new_zeroed_in(Global)
     }
 
     /// Constructs a new `Pin<Box<T>>`. If `T` does not implement `Unpin`, then
@@ -235,14 +233,103 @@ impl<T> Box<T> {
     pub fn pin(x: T) -> Pin<Box<T>> {
         (box x).into()
     }
+}
+
+impl<T, A: AllocRef> Box<T, A> {
+    /// Allocates memory in the given allocator then places `x` into it.
+    ///
+    /// This doesn't actually allocate if `T` is zero-sized.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(allocator_api)]
+    ///
+    /// use std::alloc::System;
+    ///
+    /// let five = Box::new_in(5, System);
+    /// ```
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline]
+    pub fn new_in(x: T, alloc: A) -> Self {
+        let mut boxed = Self::new_uninit_in(alloc);
+        unsafe {
+            boxed.as_mut_ptr().write(x);
+            boxed.assume_init()
+        }
+    }
+
+    /// Constructs a new box with uninitialized contents in the provided allocator.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(allocator_api, new_uninit)]
+    ///
+    /// use std::alloc::System;
+    ///
+    /// let mut five = Box::<u32, _>::new_uninit_in(System);
+    ///
+    /// let five = unsafe {
+    ///     // Deferred initialization:
+    ///     five.as_mut_ptr().write(5);
+    ///
+    ///     five.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*five, 5)
+    /// ```
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    // #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_uninit_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> {
+        let layout = Layout::new::<mem::MaybeUninit<T>>();
+        let ptr = alloc.alloc(layout).unwrap_or_else(|_| handle_alloc_error(layout)).cast();
+        unsafe { Box::from_raw_in(ptr.as_ptr(), alloc) }
+    }
+
+    /// Constructs a new `Box` with uninitialized contents, with the memory
+    /// being filled with `0` bytes in the provided allocator.
+    ///
+    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
+    /// of this method.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(allocator_api, new_uninit)]
+    ///
+    /// use std::alloc::System;
+    ///
+    /// let zero = Box::<u32, _>::new_zeroed_in(System);
+    /// let zero = unsafe { zero.assume_init() };
+    ///
+    /// assert_eq!(*zero, 0)
+    /// ```
+    ///
+    /// [zeroed]: mem::MaybeUninit::zeroed
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    // #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_zeroed_in(alloc: A) -> Box<mem::MaybeUninit<T>, A> {
+        let layout = Layout::new::<mem::MaybeUninit<T>>();
+        let ptr = alloc.alloc_zeroed(layout).unwrap_or_else(|_| handle_alloc_error(layout)).cast();
+        unsafe { Box::from_raw_in(ptr.as_ptr(), alloc) }
+    }
+
+    /// Constructs a new `Pin<Box<T, A>>`. If `T` does not implement `Unpin`, then
+    /// `x` will be pinned in memory and unable to be moved.
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline(always)]
+    pub fn pin_in(x: T, alloc: A) -> Pin<Self> {
+        Self::new_in(x, alloc).into()
+    }
 
     /// Converts a `Box<T>` into a `Box<[T]>`
     ///
     /// This conversion does not allocate on the heap and happens in place.
     #[unstable(feature = "box_into_boxed_slice", issue = "71582")]
-    pub fn into_boxed_slice(boxed: Box<T>) -> Box<[T]> {
-        // *mut T and *mut [T; 1] have the same size and alignment
-        unsafe { Box::from_raw(Box::into_raw(boxed) as *mut [T; 1]) }
+    pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
+        let (raw, alloc) = Box::into_raw_with_alloc(boxed);
+        unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) }
     }
 }
 
@@ -296,8 +383,64 @@ impl<T> Box<[T]> {
     }
 }
 
-impl<T> Box<mem::MaybeUninit<T>> {
-    /// Converts to `Box<T>`.
+impl<T, A: AllocRef> Box<[T], A> {
+    /// Constructs a new boxed slice with uninitialized contents in the provided allocator.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(allocator_api, new_uninit)]
+    ///
+    /// use std::alloc::System;
+    ///
+    /// let mut values = Box::<[u32], _>::new_uninit_slice_in(3, System);
+    ///
+    /// let values = unsafe {
+    ///     // Deferred initialization:
+    ///     values[0].as_mut_ptr().write(1);
+    ///     values[1].as_mut_ptr().write(2);
+    ///     values[2].as_mut_ptr().write(3);
+    ///
+    ///     values.assume_init()
+    /// };
+    ///
+    /// assert_eq!(*values, [1, 2, 3])
+    /// ```
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    // #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_uninit_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit<T>], A> {
+        unsafe { RawVec::with_capacity_in(len, alloc).into_box(len) }
+    }
+
+    /// Constructs a new boxed slice with uninitialized contents in the provided allocator,
+    /// with the memory being filled with `0` bytes.
+    ///
+    /// See [`MaybeUninit::zeroed`][zeroed] for examples of correct and incorrect usage
+    /// of this method.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(allocator_api, new_uninit)]
+    ///
+    /// use std::alloc::System;
+    ///
+    /// let values = Box::<[u32], _>::new_zeroed_slice_in(3, System);
+    /// let values = unsafe { values.assume_init() };
+    ///
+    /// assert_eq!(*values, [0, 0, 0])
+    /// ```
+    ///
+    /// [zeroed]: mem::MaybeUninit::zeroed
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    // #[unstable(feature = "new_uninit", issue = "63291")]
+    pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit<T>], A> {
+        unsafe { RawVec::with_capacity_zeroed_in(len, alloc).into_box(len) }
+    }
+}
+
+impl<T, A: AllocRef> Box<mem::MaybeUninit<T>, A> {
+    /// Converts to `Box<T, A>`.
     ///
     /// # Safety
     ///
@@ -327,13 +470,14 @@ impl<T> Box<mem::MaybeUninit<T>> {
     /// ```
     #[unstable(feature = "new_uninit", issue = "63291")]
     #[inline]
-    pub unsafe fn assume_init(self) -> Box<T> {
-        unsafe { Box::from_raw(Box::into_raw(self) as *mut T) }
+    pub unsafe fn assume_init(self) -> Box<T, A> {
+        let (raw, alloc) = Box::into_raw_with_alloc(self);
+        unsafe { Box::from_raw_in(raw as *mut T, alloc) }
     }
 }
 
-impl<T> Box<[mem::MaybeUninit<T>]> {
-    /// Converts to `Box<[T]>`.
+impl<T, A: AllocRef> Box<[mem::MaybeUninit<T>], A> {
+    /// Converts to `Box<[T], A>`.
     ///
     /// # Safety
     ///
@@ -365,8 +509,9 @@ impl<T> Box<[mem::MaybeUninit<T>]> {
     /// ```
     #[unstable(feature = "new_uninit", issue = "63291")]
     #[inline]
-    pub unsafe fn assume_init(self) -> Box<[T]> {
-        unsafe { Box::from_raw(Box::into_raw(self) as *mut [T]) }
+    pub unsafe fn assume_init(self) -> Box<[T], A> {
+        let (raw, alloc) = Box::into_raw_with_alloc(self);
+        unsafe { Box::from_raw_in(raw as *mut [T], alloc) }
     }
 }
 
@@ -412,7 +557,62 @@ impl<T: ?Sized> Box<T> {
     #[stable(feature = "box_raw", since = "1.4.0")]
     #[inline]
     pub unsafe fn from_raw(raw: *mut T) -> Self {
-        Box(unsafe { Unique::new_unchecked(raw) })
+        unsafe { Self::from_raw_in(raw, Global) }
+    }
+}
+
+impl<T: ?Sized, A: AllocRef> Box<T, A> {
+    /// Constructs a box from a raw pointer in the given allocator.
+    ///
+    /// After calling this function, the raw pointer is owned by the
+    /// resulting `Box`. Specifically, the `Box` destructor will call
+    /// the destructor of `T` and free the allocated memory. For this
+    /// to be safe, the memory must have been allocated in accordance
+    /// with the [memory layout] used by `Box` .
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe because improper use may lead to
+    /// memory problems. For example, a double-free may occur if the
+    /// function is called twice on the same raw pointer.
+    ///
+    ///
+    /// # Examples
+    ///
+    /// Recreate a `Box` which was previously converted to a raw pointer
+    /// using [`Box::into_raw_with_alloc`]:
+    /// ```
+    /// #![feature(allocator_api)]
+    ///
+    /// use std::alloc::System;
+    ///
+    /// let x = Box::new_in(5, System);
+    /// let (ptr, alloc) = Box::into_raw_with_alloc(x);
+    /// let x = unsafe { Box::from_raw_in(ptr, alloc) };
+    /// ```
+    /// Manually create a `Box` from scratch by using the system allocator:
+    /// ```
+    /// #![feature(allocator_api, slice_ptr_get)]
+    ///
+    /// use std::alloc::{AllocRef, Layout, System};
+    ///
+    /// unsafe {
+    ///     let ptr = System.alloc(Layout::new::<i32>())?.as_mut_ptr();
+    ///     // In general .write is required to avoid attempting to destruct
+    ///     // the (uninitialized) previous contents of `ptr`, though for this
+    ///     // simple example `*ptr = 5` would have worked as well.
+    ///     ptr.write(5);
+    ///     let x = Box::from_raw_in(ptr, System);
+    /// }
+    /// # Ok::<(), std::alloc::AllocError>(())
+    /// ```
+    ///
+    /// [memory layout]: self#memory-layout
+    /// [`Layout`]: crate::Layout
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline]
+    pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
+        Box(unsafe { Unique::new_unchecked(raw) }, alloc)
     }
 
     /// Consumes the `Box`, returning a wrapped raw pointer.
@@ -456,13 +656,61 @@ impl<T: ?Sized> Box<T> {
     /// [memory layout]: self#memory-layout
     #[stable(feature = "box_raw", since = "1.4.0")]
     #[inline]
-    pub fn into_raw(b: Box<T>) -> *mut T {
-        // Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
-        // raw pointer for the type system. Turning it directly into a raw pointer would not be
-        // recognized as "releasing" the unique pointer to permit aliased raw accesses,
-        // so all raw pointer methods go through `leak` which creates a (unique)
-        // mutable reference. Turning *that* to a raw pointer behaves correctly.
-        Box::leak(b) as *mut T
+    pub fn into_raw(b: Self) -> *mut T {
+        Self::into_raw_with_alloc(b).0
+    }
+
+    /// Consumes the `Box`, returning a wrapped raw pointer and the allocator.
+    ///
+    /// The pointer will be properly aligned and non-null.
+    ///
+    /// After calling this function, the caller is responsible for the
+    /// memory previously managed by the `Box`. In particular, the
+    /// caller should properly destroy `T` and release the memory, taking
+    /// into account the [memory layout] used by `Box`. The easiest way to
+    /// do this is to convert the raw pointer back into a `Box` with the
+    /// [`Box::from_raw_in`] function, allowing the `Box` destructor to perform
+    /// the cleanup.
+    ///
+    /// Note: this is an associated function, which means that you have
+    /// to call it as `Box::into_raw_with_alloc(b)` instead of `b.into_raw_with_alloc()`. This
+    /// is so that there is no conflict with a method on the inner type.
+    ///
+    /// # Examples
+    /// Converting the raw pointer back into a `Box` with [`Box::from_raw_in`]
+    /// for automatic cleanup:
+    /// ```
+    /// #![feature(allocator_api)]
+    ///
+    /// use std::alloc::System;
+    ///
+    /// let x = Box::new_in(String::from("Hello"), System);
+    /// let (ptr, alloc) = Box::into_raw_with_alloc(x);
+    /// let x = unsafe { Box::from_raw_in(ptr, alloc) };
+    /// ```
+    /// Manual cleanup by explicitly running the destructor and deallocating
+    /// the memory:
+    /// ```
+    /// #![feature(allocator_api)]
+    ///
+    /// use std::alloc::{AllocRef, Layout, System};
+    /// use std::ptr::{self, NonNull};
+    ///
+    /// let x = Box::new_in(String::from("Hello"), System);
+    /// let (ptr, alloc) = Box::into_raw_with_alloc(x);
+    /// unsafe {
+    ///     ptr::drop_in_place(ptr);
+    ///     let non_null = NonNull::new_unchecked(ptr);
+    ///     alloc.dealloc(non_null.cast(), Layout::new::<String>());
+    /// }
+    /// ```
+    ///
+    /// [memory layout]: self#memory-layout
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline]
+    pub fn into_raw_with_alloc(b: Self) -> (*mut T, A) {
+        let (leaked, alloc) = Box::into_unique(b);
+        (leaked.as_ptr(), alloc)
     }
 
     #[unstable(
@@ -472,13 +720,30 @@ impl<T: ?Sized> Box<T> {
     )]
     #[inline]
     #[doc(hidden)]
-    pub fn into_unique(b: Box<T>) -> Unique<T> {
+    pub fn into_unique(b: Self) -> (Unique<T>, A) {
         // Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
         // raw pointer for the type system. Turning it directly into a raw pointer would not be
         // recognized as "releasing" the unique pointer to permit aliased raw accesses,
-        // so all raw pointer methods go through `leak` which creates a (unique)
-        // mutable reference. Turning *that* to a raw pointer behaves correctly.
-        Box::leak(b).into()
+        // so all raw pointer methods have to leak the box. Turning *that* to a raw pointer
+        // behaves correctly.
+        let b = mem::ManuallyDrop::new(b);
+
+        // The box is unitiliazed later when moving out the allocator. The pointer is stored
+        // beforehand.
+        let ptr = b.0;
+        let alloc = unsafe { ptr::read(&b.1) };
+        (ptr, alloc)
+    }
+
+    /// Returns a reference to the underlying allocator.
+    ///
+    /// Note: this is an associated function, which means that you have
+    /// to call it as `Box::alloc(&b)` instead of `b.alloc()`. This
+    /// is so that there is no conflict with a method on the inner type.
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    #[inline]
+    pub fn alloc(b: &Self) -> &A {
+        &b.1
     }
 
     /// Consumes and leaks the `Box`, returning a mutable reference,
@@ -518,9 +783,9 @@ impl<T: ?Sized> Box<T> {
     /// ```
     #[stable(feature = "box_leak", since = "1.26.0")]
     #[inline]
-    pub fn leak<'a>(b: Box<T>) -> &'a mut T
+    pub fn leak<'a>(b: Self) -> &'a mut T
     where
-        T: 'a, // Technically not needed, but kept to be explicit.
+        A: 'a,
     {
         unsafe { &mut *mem::ManuallyDrop::new(b).0.as_ptr() }
     }
@@ -531,7 +796,7 @@ impl<T: ?Sized> Box<T> {
     ///
     /// This is also available via [`From`].
     #[unstable(feature = "box_into_pin", issue = "62370")]
-    pub fn into_pin(boxed: Box<T>) -> Pin<Box<T>> {
+    pub fn into_pin(boxed: Self) -> Pin<Self> {
         // It's not possible to move or replace the insides of a `Pin<Box<T>>`
         // when `T: !Unpin`,  so it's safe to pin it directly without any
         // additional requirements.
@@ -540,7 +805,7 @@ impl<T: ?Sized> Box<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<#[may_dangle] T: ?Sized> Drop for Box<T> {
+unsafe impl<#[may_dangle] T: ?Sized, A: AllocRef> Drop for Box<T, A> {
     fn drop(&mut self) {
         // FIXME: Do nothing, drop is currently performed by compiler.
     }
@@ -549,27 +814,27 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Box<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Default> Default for Box<T> {
     /// Creates a `Box<T>`, with the `Default` value for T.
-    fn default() -> Box<T> {
-        box Default::default()
+    fn default() -> Self {
+        box T::default()
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Default for Box<[T]> {
-    fn default() -> Box<[T]> {
+    fn default() -> Self {
         Box::<[T; 0]>::new([])
     }
 }
 
 #[stable(feature = "default_box_extra", since = "1.17.0")]
 impl Default for Box<str> {
-    fn default() -> Box<str> {
+    fn default() -> Self {
         unsafe { from_boxed_utf8_unchecked(Default::default()) }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Clone> Clone for Box<T> {
+impl<T: Clone, A: AllocRef + Clone> Clone for Box<T, A> {
     /// Returns a new box with a `clone()` of this box's contents.
     ///
     /// # Examples
@@ -586,8 +851,8 @@ impl<T: Clone> Clone for Box<T> {
     /// ```
     #[rustfmt::skip]
     #[inline]
-    fn clone(&self) -> Box<T> {
-        box { (**self).clone() }
+    fn clone(&self) -> Self {
+        Self::new_in((**self).clone(), self.1.clone())
     }
 
     /// Copies `source`'s contents into `self` without creating a new allocation.
@@ -608,7 +873,7 @@ impl<T: Clone> Clone for Box<T> {
     /// assert_eq!(yp, &*y);
     /// ```
     #[inline]
-    fn clone_from(&mut self, source: &Box<T>) {
+    fn clone_from(&mut self, source: &Self) {
         (**self).clone_from(&(**source));
     }
 }
@@ -623,58 +888,58 @@ impl Clone for Box<str> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized + PartialEq> PartialEq for Box<T> {
+impl<T: ?Sized + PartialEq, A: AllocRef> PartialEq for Box<T, A> {
     #[inline]
-    fn eq(&self, other: &Box<T>) -> bool {
+    fn eq(&self, other: &Self) -> bool {
         PartialEq::eq(&**self, &**other)
     }
     #[inline]
-    fn ne(&self, other: &Box<T>) -> bool {
+    fn ne(&self, other: &Self) -> bool {
         PartialEq::ne(&**self, &**other)
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized + PartialOrd> PartialOrd for Box<T> {
+impl<T: ?Sized + PartialOrd, A: AllocRef> PartialOrd for Box<T, A> {
     #[inline]
-    fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
         PartialOrd::partial_cmp(&**self, &**other)
     }
     #[inline]
-    fn lt(&self, other: &Box<T>) -> bool {
+    fn lt(&self, other: &Self) -> bool {
         PartialOrd::lt(&**self, &**other)
     }
     #[inline]
-    fn le(&self, other: &Box<T>) -> bool {
+    fn le(&self, other: &Self) -> bool {
         PartialOrd::le(&**self, &**other)
     }
     #[inline]
-    fn ge(&self, other: &Box<T>) -> bool {
+    fn ge(&self, other: &Self) -> bool {
         PartialOrd::ge(&**self, &**other)
     }
     #[inline]
-    fn gt(&self, other: &Box<T>) -> bool {
+    fn gt(&self, other: &Self) -> bool {
         PartialOrd::gt(&**self, &**other)
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized + Ord> Ord for Box<T> {
+impl<T: ?Sized + Ord, A: AllocRef> Ord for Box<T, A> {
     #[inline]
-    fn cmp(&self, other: &Box<T>) -> Ordering {
+    fn cmp(&self, other: &Self) -> Ordering {
         Ord::cmp(&**self, &**other)
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized + Eq> Eq for Box<T> {}
+impl<T: ?Sized + Eq, A: AllocRef> Eq for Box<T, A> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized + Hash> Hash for Box<T> {
+impl<T: ?Sized + Hash, A: AllocRef> Hash for Box<T, A> {
     fn hash<H: Hasher>(&self, state: &mut H) {
         (**self).hash(state);
     }
 }
 
 #[stable(feature = "indirect_hasher_impl", since = "1.22.0")]
-impl<T: ?Sized + Hasher> Hasher for Box<T> {
+impl<T: ?Sized + Hasher, A: AllocRef> Hasher for Box<T, A> {
     fn finish(&self) -> u64 {
         (**self).finish()
     }
@@ -739,11 +1004,11 @@ impl<T> From<T> for Box<T> {
 }
 
 #[stable(feature = "pin", since = "1.33.0")]
-impl<T: ?Sized> From<Box<T>> for Pin<Box<T>> {
+impl<T: ?Sized, A: AllocRef> From<Box<T, A>> for Pin<Box<T, A>> {
     /// Converts a `Box<T>` into a `Pin<Box<T>>`
     ///
     /// This conversion does not allocate on the heap and happens in place.
-    fn from(boxed: Box<T>) -> Self {
+    fn from(boxed: Box<T, A>) -> Self {
         Box::into_pin(boxed)
     }
 }
@@ -814,7 +1079,7 @@ impl From<Cow<'_, str>> for Box<str> {
 }
 
 #[stable(feature = "boxed_str_conv", since = "1.19.0")]
-impl From<Box<str>> for Box<[u8]> {
+impl<A: AllocRef> From<Box<str, A>> for Box<[u8], A> {
     /// Converts a `Box<str>>` into a `Box<[u8]>`
     ///
     /// This conversion does not allocate on the heap and happens in place.
@@ -832,8 +1097,9 @@ impl From<Box<str>> for Box<[u8]> {
     /// assert_eq!(boxed_slice, boxed_str);
     /// ```
     #[inline]
-    fn from(s: Box<str>) -> Self {
-        unsafe { Box::from_raw(Box::into_raw(s) as *mut [u8]) }
+    fn from(s: Box<str, A>) -> Self {
+        let (raw, alloc) = Box::into_raw_with_alloc(s);
+        unsafe { Box::from_raw_in(raw as *mut [u8], alloc) }
     }
 }
 
@@ -866,7 +1132,7 @@ impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
     }
 }
 
-impl Box<dyn Any> {
+impl<A: AllocRef> Box<dyn Any, A> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     /// Attempt to downcast the box to a concrete type.
@@ -886,11 +1152,11 @@ impl Box<dyn Any> {
     /// print_if_string(Box::new(my_string));
     /// print_if_string(Box::new(0i8));
     /// ```
-    pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<dyn Any>> {
+    pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
         if self.is::<T>() {
             unsafe {
-                let raw: *mut dyn Any = Box::into_raw(self);
-                Ok(Box::from_raw(raw as *mut T))
+                let (raw, alloc): (*mut dyn Any, _) = Box::into_raw_with_alloc(self);
+                Ok(Box::from_raw_in(raw as *mut T, alloc))
             }
         } else {
             Err(self)
@@ -898,7 +1164,7 @@ impl Box<dyn Any> {
     }
 }
 
-impl Box<dyn Any + Send> {
+impl<A: AllocRef> Box<dyn Any + Send, A> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     /// Attempt to downcast the box to a concrete type.
@@ -918,30 +1184,34 @@ impl Box<dyn Any + Send> {
     /// print_if_string(Box::new(my_string));
     /// print_if_string(Box::new(0i8));
     /// ```
-    pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<dyn Any + Send>> {
-        <Box<dyn Any>>::downcast(self).map_err(|s| unsafe {
-            // reapply the Send marker
-            Box::from_raw(Box::into_raw(s) as *mut (dyn Any + Send))
-        })
+    pub fn downcast<T: Any>(self) -> Result<Box<T, A>, Self> {
+        if self.is::<T>() {
+            unsafe {
+                let (raw, alloc): (*mut (dyn Any + Send), _) = Box::into_raw_with_alloc(self);
+                Ok(Box::from_raw_in(raw as *mut T, alloc))
+            }
+        } else {
+            Err(self)
+        }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: fmt::Display + ?Sized> fmt::Display for Box<T> {
+impl<T: fmt::Display + ?Sized, A: AllocRef> fmt::Display for Box<T, A> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Display::fmt(&**self, f)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: fmt::Debug + ?Sized> fmt::Debug for Box<T> {
+impl<T: fmt::Debug + ?Sized, A: AllocRef> fmt::Debug for Box<T, A> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         fmt::Debug::fmt(&**self, f)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized> fmt::Pointer for Box<T> {
+impl<T: ?Sized, A: AllocRef> fmt::Pointer for Box<T, A> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         // It's not possible to extract the inner Uniq directly from the Box,
         // instead we cast it to a *const which aliases the Unique
@@ -951,7 +1221,7 @@ impl<T: ?Sized> fmt::Pointer for Box<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized> Deref for Box<T> {
+impl<T: ?Sized, A: AllocRef> Deref for Box<T, A> {
     type Target = T;
 
     fn deref(&self) -> &T {
@@ -960,17 +1230,17 @@ impl<T: ?Sized> Deref for Box<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: ?Sized> DerefMut for Box<T> {
+impl<T: ?Sized, A: AllocRef> DerefMut for Box<T, A> {
     fn deref_mut(&mut self) -> &mut T {
         &mut **self
     }
 }
 
 #[unstable(feature = "receiver_trait", issue = "none")]
-impl<T: ?Sized> Receiver for Box<T> {}
+impl<T: ?Sized, A: AllocRef> Receiver for Box<T, A> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator + ?Sized> Iterator for Box<I> {
+impl<I: Iterator + ?Sized, A: AllocRef> Iterator for Box<I, A> {
     type Item = I::Item;
     fn next(&mut self) -> Option<I::Item> {
         (**self).next()
@@ -991,7 +1261,7 @@ trait BoxIter {
     fn last(self) -> Option<Self::Item>;
 }
 
-impl<I: Iterator + ?Sized> BoxIter for Box<I> {
+impl<I: Iterator + ?Sized, A: AllocRef> BoxIter for Box<I, A> {
     type Item = I::Item;
     default fn last(self) -> Option<I::Item> {
         #[inline]
@@ -1006,14 +1276,14 @@ impl<I: Iterator + ?Sized> BoxIter for Box<I> {
 /// Specialization for sized `I`s that uses `I`s implementation of `last()`
 /// instead of the default.
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: Iterator> BoxIter for Box<I> {
+impl<I: Iterator, A: AllocRef> BoxIter for Box<I, A> {
     fn last(self) -> Option<I::Item> {
         (*self).last()
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
+impl<I: DoubleEndedIterator + ?Sized, A: AllocRef> DoubleEndedIterator for Box<I, A> {
     fn next_back(&mut self) -> Option<I::Item> {
         (**self).next_back()
     }
@@ -1022,7 +1292,7 @@ impl<I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for Box<I> {
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {
+impl<I: ExactSizeIterator + ?Sized, A: AllocRef> ExactSizeIterator for Box<I, A> {
     fn len(&self) -> usize {
         (**self).len()
     }
@@ -1032,40 +1302,40 @@ impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {
 }
 
 #[stable(feature = "fused", since = "1.26.0")]
-impl<I: FusedIterator + ?Sized> FusedIterator for Box<I> {}
+impl<I: FusedIterator + ?Sized, A: AllocRef> FusedIterator for Box<I, A> {}
 
 #[stable(feature = "boxed_closure_impls", since = "1.35.0")]
-impl<A, F: FnOnce<A> + ?Sized> FnOnce<A> for Box<F> {
-    type Output = <F as FnOnce<A>>::Output;
+impl<Args, F: FnOnce<Args> + ?Sized, A: AllocRef> FnOnce<Args> for Box<F, A> {
+    type Output = <F as FnOnce<Args>>::Output;
 
-    extern "rust-call" fn call_once(self, args: A) -> Self::Output {
-        <F as FnOnce<A>>::call_once(*self, args)
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output {
+        <F as FnOnce<Args>>::call_once(*self, args)
     }
 }
 
 #[stable(feature = "boxed_closure_impls", since = "1.35.0")]
-impl<A, F: FnMut<A> + ?Sized> FnMut<A> for Box<F> {
-    extern "rust-call" fn call_mut(&mut self, args: A) -> Self::Output {
-        <F as FnMut<A>>::call_mut(self, args)
+impl<Args, F: FnMut<Args> + ?Sized, A: AllocRef> FnMut<Args> for Box<F, A> {
+    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output {
+        <F as FnMut<Args>>::call_mut(self, args)
     }
 }
 
 #[stable(feature = "boxed_closure_impls", since = "1.35.0")]
-impl<A, F: Fn<A> + ?Sized> Fn<A> for Box<F> {
-    extern "rust-call" fn call(&self, args: A) -> Self::Output {
-        <F as Fn<A>>::call(self, args)
+impl<Args, F: Fn<Args> + ?Sized, A: AllocRef> Fn<Args> for Box<F, A> {
+    extern "rust-call" fn call(&self, args: Args) -> Self::Output {
+        <F as Fn<Args>>::call(self, args)
     }
 }
 
 #[unstable(feature = "coerce_unsized", issue = "27732")]
-impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}
+impl<T: ?Sized + Unsize<U>, U: ?Sized, A: AllocRef> CoerceUnsized<Box<U, A>> for Box<T, A> {}
 
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
-impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U>> for Box<T> {}
+impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U>> for Box<T, Global> {}
 
 #[stable(feature = "boxed_slice_from_iter", since = "1.32.0")]
-impl<A> FromIterator<A> for Box<[A]> {
-    fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
+impl<I> FromIterator<I> for Box<[I]> {
+    fn from_iter<T: IntoIterator<Item = I>>(iter: T) -> Self {
         iter.into_iter().collect::<Vec<_>>().into_boxed_slice()
     }
 }
@@ -1086,28 +1356,28 @@ impl<T: Clone> Clone for Box<[T]> {
 }
 
 #[stable(feature = "box_borrow", since = "1.1.0")]
-impl<T: ?Sized> borrow::Borrow<T> for Box<T> {
+impl<T: ?Sized, A: AllocRef> borrow::Borrow<T> for Box<T, A> {
     fn borrow(&self) -> &T {
         &**self
     }
 }
 
 #[stable(feature = "box_borrow", since = "1.1.0")]
-impl<T: ?Sized> borrow::BorrowMut<T> for Box<T> {
+impl<T: ?Sized, A: AllocRef> borrow::BorrowMut<T> for Box<T, A> {
     fn borrow_mut(&mut self) -> &mut T {
         &mut **self
     }
 }
 
 #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
-impl<T: ?Sized> AsRef<T> for Box<T> {
+impl<T: ?Sized, A: AllocRef> AsRef<T> for Box<T, A> {
     fn as_ref(&self) -> &T {
         &**self
     }
 }
 
 #[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
-impl<T: ?Sized> AsMut<T> for Box<T> {
+impl<T: ?Sized, A: AllocRef> AsMut<T> for Box<T, A> {
     fn as_mut(&mut self) -> &mut T {
         &mut **self
     }
@@ -1136,10 +1406,10 @@ impl<T: ?Sized> AsMut<T> for Box<T> {
  *  could have a method to project a Pin<T> from it.
  */
 #[stable(feature = "pin", since = "1.33.0")]
-impl<T: ?Sized> Unpin for Box<T> {}
+impl<T: ?Sized, A: AllocRef> Unpin for Box<T, A> {}
 
 #[unstable(feature = "generator_trait", issue = "43122")]
-impl<G: ?Sized + Generator<R> + Unpin, R> Generator<R> for Box<G> {
+impl<G: ?Sized + Generator<R> + Unpin, R, A: AllocRef> Generator<R> for Box<G, A> {
     type Yield = G::Yield;
     type Return = G::Return;
 
@@ -1149,7 +1419,7 @@ impl<G: ?Sized + Generator<R> + Unpin, R> Generator<R> for Box<G> {
 }
 
 #[unstable(feature = "generator_trait", issue = "43122")]
-impl<G: ?Sized + Generator<R>, R> Generator<R> for Pin<Box<G>> {
+impl<G: ?Sized + Generator<R>, R, A: AllocRef> Generator<R> for Pin<Box<G, A>> {
     type Yield = G::Yield;
     type Return = G::Return;
 
@@ -1159,7 +1429,7 @@ impl<G: ?Sized + Generator<R>, R> Generator<R> for Pin<Box<G>> {
 }
 
 #[stable(feature = "futures_api", since = "1.36.0")]
-impl<F: ?Sized + Future + Unpin> Future for Box<F> {
+impl<F: ?Sized + Future + Unpin, A: AllocRef> Future for Box<F, A> {
     type Output = F::Output;
 
     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs
index 880627e94c3..626521c2c3c 100644
--- a/library/alloc/src/collections/btree/node.rs
+++ b/library/alloc/src/collections/btree/node.rs
@@ -121,7 +121,7 @@ struct BoxedNode<K, V> {
 
 impl<K, V> BoxedNode<K, V> {
     fn from_leaf(node: Box<LeafNode<K, V>>) -> Self {
-        BoxedNode { ptr: Box::into_unique(node) }
+        BoxedNode { ptr: Box::into_unique(node).0 }
     }
 
     fn from_internal(node: Box<InternalNode<K, V>>) -> Self {
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index 1844d3ae004..a60e676fda5 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -6,7 +6,7 @@ use core::cmp;
 use core::intrinsics;
 use core::mem::{self, ManuallyDrop, MaybeUninit};
 use core::ops::Drop;
-use core::ptr::{NonNull, Unique};
+use core::ptr::{self, NonNull, Unique};
 use core::slice;
 
 use crate::alloc::{handle_alloc_error, AllocRef, Global, Layout};
@@ -111,12 +111,36 @@ impl<T> RawVec<T, Global> {
     pub unsafe fn from_raw_parts(ptr: *mut T, capacity: usize) -> Self {
         unsafe { Self::from_raw_parts_in(ptr, capacity, Global) }
     }
+}
+
+impl<T, A: AllocRef> RawVec<T, A> {
+    /// Like `new`, but parameterized over the choice of allocator for
+    /// the returned `RawVec`.
+    #[allow_internal_unstable(const_fn)]
+    pub const fn new_in(alloc: A) -> Self {
+        // `cap: 0` means "unallocated". zero-sized types are ignored.
+        Self { ptr: Unique::dangling(), cap: 0, alloc }
+    }
+
+    /// Like `with_capacity`, but parameterized over the choice of
+    /// allocator for the returned `RawVec`.
+    #[inline]
+    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
+        Self::allocate_in(capacity, AllocInit::Uninitialized, alloc)
+    }
+
+    /// Like `with_capacity_zeroed`, but parameterized over the choice
+    /// of allocator for the returned `RawVec`.
+    #[inline]
+    pub fn with_capacity_zeroed_in(capacity: usize, alloc: A) -> Self {
+        Self::allocate_in(capacity, AllocInit::Zeroed, alloc)
+    }
 
     /// Converts a `Box<[T]>` into a `RawVec<T>`.
-    pub fn from_box(slice: Box<[T]>) -> Self {
+    pub fn from_box(slice: Box<[T], A>) -> Self {
         unsafe {
-            let mut slice = ManuallyDrop::new(slice);
-            RawVec::from_raw_parts(slice.as_mut_ptr(), slice.len())
+            let (slice, alloc) = Box::into_raw_with_alloc(slice);
+            RawVec::from_raw_parts_in(slice.as_mut_ptr(), slice.len(), alloc)
         }
     }
 
@@ -132,7 +156,7 @@ impl<T> RawVec<T, Global> {
     ///
     /// Note, that the requested capacity and `self.capacity()` could differ, as
     /// an allocator could overallocate and return a greater memory block than requested.
-    pub unsafe fn into_box(self, len: usize) -> Box<[MaybeUninit<T>]> {
+    pub unsafe fn into_box(self, len: usize) -> Box<[MaybeUninit<T>], A> {
         // Sanity-check one half of the safety requirement (we cannot check the other half).
         debug_assert!(
             len <= self.capacity(),
@@ -142,33 +166,9 @@ impl<T> RawVec<T, Global> {
         let me = ManuallyDrop::new(self);
         unsafe {
             let slice = slice::from_raw_parts_mut(me.ptr() as *mut MaybeUninit<T>, len);
-            Box::from_raw(slice)
+            Box::from_raw_in(slice, ptr::read(&me.alloc))
         }
     }
-}
-
-impl<T, A: AllocRef> RawVec<T, A> {
-    /// Like `new`, but parameterized over the choice of allocator for
-    /// the returned `RawVec`.
-    #[allow_internal_unstable(const_fn)]
-    pub const fn new_in(alloc: A) -> Self {
-        // `cap: 0` means "unallocated". zero-sized types are ignored.
-        Self { ptr: Unique::dangling(), cap: 0, alloc }
-    }
-
-    /// Like `with_capacity`, but parameterized over the choice of
-    /// allocator for the returned `RawVec`.
-    #[inline]
-    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
-        Self::allocate_in(capacity, AllocInit::Uninitialized, alloc)
-    }
-
-    /// Like `with_capacity_zeroed`, but parameterized over the choice
-    /// of allocator for the returned `RawVec`.
-    #[inline]
-    pub fn with_capacity_zeroed_in(capacity: usize, alloc: A) -> Self {
-        Self::allocate_in(capacity, AllocInit::Zeroed, alloc)
-    }
 
     fn allocate_in(capacity: usize, init: AllocInit, alloc: A) -> Self {
         if mem::size_of::<T>() == 0 {
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 939ebe074ed..72e5e0a8242 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -1034,7 +1034,7 @@ impl<T: ?Sized> Rc<T> {
 
     fn from_box(v: Box<T>) -> Rc<T> {
         unsafe {
-            let box_unique = Box::into_unique(v);
+            let (box_unique, alloc) = Box::into_unique(v);
             let bptr = box_unique.as_ptr();
 
             let value_size = size_of_val(&*bptr);
@@ -1048,7 +1048,7 @@ impl<T: ?Sized> Rc<T> {
             );
 
             // Free the allocation without dropping its contents
-            box_free(box_unique);
+            box_free(box_unique, alloc);
 
             Self::from_ptr(ptr)
         }
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 3a83aa7cbe5..d70de1163c9 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -1006,7 +1006,7 @@ impl<T: ?Sized> Arc<T> {
 
     fn from_box(v: Box<T>) -> Arc<T> {
         unsafe {
-            let box_unique = Box::into_unique(v);
+            let (box_unique, alloc) = Box::into_unique(v);
             let bptr = box_unique.as_ptr();
 
             let value_size = size_of_val(&*bptr);
@@ -1020,7 +1020,7 @@ impl<T: ?Sized> Arc<T> {
             );
 
             // Free the allocation without dropping its contents
-            box_free(box_unique);
+            box_free(box_unique, alloc);
 
             Self::from_ptr(ptr)
         }
diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff
index 4535cf290a1..f01f8d6211f 100644
--- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff
+++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff
@@ -53,10 +53,10 @@
 -     }
 - 
 -     bb4 (cleanup): {
--         _3 = alloc::alloc::box_free::<Vec<u32>>(move (_2.0: std::ptr::Unique<std::vec::Vec<u32>>)) -> bb3; // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
+-         _3 = alloc::alloc::box_free::<Vec<u32>, std::alloc::Global>(move (_2.0: std::ptr::Unique<std::vec::Vec<u32>>), move (_2.1: std::alloc::Global)) -> bb3; // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43
 -                                          // mir::Constant
 -                                          // + span: $DIR/inline-into-box-place.rs:8:42: 8:43
--                                          // + literal: Const { ty: unsafe fn(std::ptr::Unique<std::vec::Vec<u32>>) {alloc::alloc::box_free::<std::vec::Vec<u32>>}, val: Value(Scalar(<ZST>)) }
+-                                          // + literal: Const { ty: unsafe fn(std::ptr::Unique<std::vec::Vec<u32>>, std::alloc::Global) {alloc::alloc::box_free::<std::vec::Vec<u32>, std::alloc::Global>}, val: Value(Scalar(<ZST>)) }
       }
   }
   
diff --git a/src/test/ui/box/alloc-unstable-fail.rs b/src/test/ui/box/alloc-unstable-fail.rs
new file mode 100644
index 00000000000..9427571648c
--- /dev/null
+++ b/src/test/ui/box/alloc-unstable-fail.rs
@@ -0,0 +1,6 @@
+use std::boxed::Box;
+
+fn main() {
+    let _boxed: Box<u32, _> = Box::new(10);
+    //~^ ERROR use of unstable library feature 'allocator_api'
+}
diff --git a/src/test/ui/box/alloc-unstable-fail.stderr b/src/test/ui/box/alloc-unstable-fail.stderr
new file mode 100644
index 00000000000..03ae36e8890
--- /dev/null
+++ b/src/test/ui/box/alloc-unstable-fail.stderr
@@ -0,0 +1,12 @@
+error[E0658]: use of unstable library feature 'allocator_api'
+  --> $DIR/alloc-unstable-fail.rs:4:26
+   |
+LL |     let _boxed: Box<u32, _> = Box::new(10);
+   |                          ^
+   |
+   = note: see issue #32838 <https://github.com/rust-lang/rust/issues/32838> for more information
+   = help: add `#![feature(allocator_api)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/box/alloc-unstable.rs b/src/test/ui/box/alloc-unstable.rs
new file mode 100644
index 00000000000..66388d0d512
--- /dev/null
+++ b/src/test/ui/box/alloc-unstable.rs
@@ -0,0 +1,8 @@
+// run-pass
+#![feature(allocator_api)]
+
+use std::boxed::Box;
+
+fn main() {
+    let _boxed: Box<u32, _> = Box::new(10);
+}
diff --git a/src/test/ui/box-into-boxed-slice-fail.rs b/src/test/ui/box/into-boxed-slice-fail.rs
index 49dbb170f8e..49dbb170f8e 100644
--- a/src/test/ui/box-into-boxed-slice-fail.rs
+++ b/src/test/ui/box/into-boxed-slice-fail.rs
diff --git a/src/test/ui/box-into-boxed-slice-fail.stderr b/src/test/ui/box/into-boxed-slice-fail.stderr
index 8cfa3668d92..7a5ba16461f 100644
--- a/src/test/ui/box-into-boxed-slice-fail.stderr
+++ b/src/test/ui/box/into-boxed-slice-fail.stderr
@@ -1,14 +1,14 @@
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/box-into-boxed-slice-fail.rs:7:35
+  --> $DIR/into-boxed-slice-fail.rs:7:35
    |
 LL |     let _ = Box::into_boxed_slice(boxed_slice);
    |                                   ^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `[u8]`
-   = note: required by `Box::<T>::into_boxed_slice`
+   = note: required by `Box::<T, A>::into_boxed_slice`
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/box-into-boxed-slice-fail.rs:7:13
+  --> $DIR/into-boxed-slice-fail.rs:7:13
    |
 LL |     let _ = Box::into_boxed_slice(boxed_slice);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -17,16 +17,16 @@ LL |     let _ = Box::into_boxed_slice(boxed_slice);
    = note: slice and array elements must have `Sized` type
 
 error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time
-  --> $DIR/box-into-boxed-slice-fail.rs:11:35
+  --> $DIR/into-boxed-slice-fail.rs:11:35
    |
 LL |     let _ = Box::into_boxed_slice(boxed_trait);
    |                                   ^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `dyn Debug`
-   = note: required by `Box::<T>::into_boxed_slice`
+   = note: required by `Box::<T, A>::into_boxed_slice`
 
 error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time
-  --> $DIR/box-into-boxed-slice-fail.rs:11:13
+  --> $DIR/into-boxed-slice-fail.rs:11:13
    |
 LL |     let _ = Box::into_boxed_slice(boxed_trait);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
diff --git a/src/test/ui/box-into-boxed-slice.rs b/src/test/ui/box/into-boxed-slice.rs
index 61b3d915253..61b3d915253 100644
--- a/src/test/ui/box-into-boxed-slice.rs
+++ b/src/test/ui/box/into-boxed-slice.rs
diff --git a/src/test/ui/box/leak-alloc.rs b/src/test/ui/box/leak-alloc.rs
new file mode 100644
index 00000000000..2e73d6f1432
--- /dev/null
+++ b/src/test/ui/box/leak-alloc.rs
@@ -0,0 +1,29 @@
+#![feature(allocator_api)]
+
+use std::alloc::{AllocError, AllocRef, Layout, System};
+use std::ptr::NonNull;
+
+use std::boxed::Box;
+
+struct Allocator {}
+
+unsafe impl AllocRef for Allocator {
+    fn alloc(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
+        System.alloc(layout)
+    }
+
+    unsafe fn dealloc(&self, ptr: NonNull<u8>, layout: Layout) {
+        System.dealloc(ptr, layout)
+    }
+}
+
+fn use_value(_: u32) {}
+
+fn main() {
+    let alloc = Allocator {};
+    let boxed = Box::new_in(10, alloc.by_ref());
+    let theref = Box::leak(boxed);
+    drop(alloc);
+    //~^ ERROR cannot move out of `alloc` because it is borrowed
+    use_value(*theref)
+}
diff --git a/src/test/ui/box/leak-alloc.stderr b/src/test/ui/box/leak-alloc.stderr
new file mode 100644
index 00000000000..09beb181460
--- /dev/null
+++ b/src/test/ui/box/leak-alloc.stderr
@@ -0,0 +1,15 @@
+error[E0505]: cannot move out of `alloc` because it is borrowed
+  --> $DIR/leak-alloc.rs:26:10
+   |
+LL |     let boxed = Box::new_in(10, alloc.by_ref());
+   |                                 ----- borrow of `alloc` occurs here
+LL |     let theref = Box::leak(boxed);
+LL |     drop(alloc);
+   |          ^^^^^ move out of `alloc` occurs here
+LL |
+LL |     use_value(*theref)
+   |               ------- borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0505`.
diff --git a/src/test/ui/box-new.rs b/src/test/ui/box/new.rs
index be1a40cf779..be1a40cf779 100644
--- a/src/test/ui/box-new.rs
+++ b/src/test/ui/box/new.rs
diff --git a/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr
index 0959e155c57..20dc955ffe4 100644
--- a/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr
+++ b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr
@@ -2,9 +2,10 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
   --> $DIR/impl-foreign-for-fundamental[foreign].rs:10:1
    |
 LL | impl Remote for Box<i32> {
-   | ^^^^^^^^^^^^^^^^--------
-   | |               |
-   | |               `i32` is not defined in the current crate
+   | ^^^^^------^^^^^--------
+   | |    |          |
+   | |    |          `i32` is not defined in the current crate
+   | |    `std::alloc::Global` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead
@@ -13,9 +14,10 @@ error[E0117]: only traits defined in the current crate can be implemented for ar
   --> $DIR/impl-foreign-for-fundamental[foreign].rs:14:1
    |
 LL | impl<T> Remote for Box<Rc<T>> {
-   | ^^^^^^^^^^^^^^^^^^^----------
-   | |                  |
-   | |                  `Rc` is not defined in the current crate
+   | ^^^^^^^^------^^^^^----------
+   | |       |          |
+   | |       |          `Rc` is not defined in the current crate
+   | |       `std::alloc::Global` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead
diff --git a/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr
index b4d559eb1f2..c1e2fdaf5e3 100644
--- a/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr
+++ b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr
@@ -6,6 +6,7 @@ LL | impl Remote1<Box<String>> for i32 {
    | |    |                        |
    | |    |                        `i32` is not defined in the current crate
    | |    `String` is not defined in the current crate
+   | |    `std::alloc::Global` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead
@@ -18,6 +19,7 @@ LL | impl Remote1<Box<Rc<i32>>> for f64 {
    | |    |                         |
    | |    |                         `f64` is not defined in the current crate
    | |    `Rc` is not defined in the current crate
+   | |    `std::alloc::Global` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead
@@ -30,6 +32,7 @@ LL | impl<T> Remote1<Box<Rc<T>>> for f32 {
    | |       |                       |
    | |       |                       `f32` is not defined in the current crate
    | |       `Rc` is not defined in the current crate
+   | |       `std::alloc::Global` is not defined in the current crate
    | impl doesn't use only types from inside the current crate
    |
    = note: define and implement a trait or new type instead
diff --git a/src/test/ui/error-codes/e0119/conflict-with-std.stderr b/src/test/ui/error-codes/e0119/conflict-with-std.stderr
index 4b6b4430f32..9dc1a509cd0 100644
--- a/src/test/ui/error-codes/e0119/conflict-with-std.stderr
+++ b/src/test/ui/error-codes/e0119/conflict-with-std.stderr
@@ -5,8 +5,8 @@ LL | impl AsRef<Q> for Box<Q> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: conflicting implementation in crate `alloc`:
-           - impl<T> AsRef<T> for Box<T>
-             where T: ?Sized;
+           - impl<T, A> AsRef<T> for Box<T, A>
+             where A: AllocRef, T: ?Sized;
 
 error[E0119]: conflicting implementations of trait `std::convert::From<S>` for type `S`:
   --> $DIR/conflict-with-std.rs:12:1
diff --git a/src/test/ui/issues/issue-14092.rs b/src/test/ui/issues/issue-14092.rs
index 77da6badde9..3cfaa20a8b5 100644
--- a/src/test/ui/issues/issue-14092.rs
+++ b/src/test/ui/issues/issue-14092.rs
@@ -1,4 +1,4 @@
 fn fn1(0: Box) {}
-        //~^ ERROR wrong number of type arguments: expected 1, found 0 [E0107]
+        //~^ ERROR wrong number of type arguments: expected at least 1, found 0 [E0107]
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-14092.stderr b/src/test/ui/issues/issue-14092.stderr
index 626830ece8c..b749c44780d 100644
--- a/src/test/ui/issues/issue-14092.stderr
+++ b/src/test/ui/issues/issue-14092.stderr
@@ -1,8 +1,8 @@
-error[E0107]: wrong number of type arguments: expected 1, found 0
+error[E0107]: wrong number of type arguments: expected at least 1, found 0
   --> $DIR/issue-14092.rs:1:11
    |
 LL | fn fn1(0: Box) {}
-   |           ^^^ expected 1 type argument
+   |           ^^^ expected at least 1 type argument
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-3601.stderr b/src/test/ui/issues/issue-3601.stderr
index adad480f92b..c873c20cca8 100644
--- a/src/test/ui/issues/issue-3601.stderr
+++ b/src/test/ui/issues/issue-3601.stderr
@@ -1,8 +1,8 @@
-error[E0004]: non-exhaustive patterns: `Box(_)` not covered
+error[E0004]: non-exhaustive patterns: `Box(_, _)` not covered
   --> $DIR/issue-3601.rs:30:44
    |
 LL |         box NodeKind::Element(ed) => match ed.kind {
-   |                                            ^^^^^^^ pattern `Box(_)` not covered
+   |                                            ^^^^^^^ pattern `Box(_, _)` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
    = note: the matched value is of type `Box<ElementKind>`
diff --git a/src/test/ui/issues/issue-41974.stderr b/src/test/ui/issues/issue-41974.stderr
index f1342181b37..fb24aadde08 100644
--- a/src/test/ui/issues/issue-41974.stderr
+++ b/src/test/ui/issues/issue-41974.stderr
@@ -1,13 +1,13 @@
-error[E0119]: conflicting implementations of trait `std::ops::Drop` for type `std::boxed::Box<_>`:
+error[E0119]: conflicting implementations of trait `std::ops::Drop` for type `std::boxed::Box<_, _>`:
   --> $DIR/issue-41974.rs:7:1
    |
 LL | impl<T> Drop for T where T: A {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: conflicting implementation in crate `alloc`:
-           - impl<T> Drop for Box<T>
-             where T: ?Sized;
-   = note: downstream crates may implement trait `A` for type `std::boxed::Box<_>`
+           - impl<T, A> Drop for Box<T, A>
+             where A: AllocRef, T: ?Sized;
+   = note: downstream crates may implement trait `A` for type `std::boxed::Box<_, _>`
 
 error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
   --> $DIR/issue-41974.rs:7:18
diff --git a/src/test/ui/privacy/privacy-ns1.rs b/src/test/ui/privacy/privacy-ns1.rs
index 614375e5e51..c7084bfd980 100644
--- a/src/test/ui/privacy/privacy-ns1.rs
+++ b/src/test/ui/privacy/privacy-ns1.rs
@@ -33,7 +33,7 @@ fn test_glob2() {
     use foo2::*;
 
     let _x: Box<Bar>;  //~ ERROR wrong number of const arguments: expected 0, found 1
-    //~^ ERROR wrong number of type arguments: expected 1, found 0
+    //~^ ERROR wrong number of type arguments: expected at least 1, found 0
 }
 
 // neither public
diff --git a/src/test/ui/privacy/privacy-ns1.stderr b/src/test/ui/privacy/privacy-ns1.stderr
index eda9d4c128d..ccbb5d5c90f 100644
--- a/src/test/ui/privacy/privacy-ns1.stderr
+++ b/src/test/ui/privacy/privacy-ns1.stderr
@@ -58,11 +58,11 @@ error[E0107]: wrong number of const arguments: expected 0, found 1
 LL |     let _x: Box<Bar>;
    |                 ^^^ unexpected const argument
 
-error[E0107]: wrong number of type arguments: expected 1, found 0
+error[E0107]: wrong number of type arguments: expected at least 1, found 0
   --> $DIR/privacy-ns1.rs:35:13
    |
 LL |     let _x: Box<Bar>;
-   |             ^^^^^^^^ expected 1 type argument
+   |             ^^^^^^^^ expected at least 1 type argument
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/privacy/privacy-ns2.rs b/src/test/ui/privacy/privacy-ns2.rs
index 0546de873f3..b770c8f8f86 100644
--- a/src/test/ui/privacy/privacy-ns2.rs
+++ b/src/test/ui/privacy/privacy-ns2.rs
@@ -39,7 +39,7 @@ fn test_single2() {
     use foo2::Bar;
 
     let _x : Box<Bar>; //~ ERROR wrong number of const arguments: expected 0, found 1
-    //~^ ERROR wrong number of type arguments: expected 1, found 0
+    //~^ ERROR wrong number of type arguments: expected at least 1, found 0
     let _x : Bar(); //~ ERROR expected type, found function `Bar`
 }
 
@@ -47,7 +47,7 @@ fn test_list2() {
     use foo2::{Bar,Baz};
 
     let _x: Box<Bar>; //~ ERROR wrong number of const arguments: expected 0, found 1
-    //~^ ERROR wrong number of type arguments: expected 1, found 0
+    //~^ ERROR wrong number of type arguments: expected at least 1, found 0
 }
 
 // neither public
diff --git a/src/test/ui/privacy/privacy-ns2.stderr b/src/test/ui/privacy/privacy-ns2.stderr
index d7d9b835275..dbb269c0ba6 100644
--- a/src/test/ui/privacy/privacy-ns2.stderr
+++ b/src/test/ui/privacy/privacy-ns2.stderr
@@ -84,11 +84,11 @@ error[E0107]: wrong number of const arguments: expected 0, found 1
 LL |     let _x : Box<Bar>;
    |                  ^^^ unexpected const argument
 
-error[E0107]: wrong number of type arguments: expected 1, found 0
+error[E0107]: wrong number of type arguments: expected at least 1, found 0
   --> $DIR/privacy-ns2.rs:41:14
    |
 LL |     let _x : Box<Bar>;
-   |              ^^^^^^^^ expected 1 type argument
+   |              ^^^^^^^^ expected at least 1 type argument
 
 error[E0107]: wrong number of const arguments: expected 0, found 1
   --> $DIR/privacy-ns2.rs:49:17
@@ -96,11 +96,11 @@ error[E0107]: wrong number of const arguments: expected 0, found 1
 LL |     let _x: Box<Bar>;
    |                 ^^^ unexpected const argument
 
-error[E0107]: wrong number of type arguments: expected 1, found 0
+error[E0107]: wrong number of type arguments: expected at least 1, found 0
   --> $DIR/privacy-ns2.rs:49:13
    |
 LL |     let _x: Box<Bar>;
-   |             ^^^^^^^^ expected 1 type argument
+   |             ^^^^^^^^ expected at least 1 type argument
 
 error: aborting due to 10 previous errors
 
diff --git a/src/test/ui/unique-object-noncopyable.stderr b/src/test/ui/unique-object-noncopyable.stderr
index 423350cd936..2e23ddd9053 100644
--- a/src/test/ui/unique-object-noncopyable.stderr
+++ b/src/test/ui/unique-object-noncopyable.stderr
@@ -1,27 +1,30 @@
 error[E0599]: no method named `clone` found for struct `Box<dyn Foo>` in the current scope
   --> $DIR/unique-object-noncopyable.rs:24:16
    |
-LL | trait Foo {
-   | ---------
-   | |
-   | doesn't satisfy `dyn Foo: Clone`
-   | doesn't satisfy `dyn Foo: Sized`
+LL |   trait Foo {
+   |   ---------
+   |   |
+   |   doesn't satisfy `dyn Foo: Clone`
+   |   doesn't satisfy `dyn Foo: Sized`
 ...
-LL |     let _z = y.clone();
-   |                ^^^^^ method not found in `Box<dyn Foo>`
+LL |       let _z = y.clone();
+   |                  ^^^^^ method not found in `Box<dyn Foo>`
    | 
-  ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL
+  ::: $SRC_DIR/core/src/clone.rs:LL:COL
    |
-LL | pub struct Box<T: ?Sized>(Unique<T>);
-   | ------------------------------------- doesn't satisfy `Box<dyn Foo>: Clone`
+LL |       fn clone(&self) -> Self;
+   |          -----
+   |          |
+   |          the method is available for `Arc<Box<dyn Foo>>` here
+   |          the method is available for `Rc<Box<dyn Foo>>` here
    | 
-  ::: $SRC_DIR/core/src/clone.rs:LL:COL
+  ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL
    |
-LL |     fn clone(&self) -> Self;
-   |        -----
-   |        |
-   |        the method is available for `Arc<Box<dyn Foo>>` here
-   |        the method is available for `Rc<Box<dyn Foo>>` here
+LL | / pub struct Box<
+LL | |     T: ?Sized,
+LL | |     #[unstable(feature = "allocator_api", issue = "32838")] A: AllocRef = Global,
+LL | | >(Unique<T>, A);
+   | |________________- doesn't satisfy `Box<dyn Foo>: Clone`
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `dyn Foo: Sized`
diff --git a/src/test/ui/unique-pinned-nocopy.stderr b/src/test/ui/unique-pinned-nocopy.stderr
index d39db225043..d533724a009 100644
--- a/src/test/ui/unique-pinned-nocopy.stderr
+++ b/src/test/ui/unique-pinned-nocopy.stderr
@@ -1,24 +1,27 @@
 error[E0599]: no method named `clone` found for struct `Box<R>` in the current scope
   --> $DIR/unique-pinned-nocopy.rs:12:16
    |
-LL | struct R {
-   | -------- doesn't satisfy `R: Clone`
+LL |   struct R {
+   |   -------- doesn't satisfy `R: Clone`
 ...
-LL |     let _j = i.clone();
-   |                ^^^^^ method not found in `Box<R>`
+LL |       let _j = i.clone();
+   |                  ^^^^^ method not found in `Box<R>`
    | 
-  ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL
+  ::: $SRC_DIR/core/src/clone.rs:LL:COL
    |
-LL | pub struct Box<T: ?Sized>(Unique<T>);
-   | ------------------------------------- doesn't satisfy `Box<R>: Clone`
+LL |       fn clone(&self) -> Self;
+   |          -----
+   |          |
+   |          the method is available for `Arc<Box<R>>` here
+   |          the method is available for `Rc<Box<R>>` here
    | 
-  ::: $SRC_DIR/core/src/clone.rs:LL:COL
+  ::: $SRC_DIR/alloc/src/boxed.rs:LL:COL
    |
-LL |     fn clone(&self) -> Self;
-   |        -----
-   |        |
-   |        the method is available for `Arc<Box<R>>` here
-   |        the method is available for `Rc<Box<R>>` here
+LL | / pub struct Box<
+LL | |     T: ?Sized,
+LL | |     #[unstable(feature = "allocator_api", issue = "32838")] A: AllocRef = Global,
+LL | | >(Unique<T>, A);
+   | |________________- doesn't satisfy `Box<R>: Clone`
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `R: Clone`