Skip to content

Commit

Permalink
avoid materializing unintialized Boxes in RawVec
Browse files Browse the repository at this point in the history
  • Loading branch information
matklad committed May 27, 2019
1 parent ed2a511 commit a23a77f
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 7 deletions.
9 changes: 6 additions & 3 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}
}

Expand Down
10 changes: 6 additions & 4 deletions src/liballoc/raw_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit a23a77f

Please sign in to comment.