Skip to content

Commit 939c932

Browse files
authored
Rollup merge of #71168 - SimonSapin:into_raw_non_null, r=Amanieu
Deprecate `{Box,Rc,Arc}::into_raw_non_null` Per ongoing FCP at #47336 (comment) See also #47336 (comment)
2 parents 29fd528 + 7709d20 commit 939c932

File tree

5 files changed

+46
-31
lines changed

5 files changed

+46
-31
lines changed

src/liballoc/boxed.rs

+31-15
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,12 @@ impl<T: ?Sized> Box<T> {
428428
#[stable(feature = "box_raw", since = "1.4.0")]
429429
#[inline]
430430
pub fn into_raw(b: Box<T>) -> *mut T {
431-
Box::into_raw_non_null(b).as_ptr()
431+
// Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
432+
// raw pointer for the type system. Turning it directly into a raw pointer would not be
433+
// recognized as "releasing" the unique pointer to permit aliased raw accesses,
434+
// so all raw pointer methods go through `leak` which creates a (unique)
435+
// mutable reference. Turning *that* to a raw pointer behaves correctly.
436+
Box::leak(b) as *mut T
432437
}
433438

434439
/// Consumes the `Box`, returning the wrapped pointer as `NonNull<T>`.
@@ -451,6 +456,7 @@ impl<T: ?Sized> Box<T> {
451456
///
452457
/// ```
453458
/// #![feature(box_into_raw_non_null)]
459+
/// #![allow(deprecated)]
454460
///
455461
/// let x = Box::new(5);
456462
/// let ptr = Box::into_raw_non_null(x);
@@ -460,24 +466,34 @@ impl<T: ?Sized> Box<T> {
460466
/// let x = unsafe { Box::from_raw(ptr.as_ptr()) };
461467
/// ```
462468
#[unstable(feature = "box_into_raw_non_null", issue = "47336")]
469+
#[rustc_deprecated(
470+
since = "1.44.0",
471+
reason = "use `Box::leak(b).into()` or `NonNull::from(Box::leak(b))` instead"
472+
)]
463473
#[inline]
464474
pub fn into_raw_non_null(b: Box<T>) -> NonNull<T> {
465-
Box::into_unique(b).into()
466-
}
467-
468-
#[unstable(feature = "ptr_internals", issue = "none", reason = "use into_raw_non_null instead")]
475+
// Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
476+
// raw pointer for the type system. Turning it directly into a raw pointer would not be
477+
// recognized as "releasing" the unique pointer to permit aliased raw accesses,
478+
// so all raw pointer methods go through `leak` which creates a (unique)
479+
// mutable reference. Turning *that* to a raw pointer behaves correctly.
480+
Box::leak(b).into()
481+
}
482+
483+
#[unstable(
484+
feature = "ptr_internals",
485+
issue = "none",
486+
reason = "use `Box::leak(b).into()` or `Unique::from(Box::leak(b))` instead"
487+
)]
469488
#[inline]
470489
#[doc(hidden)]
471490
pub fn into_unique(b: Box<T>) -> Unique<T> {
472-
let b = mem::ManuallyDrop::new(b);
473-
let mut unique = b.0;
474-
// Box is kind-of a library type, but recognized as a "unique pointer" by
475-
// Stacked Borrows. This function here corresponds to "reborrowing to
476-
// a raw pointer", but there is no actual reborrow here -- so
477-
// without some care, the pointer we are returning here still carries
478-
// the tag of `b`, with `Unique` permission.
479-
// We round-trip through a mutable reference to avoid that.
480-
unsafe { Unique::new_unchecked(unique.as_mut() as *mut T) }
491+
// Box is recognized as a "unique pointer" by Stacked Borrows, but internally it is a
492+
// raw pointer for the type system. Turning it directly into a raw pointer would not be
493+
// recognized as "releasing" the unique pointer to permit aliased raw accesses,
494+
// so all raw pointer methods go through `leak` which creates a (unique)
495+
// mutable reference. Turning *that* to a raw pointer behaves correctly.
496+
Box::leak(b).into()
481497
}
482498

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

529545
/// Converts a `Box<T>` into a `Pin<Box<T>>`

src/liballoc/collections/linked_list.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ impl<T> LinkedList<T> {
143143
unsafe {
144144
node.next = self.head;
145145
node.prev = None;
146-
let node = Some(Box::into_raw_non_null(node));
146+
let node = Some(Box::leak(node).into());
147147

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

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

1136-
let node = Some(Box::into_raw_non_null(box Node {
1137-
next: Some(head),
1138-
prev: Some(prev),
1139-
element,
1140-
}));
1136+
let node = Some(
1137+
Box::leak(box Node { next: Some(head), prev: Some(prev), element }).into(),
1138+
);
11411139

11421140
// Not creating references to entire nodes to not invalidate the
11431141
// reference to `element` we handed to the user.
@@ -1450,7 +1448,7 @@ impl<'a, T> CursorMut<'a, T> {
14501448
#[unstable(feature = "linked_list_cursors", issue = "58533")]
14511449
pub fn insert_after(&mut self, item: T) {
14521450
unsafe {
1453-
let spliced_node = Box::into_raw_non_null(Box::new(Node::new(item)));
1451+
let spliced_node = Box::leak(Box::new(Node::new(item))).into();
14541452
let node_next = match self.current {
14551453
None => self.list.head,
14561454
Some(node) => node.as_ref().next,
@@ -1470,7 +1468,7 @@ impl<'a, T> CursorMut<'a, T> {
14701468
#[unstable(feature = "linked_list_cursors", issue = "58533")]
14711469
pub fn insert_before(&mut self, item: T) {
14721470
unsafe {
1473-
let spliced_node = Box::into_raw_non_null(Box::new(Node::new(item)));
1471+
let spliced_node = Box::leak(Box::new(Node::new(item))).into();
14741472
let node_prev = match self.current {
14751473
None => self.list.tail,
14761474
Some(node) => node.as_ref().prev,

src/liballoc/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@
7777
#![feature(allocator_api)]
7878
#![feature(allow_internal_unstable)]
7979
#![feature(arbitrary_self_types)]
80-
#![feature(box_into_raw_non_null)]
8180
#![feature(box_patterns)]
8281
#![feature(box_syntax)]
8382
#![feature(cfg_sanitize)]

src/liballoc/rc.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -324,11 +324,9 @@ impl<T> Rc<T> {
324324
// pointers, which ensures that the weak destructor never frees
325325
// the allocation while the strong destructor is running, even
326326
// if the weak pointer is stored inside the strong one.
327-
Self::from_inner(Box::into_raw_non_null(box RcBox {
328-
strong: Cell::new(1),
329-
weak: Cell::new(1),
330-
value,
331-
}))
327+
Self::from_inner(
328+
Box::leak(box RcBox { strong: Cell::new(1), weak: Cell::new(1), value }).into(),
329+
)
332330
}
333331

334332
/// Constructs a new `Rc` with uninitialized contents.
@@ -662,6 +660,7 @@ impl<T: ?Sized> Rc<T> {
662660
///
663661
/// ```
664662
/// #![feature(rc_into_raw_non_null)]
663+
/// #![allow(deprecated)]
665664
///
666665
/// use std::rc::Rc;
667666
///
@@ -671,6 +670,7 @@ impl<T: ?Sized> Rc<T> {
671670
/// assert_eq!(deref, "hello");
672671
/// ```
673672
#[unstable(feature = "rc_into_raw_non_null", issue = "47336")]
673+
#[rustc_deprecated(since = "1.44.0", reason = "use `Rc::into_raw` instead")]
674674
#[inline]
675675
pub fn into_raw_non_null(this: Self) -> NonNull<T> {
676676
// safe because Rc guarantees its pointer is non-null

src/liballoc/sync.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ impl<T> Arc<T> {
325325
weak: atomic::AtomicUsize::new(1),
326326
data,
327327
};
328-
Self::from_inner(Box::into_raw_non_null(x))
328+
Self::from_inner(Box::leak(x).into())
329329
}
330330

331331
/// Constructs a new `Arc` with uninitialized contents.
@@ -659,6 +659,7 @@ impl<T: ?Sized> Arc<T> {
659659
///
660660
/// ```
661661
/// #![feature(rc_into_raw_non_null)]
662+
/// #![allow(deprecated)]
662663
///
663664
/// use std::sync::Arc;
664665
///
@@ -668,6 +669,7 @@ impl<T: ?Sized> Arc<T> {
668669
/// assert_eq!(deref, "hello");
669670
/// ```
670671
#[unstable(feature = "rc_into_raw_non_null", issue = "47336")]
672+
#[rustc_deprecated(since = "1.44.0", reason = "use `Arc::into_raw` instead")]
671673
#[inline]
672674
pub fn into_raw_non_null(this: Self) -> NonNull<T> {
673675
// safe because Arc guarantees its pointer is non-null

0 commit comments

Comments
 (0)