about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-10-15 15:55:08 +0000
committerbors <bors@rust-lang.org>2021-10-15 15:55:08 +0000
commit265fef45f20e3b8ed9495201b5d02bab1210f0f9 (patch)
treefe4e428ff5bc108a76e956e6a17d526bec8f613c
parentaf9b508e1d6c83a8f0e6f5c0b2b75598aa37ed27 (diff)
parentdf15b289f39c497d16fac694c6982fbdfa2e6fe2 (diff)
downloadrust-265fef45f20e3b8ed9495201b5d02bab1210f0f9.tar.gz
rust-265fef45f20e3b8ed9495201b5d02bab1210f0f9.zip
Auto merge of #89337 - mbrubeck:vec-leak, r=m-ou-se
Avoid allocations and copying in Vec::leak

The [`Vec::leak`] method (#62195) is currently implemented by calling `Vec::into_boxed_slice` and `Box::leak`.  This shrinks the vector before leaking it, which potentially causes a reallocation and copies the vector's contents.

By avoiding the conversion to `Box`, we can instead leak the vector without any expensive operations, just by returning a slice reference and forgetting the `Vec`.  Users who *want* to shrink the vector first can still do so by calling `shrink_to_fit` explicitly.

**Note:**  This could break code that uses `Box::from_raw` to “un-leak” the slice returned by `Vec::leak`.  However, the `Vec::leak` docs explicitly forbid this, so such code is already incorrect.

[`Vec::leak`]: https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.leak
-rw-r--r--library/alloc/src/vec/mod.rs8
1 files changed, 5 insertions, 3 deletions
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index a12acb1a1c0..20a16869cb3 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1973,8 +1973,9 @@ impl<T, A: Allocator> Vec<T, A> {
     /// `'a`. If the type has only static references, or none at all, then this
     /// may be chosen to be `'static`.
     ///
-    /// This function is similar to the [`leak`][Box::leak] function on [`Box`]
-    /// except that there is no way to recover the leaked memory.
+    /// As of Rust 1.57, this method does not reallocate or shrink the `Vec`,
+    /// so the leaked allocation may include unused capacity that is not part
+    /// of the returned slice.
     ///
     /// This function is mainly useful for data that lives for the remainder of
     /// the program's life. Dropping the returned reference will cause a memory
@@ -1997,7 +1998,8 @@ impl<T, A: Allocator> Vec<T, A> {
     where
         A: 'a,
     {
-        Box::leak(self.into_boxed_slice())
+        let mut me = ManuallyDrop::new(self);
+        unsafe { slice::from_raw_parts_mut(me.as_mut_ptr(), me.len) }
     }
 
     /// Returns the remaining spare capacity of the vector as a slice of