@@ -569,9 +569,33 @@ impl<T: ?Sized> Rc<T> {
569569 /// ```
570570 #[ stable( feature = "rc_raw" , since = "1.17.0" ) ]
571571 pub fn into_raw ( this : Self ) -> * const T {
572+ let ptr = Self :: as_ptr ( & this) ;
573+ mem:: forget ( this) ;
574+ ptr
575+ }
576+
577+ /// Provides a raw pointer to the data.
578+ ///
579+ /// The counts are not affected in any way and the `Rc` is not consumed. The pointer is valid
580+ /// for as long there are strong counts in the `Rc`.
581+ ///
582+ /// # Examples
583+ ///
584+ /// ```
585+ /// #![feature(weak_into_raw)]
586+ ///
587+ /// use std::rc::Rc;
588+ ///
589+ /// let x = Rc::new("hello".to_owned());
590+ /// let y = Rc::clone(&x);
591+ /// let x_ptr = Rc::as_ptr(&x);
592+ /// assert_eq!(x_ptr, Rc::as_ptr(&y));
593+ /// assert_eq!(unsafe { &*x_ptr }, "hello");
594+ /// ```
595+ #[ unstable( feature = "weak_into_raw" , issue = "60728" ) ]
596+ pub fn as_ptr ( this : & Self ) -> * const T {
572597 let ptr: * mut RcBox < T > = NonNull :: as_ptr ( this. ptr ) ;
573598 let fake_ptr = ptr as * mut T ;
574- mem:: forget ( this) ;
575599
576600 // SAFETY: This cannot go through Deref::deref.
577601 // Instead, we manually offset the pointer rather than manifesting a reference.
@@ -1644,8 +1668,8 @@ impl<T> Weak<T> {
16441668
16451669 /// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
16461670 ///
1647- /// The pointer is valid only if there are some strong references. The pointer may be dangling
1648- /// or even [`null`] otherwise.
1671+ /// The pointer is valid only if there are some strong references. The pointer may be dangling,
1672+ /// unaligned or even [`null`] otherwise.
16491673 ///
16501674 /// # Examples
16511675 ///
@@ -1658,31 +1682,22 @@ impl<T> Weak<T> {
16581682 /// let strong = Rc::new("hello".to_owned());
16591683 /// let weak = Rc::downgrade(&strong);
16601684 /// // Both point to the same object
1661- /// assert!(ptr::eq(&*strong, weak.as_raw ()));
1685+ /// assert!(ptr::eq(&*strong, weak.as_ptr ()));
16621686 /// // The strong here keeps it alive, so we can still access the object.
1663- /// assert_eq!("hello", unsafe { &*weak.as_raw () });
1687+ /// assert_eq!("hello", unsafe { &*weak.as_ptr () });
16641688 ///
16651689 /// drop(strong);
1666- /// // But not any more. We can do weak.as_raw (), but accessing the pointer would lead to
1690+ /// // But not any more. We can do weak.as_ptr (), but accessing the pointer would lead to
16671691 /// // undefined behaviour.
1668- /// // assert_eq!("hello", unsafe { &*weak.as_raw () });
1692+ /// // assert_eq!("hello", unsafe { &*weak.as_ptr () });
16691693 /// ```
16701694 ///
16711695 /// [`null`]: ../../std/ptr/fn.null.html
16721696 #[ unstable( feature = "weak_into_raw" , issue = "60728" ) ]
1673- pub fn as_raw ( & self ) -> * const T {
1674- match self . inner ( ) {
1675- None => ptr:: null ( ) ,
1676- Some ( inner) => {
1677- let offset = data_offset_sized :: < T > ( ) ;
1678- let ptr = inner as * const RcBox < T > ;
1679- // Note: while the pointer we create may already point to dropped value, the
1680- // allocation still lives (it must hold the weak point as long as we are alive).
1681- // Therefore, the offset is OK to do, it won't get out of the allocation.
1682- let ptr = unsafe { ( ptr as * const u8 ) . offset ( offset) } ;
1683- ptr as * const T
1684- }
1685- }
1697+ pub fn as_ptr ( & self ) -> * const T {
1698+ let offset = data_offset_sized :: < T > ( ) ;
1699+ let ptr = self . ptr . cast :: < u8 > ( ) . as_ptr ( ) . wrapping_offset ( offset) ;
1700+ ptr as * const T
16861701 }
16871702
16881703 /// Consumes the `Weak<T>` and turns it into a raw pointer.
@@ -1691,7 +1706,7 @@ impl<T> Weak<T> {
16911706 /// can be turned back into the `Weak<T>` with [`from_raw`].
16921707 ///
16931708 /// The same restrictions of accessing the target of the pointer as with
1694- /// [`as_raw `] apply.
1709+ /// [`as_ptr `] apply.
16951710 ///
16961711 /// # Examples
16971712 ///
@@ -1712,10 +1727,10 @@ impl<T> Weak<T> {
17121727 /// ```
17131728 ///
17141729 /// [`from_raw`]: struct.Weak.html#method.from_raw
1715- /// [`as_raw `]: struct.Weak.html#method.as_raw
1730+ /// [`as_ptr `]: struct.Weak.html#method.as_ptr
17161731 #[ unstable( feature = "weak_into_raw" , issue = "60728" ) ]
17171732 pub fn into_raw ( self ) -> * const T {
1718- let result = self . as_raw ( ) ;
1733+ let result = self . as_ptr ( ) ;
17191734 mem:: forget ( self ) ;
17201735 result
17211736 }
@@ -1730,9 +1745,8 @@ impl<T> Weak<T> {
17301745 ///
17311746 /// # Safety
17321747 ///
1733- /// The pointer must have originated from the [`into_raw`] (or [`as_raw`], provided there was
1734- /// a corresponding [`forget`] on the `Weak<T>`) and must still own its potential weak reference
1735- /// count.
1748+ /// The pointer must have originated from the [`into_raw`] and must still own its potential
1749+ /// weak reference count.
17361750 ///
17371751 /// It is allowed for the strong count to be 0 at the time of calling this, but the weak count
17381752 /// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created
@@ -1765,7 +1779,6 @@ impl<T> Weak<T> {
17651779 /// [`upgrade`]: struct.Weak.html#method.upgrade
17661780 /// [`Rc`]: struct.Rc.html
17671781 /// [`Weak`]: struct.Weak.html
1768- /// [`as_raw`]: struct.Weak.html#method.as_raw
17691782 /// [`new`]: struct.Weak.html#method.new
17701783 /// [`forget`]: ../../std/mem/fn.forget.html
17711784 #[ unstable( feature = "weak_into_raw" , issue = "60728" ) ]
0 commit comments