From a23a77fb19b24adb22d0a3d3886acac1a7a31f68 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 27 May 2019 09:43:20 +0300 Subject: [PATCH] avoid materializing unintialized Boxes in RawVec --- src/liballoc/boxed.rs | 9 ++++++--- src/liballoc/raw_vec.rs | 10 ++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index bf8f5b8b91a1e..5affdbdb7e9d1 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -546,9 +546,12 @@ impl From<&[T]> for Box<[T]> { /// println!("{:?}", boxed_slice); /// ``` fn from(slice: &[T]) -> Box<[T]> { - let mut boxed = unsafe { RawVec::with_capacity(slice.len()).into_box() }; - boxed.copy_from_slice(slice); - boxed + let len = slice.len(); + let buf = RawVec::with_capacity(len); + unsafe { + ptr::copy_nonoverlapping(slice.as_ptr(), buf.ptr(), len); + buf.into_box() + } } } diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index d1fc5ac3b30d4..0454a56443579 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -685,12 +685,14 @@ impl RawVec { impl RawVec { /// Converts the entire buffer into `Box<[T]>`. /// - /// While it is not *strictly* Undefined Behavior to call - /// this procedure while some of the RawVec is uninitialized, - /// it certainly makes it trivial to trigger it. - /// /// Note that this will correctly reconstitute any `cap` changes /// that may have been performed. (see description of type for details) + /// + /// # Undefined Behavior + /// + /// All elements of `RawVec` must be initialized. Notice that + /// the rules around uninitialized boxed values are not finalized yet, + /// but until they are, it is advisable to avoid them. pub unsafe fn into_box(self) -> Box<[T]> { // NOTE: not calling `cap()` here, actually using the real `cap` field! let slice = slice::from_raw_parts_mut(self.ptr(), self.cap);