@@ -569,9 +569,33 @@ impl<T: ?Sized> Rc<T> {
569
569
/// ```
570
570
#[ stable( feature = "rc_raw" , since = "1.17.0" ) ]
571
571
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 {
572
597
let ptr: * mut RcBox < T > = NonNull :: as_ptr ( this. ptr ) ;
573
598
let fake_ptr = ptr as * mut T ;
574
- mem:: forget ( this) ;
575
599
576
600
// SAFETY: This cannot go through Deref::deref.
577
601
// Instead, we manually offset the pointer rather than manifesting a reference.
@@ -1644,8 +1668,8 @@ impl<T> Weak<T> {
1644
1668
1645
1669
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
1646
1670
///
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.
1649
1673
///
1650
1674
/// # Examples
1651
1675
///
@@ -1658,31 +1682,22 @@ impl<T> Weak<T> {
1658
1682
/// let strong = Rc::new("hello".to_owned());
1659
1683
/// let weak = Rc::downgrade(&strong);
1660
1684
/// // Both point to the same object
1661
- /// assert!(ptr::eq(&*strong, weak.as_raw ()));
1685
+ /// assert!(ptr::eq(&*strong, weak.as_ptr ()));
1662
1686
/// // 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 () });
1664
1688
///
1665
1689
/// 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
1667
1691
/// // undefined behaviour.
1668
- /// // assert_eq!("hello", unsafe { &*weak.as_raw () });
1692
+ /// // assert_eq!("hello", unsafe { &*weak.as_ptr () });
1669
1693
/// ```
1670
1694
///
1671
1695
/// [`null`]: ../../std/ptr/fn.null.html
1672
1696
#[ 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
1686
1701
}
1687
1702
1688
1703
/// Consumes the `Weak<T>` and turns it into a raw pointer.
@@ -1691,7 +1706,7 @@ impl<T> Weak<T> {
1691
1706
/// can be turned back into the `Weak<T>` with [`from_raw`].
1692
1707
///
1693
1708
/// The same restrictions of accessing the target of the pointer as with
1694
- /// [`as_raw `] apply.
1709
+ /// [`as_ptr `] apply.
1695
1710
///
1696
1711
/// # Examples
1697
1712
///
@@ -1712,10 +1727,10 @@ impl<T> Weak<T> {
1712
1727
/// ```
1713
1728
///
1714
1729
/// [`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
1716
1731
#[ unstable( feature = "weak_into_raw" , issue = "60728" ) ]
1717
1732
pub fn into_raw ( self ) -> * const T {
1718
- let result = self . as_raw ( ) ;
1733
+ let result = self . as_ptr ( ) ;
1719
1734
mem:: forget ( self ) ;
1720
1735
result
1721
1736
}
@@ -1730,9 +1745,8 @@ impl<T> Weak<T> {
1730
1745
///
1731
1746
/// # Safety
1732
1747
///
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.
1736
1750
///
1737
1751
/// It is allowed for the strong count to be 0 at the time of calling this, but the weak count
1738
1752
/// 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> {
1765
1779
/// [`upgrade`]: struct.Weak.html#method.upgrade
1766
1780
/// [`Rc`]: struct.Rc.html
1767
1781
/// [`Weak`]: struct.Weak.html
1768
- /// [`as_raw`]: struct.Weak.html#method.as_raw
1769
1782
/// [`new`]: struct.Weak.html#method.new
1770
1783
/// [`forget`]: ../../std/mem/fn.forget.html
1771
1784
#[ unstable( feature = "weak_into_raw" , issue = "60728" ) ]
0 commit comments