/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
///
- /// It is up to the caller to ensure that the object is still alive when accessing it through
- /// the pointer.
- ///
- /// The pointer may be [`null`] or be dangling in case the object has already been destroyed.
+ /// The pointer is valid only if there are some strong references. The pointer may be dangling
+ /// or even [`null`] otherwise.
///
/// # Examples
///
/// This can be used to safely get a strong reference (by calling [`upgrade`]
/// later) or to deallocate the weak count by dropping the `Weak<T>`.
///
- /// It takes ownership of one weak count. In case a [`null`] is passed, a dangling [`Weak`] is
- /// returned.
+ /// It takes ownership of one weak count (with the exception of pointers created by [`new`],
+ /// as these don't have any corresponding weak count).
///
/// # Safety
///
- /// The pointer must represent one valid weak count. In other words, it must point to `T` which
- /// is or *was* managed by an [`Rc`] and the weak count of that [`Rc`] must not have reached
- /// 0. It is allowed for the strong count to be 0.
+ /// The pointer must have originated from the [`into_raw`] (or [`as_raw`], provided there was
+ /// a corresponding [`forget`] on the `Weak<T>`) and must still own its potential weak reference
+ /// count.
+ ///
+ /// It is allowed for the strong count to be 0 at the time of calling this, but the weak count
+ /// must be non-zero or the pointer must have originated from a dangling `Weak<T>` (one created
+ /// by [`new`]).
///
/// # Examples
///
/// assert!(unsafe { Weak::from_raw(raw_2) }.upgrade().is_none());
/// ```
///
- /// [`null`]: ../../std/ptr/fn.null.html
/// [`into_raw`]: struct.Weak.html#method.into_raw
/// [`upgrade`]: struct.Weak.html#method.upgrade
/// [`Rc`]: struct.Rc.html
/// [`Weak`]: struct.Weak.html
+ /// [`as_raw`]: struct.Weak.html#method.as_raw
+ /// [`new`]: struct.Weak.html#method.new
+ /// [`forget`]: ../../std/mem/fn.forget.html
#[unstable(feature = "weak_into_raw", issue = "60728")]
pub unsafe fn from_raw(ptr: *const T) -> Self {
if ptr.is_null() {
/// If `self` was created using [`Weak::new`], this will return 0.
///
/// [`Weak::new`]: #method.new
- #[unstable(feature = "weak_counts", issue = "57977")]
+ #[stable(feature = "weak_counts", since = "1.41.0")]
pub fn strong_count(&self) -> usize {
if let Some(inner) = self.inner() {
inner.strong()
/// Gets the number of `Weak` pointers pointing to this allocation.
///
- /// If `self` was created using [`Weak::new`], this will return `None`. If
- /// not, the returned value is at least 1, since `self` still points to the
- /// allocation.
- ///
- /// [`Weak::new`]: #method.new
- #[unstable(feature = "weak_counts", issue = "57977")]
- pub fn weak_count(&self) -> Option<usize> {
+ /// If no strong pointers remain, this will return zero.
+ #[stable(feature = "weak_counts", since = "1.41.0")]
+ pub fn weak_count(&self) -> usize {
self.inner().map(|inner| {
if inner.strong() > 0 {
inner.weak() - 1 // subtract the implicit weak ptr
} else {
- inner.weak()
+ 0
}
- })
+ }).unwrap_or(0)
}
/// Returns `None` when the pointer is dangling and there is no allocated `RcBox`
unsafe fn data_offset<T: ?Sized>(ptr: *const T) -> isize {
// Align the unsized value to the end of the `RcBox`.
// Because it is ?Sized, it will always be the last field in memory.
+ // Note: This is a detail of the current implementation of the compiler,
+ // and is not a guaranteed language detail. Do not rely on it outside of std.
data_offset_align(align_of_val(&*ptr))
}