diff options
| author | Aleksey Kladov <aleksey.kladov@gmail.com> | 2019-05-27 09:43:20 +0300 |
|---|---|---|
| committer | Aleksey Kladov <aleksey.kladov@gmail.com> | 2019-05-27 11:15:31 +0300 |
| commit | a23a77fb19b24adb22d0a3d3886acac1a7a31f68 (patch) | |
| tree | 6f368529cf02baf5709aeee4e05f335f6b538985 /src/liballoc | |
| parent | ed2a5115daaffdab30b102405ffcfb222decf444 (diff) | |
| download | rust-a23a77fb19b24adb22d0a3d3886acac1a7a31f68.tar.gz rust-a23a77fb19b24adb22d0a3d3886acac1a7a31f68.zip | |
avoid materializing unintialized Boxes in RawVec
Diffstat (limited to 'src/liballoc')
| -rw-r--r-- | src/liballoc/boxed.rs | 9 | ||||
| -rw-r--r-- | 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 bf8f5b8b91a..5affdbdb7e9 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -546,9 +546,12 @@ impl<T: Copy> 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 d1fc5ac3b30..0454a564435 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -685,12 +685,14 @@ impl<T, A: Alloc> RawVec<T, A> { impl<T> RawVec<T, Global> { /// 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<T, Global>` 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); |
