From 58b1a127d66b71e1a2180b509856f2c52feca9b3 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Tue, 28 Sep 2021 13:03:31 -0700 Subject: [PATCH 1/4] Avoid allocations and copying in Vec::leak Don't shrink the Vec (by calling into_boxed_slice) before leaking it. --- library/alloc/src/vec/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index c37ec37556157..a8b939bc249e0 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1976,7 +1976,8 @@ impl Vec { 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 From 1fca2ce9010a581798fa39d1742eddcaada359ad Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Tue, 28 Sep 2021 16:27:47 -0700 Subject: [PATCH 2/4] Additional docs about Vec::leak behavior --- library/alloc/src/vec/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index a8b939bc249e0..30cd95d695989 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1952,8 +1952,11 @@ impl Vec { /// `'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. + /// 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. Unsafe code that later reconstructs or deallocates the `Vec` + /// (for example, by calling [`Vec::from_raw_parts`]) must keep track of the + /// original capacity. /// /// 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 From 129af049fef9a9de3ffba1f6b26246b02a360de3 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 12 Oct 2021 14:50:46 +0200 Subject: [PATCH 3/4] Mention Rust version in Vec::leak docs. --- library/alloc/src/vec/mod.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 30cd95d695989..546cd1f631083 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1952,10 +1952,11 @@ impl Vec { /// `'a`. If the type has only static references, or none at all, then this /// may be chosen to be `'static`. /// - /// 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. Unsafe code that later reconstructs or deallocates the `Vec` - /// (for example, by calling [`Vec::from_raw_parts`]) must keep track of the + /// 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. + /// Unsafe code that later reconstructs or deallocates the `Vec` (for + /// example, by calling [`Vec::from_raw_parts`]) must keep track of the /// original capacity. /// /// This function is mainly useful for data that lives for the remainder of From df15b289f39c497d16fac694c6982fbdfa2e6fe2 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 12 Oct 2021 15:02:52 +0200 Subject: [PATCH 4/4] Remove potentially unsound note on reconstructing a leaked Vec. --- library/alloc/src/vec/mod.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 546cd1f631083..632297196caf5 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1955,9 +1955,6 @@ impl Vec { /// 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. - /// Unsafe code that later reconstructs or deallocates the `Vec` (for - /// example, by calling [`Vec::from_raw_parts`]) must keep track of the - /// original capacity. /// /// 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