diff options
| author | bors <bors@rust-lang.org> | 2017-10-10 11:07:25 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-10-10 11:07:25 +0000 |
| commit | 0217315bf23edee385a7042b5a23b3e7e376820c (patch) | |
| tree | a081236a8c09dd20d54544f62cca217092f049d2 /src/liballoc/boxed.rs | |
| parent | 5f578dfad0dd5d43b28eff71a7e857d10c3f55fe (diff) | |
| parent | 22298b8240d40ed9b3dbdf570bccce56dfbfcd2c (diff) | |
| download | rust-0217315bf23edee385a7042b5a23b3e7e376820c.tar.gz rust-0217315bf23edee385a7042b5a23b3e7e376820c.zip | |
Auto merge of #44877 - nvzqz:box-conversions, r=alexcrichton
Improve raw Box conversions This PR has two goals: - Reduce use of `mem::transmute` in `Box` conversions I understand that `mem::transmute`-ing non `#[repr(C)]` types is implementation-defined behavior. This may not matter within the reference implementation of Rust, but I believe it's important to remain consistent. For example, I noticed that `str::from_utf8_unchecked` went from using `mem::transmute` to using pointer casts. - Make `Box` pointer conversions more straightforward regarding `Unique`
Diffstat (limited to 'src/liballoc/boxed.rs')
| -rw-r--r-- | src/liballoc/boxed.rs | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 35c8530b4dd..79292d390e5 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -269,7 +269,38 @@ impl<T: ?Sized> Box<T> { #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub unsafe fn from_raw(raw: *mut T) -> Self { - mem::transmute(raw) + Box::from_unique(Unique::new_unchecked(raw)) + } + + /// Constructs a `Box` from a `Unique<T>` pointer. + /// + /// After calling this function, the memory is owned by a `Box` and `T` can + /// then be destroyed and released upon drop. + /// + /// # Safety + /// + /// A `Unique<T>` can be safely created via [`Unique::new`] and thus doesn't + /// necessarily own the data pointed to nor is the data guaranteed to live + /// as long as the pointer. + /// + /// [`Unique::new`]: ../../core/ptr/struct.Unique.html#method.new + /// + /// # Examples + /// + /// ``` + /// #![feature(unique)] + /// + /// fn main() { + /// let x = Box::new(5); + /// let ptr = Box::into_unique(x); + /// let x = unsafe { Box::from_unique(ptr) }; + /// } + /// ``` + #[unstable(feature = "unique", reason = "needs an RFC to flesh out design", + issue = "27730")] + #[inline] + pub unsafe fn from_unique(u: Unique<T>) -> Self { + mem::transmute(u) } /// Consumes the `Box`, returning the wrapped raw pointer. @@ -295,7 +326,7 @@ impl<T: ?Sized> Box<T> { #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub fn into_raw(b: Box<T>) -> *mut T { - unsafe { mem::transmute(b) } + Box::into_unique(b).as_ptr() } /// Consumes the `Box`, returning the wrapped pointer as `Unique<T>`. @@ -303,13 +334,18 @@ impl<T: ?Sized> Box<T> { /// After calling this function, the caller is responsible for the /// memory previously managed by the `Box`. In particular, the /// caller should properly destroy `T` and release the memory. The - /// proper way to do so is to convert the raw pointer back into a - /// `Box` with the [`Box::from_raw`] function. + /// proper way to do so is to either convert the `Unique<T>` pointer: + /// + /// - Into a `Box` with the [`Box::from_unique`] function. + /// + /// - Into a raw pointer and back into a `Box` with the [`Box::from_raw`] + /// function. /// /// Note: this is an associated function, which means that you have /// to call it as `Box::into_unique(b)` instead of `b.into_unique()`. This /// is so that there is no conflict with a method on the inner type. /// + /// [`Box::from_unique`]: struct.Box.html#method.from_unique /// [`Box::from_raw`]: struct.Box.html#method.from_raw /// /// # Examples |
