Skip to content

Commit 4731510

Browse files
committed
weak-into-raw: Clarify some details in Safety
Clarify it is OK to pass a pointer that never owned a weak count (one from Weak::new) back into it as it was created from it. Relates to discussion in #60728.
1 parent 5a1d028 commit 4731510

File tree

2 files changed

+28
-20
lines changed

2 files changed

+28
-20
lines changed

src/liballoc/rc.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,10 +1619,8 @@ impl<T> Weak<T> {
16191619

16201620
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
16211621
///
1622-
/// It is up to the caller to ensure that the object is still alive when accessing it through
1623-
/// the pointer.
1624-
///
1625-
/// The pointer may be [`null`] or be dangling in case the object has already been destroyed.
1622+
/// The pointer is valid only if there are some strong references. The pointer may be dangling
1623+
/// or even [`null`] otherwise.
16261624
///
16271625
/// # Examples
16281626
///
@@ -1702,14 +1700,18 @@ impl<T> Weak<T> {
17021700
/// This can be used to safely get a strong reference (by calling [`upgrade`]
17031701
/// later) or to deallocate the weak count by dropping the `Weak<T>`.
17041702
///
1705-
/// It takes ownership of one weak count. In case a [`null`] is passed, a dangling [`Weak`] is
1706-
/// returned.
1703+
/// It takes ownership of one weak count (with the exception of pointers created by [`new`],
1704+
/// as these don't have any corresponding weak count).
17071705
///
17081706
/// # Safety
17091707
///
1710-
/// The pointer must represent one valid weak count. In other words, it must point to `T` which
1711-
/// is or *was* managed by an [`Rc`] and the weak count of that [`Rc`] must not have reached
1712-
/// 0. It is allowed for the strong count to be 0.
1708+
/// The pointer must have originated from the [`into_raw`] (or [`as_raw`], provided there was
1709+
/// a corresponding [`forget`] on the `Weak<T>`) and must still own its potential weak reference
1710+
/// count.
1711+
///
1712+
/// It is allowed for the strong count to be 0 at the time of calling this, but the weak count
1713+
/// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created
1714+
/// by [`new`]).
17131715
///
17141716
/// # Examples
17151717
///
@@ -1734,11 +1736,13 @@ impl<T> Weak<T> {
17341736
/// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none());
17351737
/// ```
17361738
///
1737-
/// [`null`]: ../../std/ptr/fn.null.html
17381739
/// [`into_raw`]: struct.Weak.html#method.into_raw
17391740
/// [`upgrade`]: struct.Weak.html#method.upgrade
17401741
/// [`Rc`]: struct.Rc.html
17411742
/// [`Weak`]: struct.Weak.html
1743+
/// [`as_raw`]: struct.Weak.html#method.as_raw
1744+
/// [`new`]: struct.Weak.html#method.new
1745+
/// [`forget`]: ../../std/mem/fn.forget.html
17421746
#[unstable(feature = "weak_into_raw", issue = "60728")]
17431747
pub unsafe fn from_raw(ptr: *const T) -> Self {
17441748
if ptr.is_null() {

src/liballoc/sync.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,10 +1295,8 @@ impl<T> Weak<T> {
12951295

12961296
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
12971297
///
1298-
/// It is up to the caller to ensure that the object is still alive when accessing it through
1299-
/// the pointer.
1300-
///
1301-
/// The pointer may be [`null`] or be dangling in case the object has already been destroyed.
1298+
/// The pointer is valid only if there are some strong references. The pointer may be dangling
1299+
/// or even [`null`] otherwise.
13021300
///
13031301
/// # Examples
13041302
///
@@ -1379,14 +1377,18 @@ impl<T> Weak<T> {
13791377
/// This can be used to safely get a strong reference (by calling [`upgrade`]
13801378
/// later) or to deallocate the weak count by dropping the `Weak<T>`.
13811379
///
1382-
/// It takes ownership of one weak count. In case a [`null`] is passed, a dangling [`Weak`] is
1383-
/// returned.
1380+
/// It takes ownership of one weak count (with the exception of pointers created by [`new`],
1381+
/// as these don't have any corresponding weak count).
13841382
///
13851383
/// # Safety
13861384
///
1387-
/// The pointer must represent one valid weak count. In other words, it must point to `T` which
1388-
/// is or *was* managed by an [`Arc`] and the weak count of that [`Arc`] must not have reached
1389-
/// 0. It is allowed for the strong count to be 0.
1385+
/// The pointer must have originated from the [`into_raw`] (or [`as_raw'], provided there was
1386+
/// a corresponding [`forget`] on the `Weak<T>`) and must still own its potential weak reference
1387+
/// count.
1388+
///
1389+
/// It is allowed for the strong count to be 0 at the time of calling this, but the weak count
1390+
/// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created
1391+
/// by [`new`]).
13901392
///
13911393
/// # Examples
13921394
///
@@ -1411,11 +1413,13 @@ impl<T> Weak<T> {
14111413
/// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none());
14121414
/// ```
14131415
///
1414-
/// [`null`]: ../../std/ptr/fn.null.html
1416+
/// [`as_raw`]: struct.Weak.html#method.as_raw
1417+
/// [`new`]: struct.Weak.html#method.new
14151418
/// [`into_raw`]: struct.Weak.html#method.into_raw
14161419
/// [`upgrade`]: struct.Weak.html#method.upgrade
14171420
/// [`Weak`]: struct.Weak.html
14181421
/// [`Arc`]: struct.Arc.html
1422+
/// [`forget`]: ../../std/mem/fn.forget.html
14191423
#[unstable(feature = "weak_into_raw", issue = "60728")]
14201424
pub unsafe fn from_raw(ptr: *const T) -> Self {
14211425
if ptr.is_null() {

0 commit comments

Comments
 (0)