Skip to content

Deprecate {Box,Rc,Arc}::into_raw_non_null #71168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 25, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 31 additions & 15 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
@@ -428,7 +428,12 @@ impl<T: ?Sized> Box<T> {
#[stable(feature = "box_raw", since = "1.4.0")]
#[inline]
pub fn into_raw(b: Box<T>) -> *mut T {
Box::into_raw_non_null(b).as_ptr()
// Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
// raw pointer for the type system. Turning it directly into a raw pointer would not be
// recognized as "releasing" the unique pointer to permit aliased raw accesses,
// so all raw pointer methods go through `leak` which creates a (unique)
// mutable reference. Turning *that* to a raw pointer behaves correctly.
Box::leak(b) as *mut T
}

/// Consumes the `Box`, returning the wrapped pointer as `NonNull<T>`.
@@ -451,6 +456,7 @@ impl<T: ?Sized> Box<T> {
///
/// ```
/// #![feature(box_into_raw_non_null)]
/// #![allow(deprecated)]
///
/// let x = Box::new(5);
/// let ptr = Box::into_raw_non_null(x);
@@ -460,24 +466,34 @@ impl<T: ?Sized> Box<T> {
/// let x = unsafe { Box::from_raw(ptr.as_ptr()) };
/// ```
#[unstable(feature = "box_into_raw_non_null", issue = "47336")]
#[rustc_deprecated(
since = "1.44.0",
reason = "use `Box::leak(b).into()` or `NonNull::from(Box::leak(b))` instead"
)]
#[inline]
pub fn into_raw_non_null(b: Box<T>) -> NonNull<T> {
Box::into_unique(b).into()
}

#[unstable(feature = "ptr_internals", issue = "none", reason = "use into_raw_non_null instead")]
// Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
// raw pointer for the type system. Turning it directly into a raw pointer would not be
// recognized as "releasing" the unique pointer to permit aliased raw accesses,
// so all raw pointer methods go through `leak` which creates a (unique)
// mutable reference. Turning *that* to a raw pointer behaves correctly.
Box::leak(b).into()
}

#[unstable(
feature = "ptr_internals",
issue = "none",
reason = "use `Box::leak(b).into()` or `Unique::from(Box::leak(b))` instead"
)]
#[inline]
#[doc(hidden)]
pub fn into_unique(b: Box<T>) -> Unique<T> {
let b = mem::ManuallyDrop::new(b);
let mut unique = b.0;
// Box is kind-of a library type, but recognized as a "unique pointer" by
// Stacked Borrows. This function here corresponds to "reborrowing to
// a raw pointer", but there is no actual reborrow here -- so
// without some care, the pointer we are returning here still carries
// the tag of `b`, with `Unique` permission.
// We round-trip through a mutable reference to avoid that.
unsafe { Unique::new_unchecked(unique.as_mut() as *mut T) }
// Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
// raw pointer for the type system. Turning it directly into a raw pointer would not be
// recognized as "releasing" the unique pointer to permit aliased raw accesses,
// so all raw pointer methods go through `leak` which creates a (unique)
// mutable reference. Turning *that* to a raw pointer behaves correctly.
Box::leak(b).into()
}

/// Consumes and leaks the `Box`, returning a mutable reference,
@@ -523,7 +539,7 @@ impl<T: ?Sized> Box<T> {
where
T: 'a, // Technically not needed, but kept to be explicit.
{
unsafe { &mut *Box::into_raw(b) }
unsafe { &mut *mem::ManuallyDrop::new(b).0.as_ptr() }
}

/// Converts a `Box<T>` into a `Pin<Box<T>>`
16 changes: 7 additions & 9 deletions src/liballoc/collections/linked_list.rs
Original file line number Diff line number Diff line change
@@ -143,7 +143,7 @@ impl<T> LinkedList<T> {
unsafe {
node.next = self.head;
node.prev = None;
let node = Some(Box::into_raw_non_null(node));
let node = Some(Box::leak(node).into());

match self.head {
None => self.tail = node,
@@ -184,7 +184,7 @@ impl<T> LinkedList<T> {
unsafe {
node.next = None;
node.prev = self.tail;
let node = Some(Box::into_raw_non_null(node));
let node = Some(Box::leak(node).into());

match self.tail {
None => self.head = node,
@@ -1133,11 +1133,9 @@ impl<T> IterMut<'_, T> {
Some(prev) => prev,
};

let node = Some(Box::into_raw_non_null(box Node {
next: Some(head),
prev: Some(prev),
element,
}));
let node = Some(
Box::leak(box Node { next: Some(head), prev: Some(prev), element }).into(),
);

// Not creating references to entire nodes to not invalidate the
// reference to `element` we handed to the user.
@@ -1442,7 +1440,7 @@ impl<'a, T> CursorMut<'a, T> {
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn insert_after(&mut self, item: T) {
unsafe {
let spliced_node = Box::into_raw_non_null(Box::new(Node::new(item)));
let spliced_node = Box::leak(Box::new(Node::new(item))).into();
let node_next = match self.current {
None => self.list.head,
Some(node) => node.as_ref().next,
@@ -1462,7 +1460,7 @@ impl<'a, T> CursorMut<'a, T> {
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn insert_before(&mut self, item: T) {
unsafe {
let spliced_node = Box::into_raw_non_null(Box::new(Node::new(item)));
let spliced_node = Box::leak(Box::new(Node::new(item))).into();
let node_prev = match self.current {
None => self.list.tail,
Some(node) => node.as_ref().prev,
1 change: 0 additions & 1 deletion src/liballoc/lib.rs
Original file line number Diff line number Diff line change
@@ -77,7 +77,6 @@
#![feature(allocator_api)]
#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(box_into_raw_non_null)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(cfg_sanitize)]
10 changes: 5 additions & 5 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
@@ -324,11 +324,9 @@ impl<T> Rc<T> {
// pointers, which ensures that the weak destructor never frees
// the allocation while the strong destructor is running, even
// if the weak pointer is stored inside the strong one.
Self::from_inner(Box::into_raw_non_null(box RcBox {
strong: Cell::new(1),
weak: Cell::new(1),
value,
}))
Self::from_inner(
Box::leak(box RcBox { strong: Cell::new(1), weak: Cell::new(1), value }).into(),
)
}

/// Constructs a new `Rc` with uninitialized contents.
@@ -638,6 +636,7 @@ impl<T: ?Sized> Rc<T> {
///
/// ```
/// #![feature(rc_into_raw_non_null)]
/// #![allow(deprecated)]
///
/// use std::rc::Rc;
///
@@ -647,6 +646,7 @@ impl<T: ?Sized> Rc<T> {
/// assert_eq!(deref, "hello");
/// ```
#[unstable(feature = "rc_into_raw_non_null", issue = "47336")]
#[rustc_deprecated(since = "1.44.0", reason = "use `Rc::into_raw` instead")]
#[inline]
pub fn into_raw_non_null(this: Self) -> NonNull<T> {
// safe because Rc guarantees its pointer is non-null
4 changes: 3 additions & 1 deletion src/liballoc/sync.rs
Original file line number Diff line number Diff line change
@@ -325,7 +325,7 @@ impl<T> Arc<T> {
weak: atomic::AtomicUsize::new(1),
data,
};
Self::from_inner(Box::into_raw_non_null(x))
Self::from_inner(Box::leak(x).into())
}

/// Constructs a new `Arc` with uninitialized contents.
@@ -635,6 +635,7 @@ impl<T: ?Sized> Arc<T> {
///
/// ```
/// #![feature(rc_into_raw_non_null)]
/// #![allow(deprecated)]
///
/// use std::sync::Arc;
///
@@ -644,6 +645,7 @@ impl<T: ?Sized> Arc<T> {
/// assert_eq!(deref, "hello");
/// ```
#[unstable(feature = "rc_into_raw_non_null", issue = "47336")]
#[rustc_deprecated(since = "1.44.0", reason = "use `Arc::into_raw` instead")]
#[inline]
pub fn into_raw_non_null(this: Self) -> NonNull<T> {
// safe because Arc guarantees its pointer is non-null