From edb2c2d291811f9b21ed8bd1499648a0614f6fc8 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Tue, 26 Sep 2017 21:16:59 -0400 Subject: [PATCH 1/6] Remove uses of mem::transmute in Box methods Makes use of conversions via Unique. --- src/liballoc/boxed.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 4341b0b2975be..512c7194fe3ff 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -269,7 +269,7 @@ impl Box { #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub unsafe fn from_raw(raw: *mut T) -> Self { - mem::transmute(raw) + Box(Unique::new_unchecked(raw)) } /// Consumes the `Box`, returning the wrapped raw pointer. @@ -295,7 +295,7 @@ impl Box { #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub fn into_raw(b: Box) -> *mut T { - unsafe { mem::transmute(b) } + Box::into_unique(b).as_ptr() } /// Consumes the `Box`, returning the wrapped pointer as `Unique`. @@ -326,7 +326,9 @@ impl Box { issue = "27730")] #[inline] pub fn into_unique(b: Box) -> Unique { - unsafe { mem::transmute(b) } + let u = b.0; + mem::forget(b); + u } } From 904133e1e28b690e2bbd101b719509aa897539a0 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Fri, 6 Oct 2017 16:39:01 -0400 Subject: [PATCH 2/6] Revert to using mem::transmute in Box::into_unique Seems to cause this error: "Cannot handle boxed::Box<[u8]> represented as TyLayout". --- src/liballoc/boxed.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 512c7194fe3ff..6b92da1107985 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -326,9 +326,7 @@ impl Box { issue = "27730")] #[inline] pub fn into_unique(b: Box) -> Unique { - let u = b.0; - mem::forget(b); - u + unsafe { mem::transmute(b) } } } From 452b71a07be066432d93a93c1f9e7f10e18d7c96 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Fri, 6 Oct 2017 17:01:50 -0400 Subject: [PATCH 3/6] Revert to using mem::transmute in Box::from_raw Same reasons as commit 904133e1e28b690e2bbd101b719509aa897539a0. --- src/liballoc/boxed.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 6b92da1107985..2e77b1b390cf6 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -269,7 +269,7 @@ impl Box { #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub unsafe fn from_raw(raw: *mut T) -> Self { - Box(Unique::new_unchecked(raw)) + mem::transmute(raw) } /// Consumes the `Box`, returning the wrapped raw pointer. From 5ce5b2fe76802385e2974bdec8d82117fb55d0ea Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Fri, 6 Oct 2017 17:29:49 -0400 Subject: [PATCH 4/6] Create Box::from_unique function Provides a reasonable interface for Box::from_raw implementation. Does not get around the requirement of mem::transmute for converting back and forth between Unique and Box. --- src/liballoc/boxed.rs | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 2e77b1b390cf6..53d643e72884d 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -269,7 +269,34 @@ impl Box { #[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` pointer. + /// + /// After calling this function, the memory is owned by a `Box` and `T` then + /// be destroyed and released upon drop. + /// + /// # Safety + /// + /// A `Unique` 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 + /// + /// ``` + /// 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) -> Self { + mem::transmute(u) } /// Consumes the `Box`, returning the wrapped raw pointer. @@ -303,13 +330,18 @@ impl Box { /// 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` 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 From 5af88ee9969320ef900190e1e6a8247d800b7fe6 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Fri, 6 Oct 2017 17:39:38 -0400 Subject: [PATCH 5/6] Add missing word in Box::from_unique docs --- src/liballoc/boxed.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 53d643e72884d..2c14dfb1dd096 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -274,8 +274,8 @@ impl Box { /// Constructs a `Box` from a `Unique` pointer. /// - /// After calling this function, the memory is owned by a `Box` and `T` then - /// be destroyed and released upon drop. + /// After calling this function, the memory is owned by a `Box` and `T` can + /// then be destroyed and released upon drop. /// /// # Safety /// From 22298b8240d40ed9b3dbdf570bccce56dfbfcd2c Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Fri, 6 Oct 2017 19:21:22 -0400 Subject: [PATCH 6/6] Add unique feature in Box::from_unique docs --- src/liballoc/boxed.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 2c14dfb1dd096..0d19b74ebae4b 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -288,9 +288,13 @@ impl Box { /// # Examples /// /// ``` - /// let x = Box::new(5); - /// let ptr = Box::into_unique(x); - /// let x = unsafe { Box::from_unique(ptr) }; + /// #![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")]