Skip to content

Commit bcf992d

Browse files
authored
Rollup merge of rust-lang#66710 - vorner:weak-into-raw-null-docs, r=dtolnay
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 rust-lang#60728. @CAD97 Do you want to have a look at the new docs?
2 parents a0312c1 + 4731510 commit bcf992d

File tree

2 files changed

+28
-20
lines changed

2 files changed

+28
-20
lines changed

src/liballoc/rc.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -1648,10 +1648,8 @@ impl<T> Weak<T> {
16481648

16491649
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
16501650
///
1651-
/// It is up to the caller to ensure that the object is still alive when accessing it through
1652-
/// the pointer.
1653-
///
1654-
/// The pointer may be [`null`] or be dangling in case the object has already been destroyed.
1651+
/// The pointer is valid only if there are some strong references. The pointer may be dangling
1652+
/// or even [`null`] otherwise.
16551653
///
16561654
/// # Examples
16571655
///
@@ -1731,14 +1729,18 @@ impl<T> Weak<T> {
17311729
/// This can be used to safely get a strong reference (by calling [`upgrade`]
17321730
/// later) or to deallocate the weak count by dropping the `Weak<T>`.
17331731
///
1734-
/// It takes ownership of one weak count. In case a [`null`] is passed, a dangling [`Weak`] is
1735-
/// returned.
1732+
/// It takes ownership of one weak count (with the exception of pointers created by [`new`],
1733+
/// as these don't have any corresponding weak count).
17361734
///
17371735
/// # Safety
17381736
///
1739-
/// The pointer must represent one valid weak count. In other words, it must point to `T` which
1740-
/// is or *was* managed by an [`Rc`] and the weak count of that [`Rc`] must not have reached
1741-
/// 0. It is allowed for the strong count to be 0.
1737+
/// The pointer must have originated from the [`into_raw`] (or [`as_raw`], provided there was
1738+
/// a corresponding [`forget`] on the `Weak<T>`) and must still own its potential weak reference
1739+
/// count.
1740+
///
1741+
/// It is allowed for the strong count to be 0 at the time of calling this, but the weak count
1742+
/// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created
1743+
/// by [`new`]).
17421744
///
17431745
/// # Examples
17441746
///
@@ -1763,11 +1765,13 @@ impl<T> Weak<T> {
17631765
/// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none());
17641766
/// ```
17651767
///
1766-
/// [`null`]: ../../std/ptr/fn.null.html
17671768
/// [`into_raw`]: struct.Weak.html#method.into_raw
17681769
/// [`upgrade`]: struct.Weak.html#method.upgrade
17691770
/// [`Rc`]: struct.Rc.html
17701771
/// [`Weak`]: struct.Weak.html
1772+
/// [`as_raw`]: struct.Weak.html#method.as_raw
1773+
/// [`new`]: struct.Weak.html#method.new
1774+
/// [`forget`]: ../../std/mem/fn.forget.html
17711775
#[unstable(feature = "weak_into_raw", issue = "60728")]
17721776
pub unsafe fn from_raw(ptr: *const T) -> Self {
17731777
if ptr.is_null() {

src/liballoc/sync.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -1324,10 +1324,8 @@ impl<T> Weak<T> {
13241324

13251325
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
13261326
///
1327-
/// It is up to the caller to ensure that the object is still alive when accessing it through
1328-
/// the pointer.
1329-
///
1330-
/// The pointer may be [`null`] or be dangling in case the object has already been destroyed.
1327+
/// The pointer is valid only if there are some strong references. The pointer may be dangling
1328+
/// or even [`null`] otherwise.
13311329
///
13321330
/// # Examples
13331331
///
@@ -1408,14 +1406,18 @@ impl<T> Weak<T> {
14081406
/// This can be used to safely get a strong reference (by calling [`upgrade`]
14091407
/// later) or to deallocate the weak count by dropping the `Weak<T>`.
14101408
///
1411-
/// It takes ownership of one weak count. In case a [`null`] is passed, a dangling [`Weak`] is
1412-
/// returned.
1409+
/// It takes ownership of one weak count (with the exception of pointers created by [`new`],
1410+
/// as these don't have any corresponding weak count).
14131411
///
14141412
/// # Safety
14151413
///
1416-
/// The pointer must represent one valid weak count. In other words, it must point to `T` which
1417-
/// is or *was* managed by an [`Arc`] and the weak count of that [`Arc`] must not have reached
1418-
/// 0. It is allowed for the strong count to be 0.
1414+
/// The pointer must have originated from the [`into_raw`] (or [`as_raw'], provided there was
1415+
/// a corresponding [`forget`] on the `Weak<T>`) and must still own its potential weak reference
1416+
/// count.
1417+
///
1418+
/// It is allowed for the strong count to be 0 at the time of calling this, but the weak count
1419+
/// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created
1420+
/// by [`new`]).
14191421
///
14201422
/// # Examples
14211423
///
@@ -1440,11 +1442,13 @@ impl<T> Weak<T> {
14401442
/// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none());
14411443
/// ```
14421444
///
1443-
/// [`null`]: ../../std/ptr/fn.null.html
1445+
/// [`as_raw`]: struct.Weak.html#method.as_raw
1446+
/// [`new`]: struct.Weak.html#method.new
14441447
/// [`into_raw`]: struct.Weak.html#method.into_raw
14451448
/// [`upgrade`]: struct.Weak.html#method.upgrade
14461449
/// [`Weak`]: struct.Weak.html
14471450
/// [`Arc`]: struct.Arc.html
1451+
/// [`forget`]: ../../std/mem/fn.forget.html
14481452
#[unstable(feature = "weak_into_raw", issue = "60728")]
14491453
pub unsafe fn from_raw(ptr: *const T) -> Self {
14501454
if ptr.is_null() {

0 commit comments

Comments
 (0)