about summary refs log tree commit diff
path: root/library/alloc
diff options
context:
space:
mode:
Diffstat (limited to 'library/alloc')
-rw-r--r--library/alloc/src/alloc.rs2
-rw-r--r--library/alloc/src/boxed.rs24
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/macros.rs5
4 files changed, 26 insertions, 6 deletions
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index ae34fc65326..e9b7f985667 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -339,7 +339,7 @@ unsafe impl Allocator for Global {
     }
 }
 
-/// The allocator for unique pointers.
+/// The allocator for `Box`.
 #[cfg(all(not(no_global_oom_handling), not(test)))]
 #[lang = "exchange_malloc"]
 #[inline]
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index 05e5d712a27..0f66217b5cb 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -233,6 +233,27 @@ pub struct Box<
     #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
 >(Unique<T>, A);
 
+/// Constructs a `Box<T>` by calling the `exchange_malloc` lang item and moving the argument into
+/// the newly allocated memory. This is an intrinsic to avoid unnecessary copies.
+///
+/// This is the surface syntax for `box <expr>` expressions.
+#[cfg(not(bootstrap))]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[unstable(feature = "liballoc_internals", issue = "none")]
+pub fn box_new<T>(_x: T) -> Box<T> {
+    unreachable!()
+}
+
+/// Transition function for the next bootstrap bump.
+#[cfg(bootstrap)]
+#[unstable(feature = "liballoc_internals", issue = "none")]
+#[inline(always)]
+pub fn box_new<T>(x: T) -> Box<T> {
+    #[rustc_box]
+    Box::new(x)
+}
+
 impl<T> Box<T> {
     /// Allocates memory on the heap and then places `x` into it.
     ///
@@ -250,8 +271,7 @@ impl<T> Box<T> {
     #[rustc_diagnostic_item = "box_new"]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub fn new(x: T) -> Self {
-        #[rustc_box]
-        Box::new(x)
+        return box_new(x);
     }
 
     /// Constructs a new box with uninitialized contents.
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 40759cb0ba8..aff90f5abb3 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -168,6 +168,7 @@
 #![feature(dropck_eyepatch)]
 #![feature(fundamental)]
 #![feature(hashmap_internals)]
+#![feature(intrinsics)]
 #![feature(lang_items)]
 #![feature(min_specialization)]
 #![feature(multiple_supertrait_upcastable)]
diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs
index 8c6a367869c..6ee3907cc8e 100644
--- a/library/alloc/src/macros.rs
+++ b/library/alloc/src/macros.rs
@@ -48,10 +48,9 @@ macro_rules! vec {
     );
     ($($x:expr),+ $(,)?) => (
         <[_]>::into_vec(
-            // This rustc_box is not required, but it produces a dramatic improvement in compile
+            // Using the intrinsic produces a dramatic improvement in compile
             // time when constructing arrays with many elements.
-            #[rustc_box]
-            $crate::boxed::Box::new([$($x),+])
+            $crate::boxed::box_new([$($x),+])
         )
     );
 }