From f4ded11b49aa24dcd8c0e114b427757b5d08dbe7 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Mon, 13 Apr 2020 19:08:33 +0200 Subject: [PATCH] weak-into-raw: Add {Arc,Rc}::as_ptr For consistency with Weak --- src/liballoc/rc.rs | 26 +++++++++++++++++++++++++- src/liballoc/sync.rs | 26 +++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 59424de4277..e106b4354e4 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -569,9 +569,33 @@ impl Rc { /// ``` #[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 = 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. diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 203b386ba1d..54df2b60857 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -566,9 +566,33 @@ impl Arc { /// ``` #[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 = 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.