Skip to content

Commit

Permalink
weak-into-raw: Add {Arc,Rc}::as_ptr
Browse files Browse the repository at this point in the history
For consistency with Weak
  • Loading branch information
vorner committed Apr 19, 2020
1 parent 80ccddc commit f4ded11
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 2 deletions.
26 changes: 25 additions & 1 deletion src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,9 +569,33 @@ impl<T: ?Sized> Rc<T> {
/// ```
#[stable(feature = "rc_raw", since = "1.17.0")]
pub fn into_raw(this: Self) -> *const T {
let ptr = Self::as_ptr(&this);
mem::forget(this);
ptr
}

/// Provides a raw pointer to the data.
///
/// The counts are not affected in any way and the `Rc` is not consumed. The pointer is valid
/// for as long there are strong counts in the `Rc`.
///
/// # Examples
///
/// ```
/// #![feature(weak_into_raw)]
///
/// use std::rc::Rc;
///
/// let x = Rc::new("hello".to_owned());
/// let y = Rc::clone(&x);
/// let x_ptr = Rc::as_ptr(&x);
/// assert_eq!(x_ptr, Rc::as_ptr(&y));
/// assert_eq!(unsafe { &*x_ptr }, "hello");
/// ```
#[unstable(feature = "weak_into_raw", issue = "60728")]
pub fn as_ptr(this: &Self) -> *const T {
let ptr: *mut RcBox<T> = NonNull::as_ptr(this.ptr);
let fake_ptr = ptr as *mut T;
mem::forget(this);

// SAFETY: This cannot go through Deref::deref.
// Instead, we manually offset the pointer rather than manifesting a reference.
Expand Down
26 changes: 25 additions & 1 deletion src/liballoc/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,9 +566,33 @@ impl<T: ?Sized> Arc<T> {
/// ```
#[stable(feature = "rc_raw", since = "1.17.0")]
pub fn into_raw(this: Self) -> *const T {
let ptr = Self::as_ptr(&this);
mem::forget(this);
ptr
}

/// Provides a raw pointer to the data.
///
/// The counts are not affected in way and the `Arc` is not consumed. The pointer is valid for
/// as long as there are strong counts in the `Arc`.
///
/// # Examples
///
/// ```
/// #![feature(weak_into_raw)]
///
/// use std::sync::Arc;
///
/// let x = Arc::new("hello".to_owned());
/// let y = Arc::clone(&x);
/// let x_ptr = Arc::as_ptr(&x);
/// assert_eq!(x_ptr, Arc::as_ptr(&y));
/// assert_eq!(unsafe { &*x_ptr }, "hello");
/// ```
#[unstable(feature = "weak_into_raw", issue = "60728")]
pub fn as_ptr(this: &Self) -> *const T {
let ptr: *mut ArcInner<T> = NonNull::as_ptr(this.ptr);
let fake_ptr = ptr as *mut T;
mem::forget(this);

// SAFETY: This cannot go through Deref::deref.
// Instead, we manually offset the pointer rather than manifesting a reference.
Expand Down

0 comments on commit f4ded11

Please sign in to comment.