Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rc: value -> allocation #65505

Merged
merged 5 commits into from
Oct 19, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 51 additions & 44 deletions src/liballoc/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
//!
//! The type [`Rc<T>`][`Rc`] provides shared ownership of a value of type `T`,
//! allocated in the heap. Invoking [`clone`][clone] on [`Rc`] produces a new
//! pointer to the same value in the heap. When the last [`Rc`] pointer to a
//! given value is destroyed, the pointed-to value is also destroyed.
//! pointer to the same allocation in the heap. When the last [`Rc`] pointer to a
//! given allocation is destroyed, the pointed-to value is also destroyed.
//!
//! Shared references in Rust disallow mutation by default, and [`Rc`]
//! is no exception: you cannot generally obtain a mutable reference to
Expand All @@ -21,7 +21,7 @@
//!
//! The [`downgrade`][downgrade] method can be used to create a non-owning
//! [`Weak`] pointer. A [`Weak`] pointer can be [`upgrade`][upgrade]d
//! to an [`Rc`], but this will return [`None`] if the value has
//! to an [`Rc`], but this will return [`None`] if the allocation has
//! already been dropped.
//!
//! A cycle between [`Rc`] pointers will never be deallocated. For this reason,
Expand All @@ -41,7 +41,7 @@
//! Rc::downgrade(&my_rc);
//! ```
//!
//! [`Weak<T>`][`Weak`] does not auto-dereference to `T`, because the value may have
//! [`Weak<T>`][`Weak`] does not auto-dereference to `T`, because the allocation may have
//! already been destroyed.
//!
//! # Cloning references
Expand Down Expand Up @@ -93,7 +93,7 @@
//! );
//!
//! // Create `Gadget`s belonging to `gadget_owner`. Cloning the `Rc<Owner>`
//! // value gives us a new pointer to the same `Owner` value, incrementing
//! // gives us a new pointer to the same `Owner` allocation, incrementing
//! // the reference count in the process.
//! let gadget1 = Gadget {
//! id: 1,
Expand All @@ -110,7 +110,7 @@
//! // Despite dropping `gadget_owner`, we're still able to print out the name
//! // of the `Owner` of the `Gadget`s. This is because we've only dropped a
//! // single `Rc<Owner>`, not the `Owner` it points to. As long as there are
//! // other `Rc<Owner>` values pointing at the same `Owner`, it will remain
//! // other `Rc<Owner>` pointing at the same `Owner`, it will remain
//! // allocated. The field projection `gadget1.owner.name` works because
//! // `Rc<Owner>` automatically dereferences to `Owner`.
//! println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name);
Expand All @@ -124,9 +124,9 @@
//!
//! If our requirements change, and we also need to be able to traverse from
//! `Owner` to `Gadget`, we will run into problems. An [`Rc`] pointer from `Owner`
//! to `Gadget` introduces a cycle between the values. This means that their
//! reference counts can never reach 0, and the values will remain allocated
//! forever: a memory leak. In order to get around this, we can use [`Weak`]
//! to `Gadget` introduces a cycle. This means that their
//! reference counts can never reach 0, and the allocation will never be destroyed:
//! a memory leak. In order to get around this, we can use [`Weak`]
//! pointers.
//!
//! Rust actually makes it somewhat difficult to produce this loop in the first
Expand Down Expand Up @@ -193,10 +193,10 @@
//! for gadget_weak in gadget_owner.gadgets.borrow().iter() {
//!
//! // `gadget_weak` is a `Weak<Gadget>`. Since `Weak` pointers can't
//! // guarantee the value is still allocated, we need to call
//! // guarantee the allocation still exists, we need to call
//! // `upgrade`, which returns an `Option<Rc<Gadget>>`.
//! //
//! // In this case we know the value still exists, so we simply
//! // In this case we know the allocation still exists, so we simply
//! // `unwrap` the `Option`. In a more complicated program, you might
//! // need graceful error handling for a `None` result.
//!
Expand Down Expand Up @@ -604,7 +604,7 @@ impl<T: ?Sized> Rc<T> {
unsafe { NonNull::new_unchecked(Rc::into_raw(this) as *mut _) }
}

/// Creates a new [`Weak`][weak] pointer to this value.
/// Creates a new [`Weak`][weak] pointer to this allocation.
///
/// [weak]: struct.Weak.html
///
Expand All @@ -625,7 +625,7 @@ impl<T: ?Sized> Rc<T> {
Weak { ptr: this.ptr }
}

/// Gets the number of [`Weak`][weak] pointers to this value.
/// Gets the number of [`Weak`][weak] pointers to this allocation.
///
/// [weak]: struct.Weak.html
///
Expand All @@ -645,7 +645,7 @@ impl<T: ?Sized> Rc<T> {
this.weak() - 1
}

/// Gets the number of strong (`Rc`) pointers to this value.
/// Gets the number of strong (`Rc`) pointers to this allocation.
///
/// # Examples
///
Expand All @@ -664,16 +664,16 @@ impl<T: ?Sized> Rc<T> {
}

/// Returns `true` if there are no other `Rc` or [`Weak`][weak] pointers to
/// this inner value.
/// this allocation.
///
/// [weak]: struct.Weak.html
#[inline]
fn is_unique(this: &Self) -> bool {
Rc::weak_count(this) == 0 && Rc::strong_count(this) == 1
}

/// Returns a mutable reference to the inner value, if there are
/// no other `Rc` or [`Weak`][weak] pointers to the same value.
/// Returns a mutable reference into the given `Rc`, if there are
/// no other `Rc` or [`Weak`][weak] pointers to the same allocation.
///
/// Returns [`None`] otherwise, because it is not safe to
/// mutate a shared value.
Expand Down Expand Up @@ -710,7 +710,7 @@ impl<T: ?Sized> Rc<T> {
}
}

/// Returns a mutable reference to the inner value,
/// Returns a mutable reference into the given `Rc`,
Centril marked this conversation as resolved.
Show resolved Hide resolved
/// without any check.
///
/// See also [`get_mut`], which is safe and does appropriate checks.
Expand All @@ -719,7 +719,7 @@ impl<T: ?Sized> Rc<T> {
///
/// # Safety
///
/// Any other `Rc` or [`Weak`] pointers to the same value must not be dereferenced
/// Any other `Rc` or [`Weak`] pointers to the same allocation must not be dereferenced
/// for the duration of the returned borrow.
/// This is trivially the case if no such pointers exist,
/// for example immediately after `Rc::new`.
Expand All @@ -745,8 +745,8 @@ impl<T: ?Sized> Rc<T> {

#[inline]
#[stable(feature = "ptr_eq", since = "1.17.0")]
/// Returns `true` if the two `Rc`s point to the same value (not
/// just values that compare as equal).
/// Returns `true` if the two `Rc`s point to the same allocation
/// (in a vein similar to [`ptr::eq`]).
///
/// # Examples
///
Expand All @@ -760,6 +760,8 @@ impl<T: ?Sized> Rc<T> {
/// assert!(Rc::ptr_eq(&five, &same_five));
/// assert!(!Rc::ptr_eq(&five, &other_five));
/// ```
///
/// [`ptr::eq`]: ../../std/ptr/fn.eq.html
pub fn ptr_eq(this: &Self, other: &Self) -> bool {
this.ptr.as_ptr() == other.ptr.as_ptr()
}
Expand All @@ -768,12 +770,12 @@ impl<T: ?Sized> Rc<T> {
impl<T: Clone> Rc<T> {
/// Makes a mutable reference into the given `Rc`.
///
/// If there are other `Rc` pointers to the same value, then `make_mut` will
/// [`clone`] the inner value to ensure unique ownership. This is also
/// If there are other `Rc` pointers to the same allocation, then `make_mut` will
/// [`clone`] the inner value to a new allocation to ensure unique ownership. This is also
/// referred to as clone-on-write.
///
/// If there are no other `Rc` pointers to this value, then [`Weak`]
/// pointers to this value will be disassociated.
/// If there are no other `Rc` pointers to this allocation, then [`Weak`]
/// pointers to this allocation will be disassociated.
///
/// See also [`get_mut`], which will fail rather than cloning.
///
Expand All @@ -794,7 +796,7 @@ impl<T: Clone> Rc<T> {
/// *Rc::make_mut(&mut data) += 1; // Won't clone anything
/// *Rc::make_mut(&mut other_data) *= 2; // Won't clone anything
///
/// // Now `data` and `other_data` point to different values.
/// // Now `data` and `other_data` point to different allocations.
/// assert_eq!(*data, 8);
/// assert_eq!(*other_data, 12);
/// ```
Expand Down Expand Up @@ -837,7 +839,7 @@ impl<T: Clone> Rc<T> {
// returned is the *only* pointer that will ever be returned to T. Our
// reference count is guaranteed to be 1 at this point, and we required
// the `Rc<T>` itself to be `mut`, so we're returning the only possible
// reference to the inner value.
// reference to the allocation.
unsafe {
&mut this.ptr.as_mut().value
}
Expand Down Expand Up @@ -1111,7 +1113,7 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Rc<T> {
impl<T: ?Sized> Clone for Rc<T> {
/// Makes a clone of the `Rc` pointer.
///
/// This creates another pointer to the same inner value, increasing the
/// This creates another pointer to the same allocation, increasing the
/// strong reference count.
///
/// # Examples
Expand Down Expand Up @@ -1189,9 +1191,11 @@ impl<T: ?Sized + Eq> RcEqIdent<T> for Rc<T> {
impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
/// Equality for two `Rc`s.
///
/// Two `Rc`s are equal if their inner values are equal.
/// Two `Rc`s are equal if their inner values are equal, even if they are
/// stored in different allocation.
///
/// If `T` also implements `Eq`, two `Rc`s that point to the same value are
/// If `T` also implements `Eq` (implying reflexivity of equality),
/// two `Rc`s that point to the same allocation are
/// always equal.
///
/// # Examples
Expand All @@ -1212,7 +1216,8 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> {
///
/// Two `Rc`s are unequal if their inner values are unequal.
///
/// If `T` also implements `Eq`, two `Rc`s that point to the same value are
/// If `T` also implements `Eq` (implying reflexivity of equality),
/// two `Rc`s that point to the same allocation are
/// never unequal.
///
/// # Examples
Expand Down Expand Up @@ -1541,16 +1546,16 @@ impl<'a, T: 'a + Clone> RcFromIter<&'a T, slice::Iter<'a, T>> for Rc<[T]> {
}

/// `Weak` is a version of [`Rc`] that holds a non-owning reference to the
/// managed value. The value is accessed by calling [`upgrade`] on the `Weak`
/// managed allocation. The allocation is accessed by calling [`upgrade`] on the `Weak`
/// pointer, which returns an [`Option`]`<`[`Rc`]`<T>>`.
///
/// Since a `Weak` reference does not count towards ownership, it will not
/// prevent the inner value from being dropped, and `Weak` itself makes no
/// prevent the value stored in the allocation from being dropped, and `Weak` itself makes no
/// guarantees about the value still being present and may return [`None`]
/// when [`upgrade`]d.
///
/// A `Weak` pointer is useful for keeping a temporary reference to the value
/// within [`Rc`] without extending its lifetime. It is also used to prevent
/// A `Weak` pointer is useful for keeping a temporary reference to the allocation
/// managed by [`Rc`] without extending its lifetime. It is also used to prevent
/// circular references between [`Rc`] pointers, since mutual owning references
/// would never allow either [`Rc`] to be dropped. For example, a tree could
/// have strong [`Rc`] pointers from parent nodes to children, and `Weak`
Expand Down Expand Up @@ -1751,9 +1756,9 @@ pub(crate) fn is_dangling<T: ?Sized>(ptr: NonNull<T>) -> bool {

impl<T: ?Sized> Weak<T> {
/// Attempts to upgrade the `Weak` pointer to an [`Rc`], extending
/// the lifetime of the value if successful.
/// the lifetime of the allocation if successful.
///
/// Returns [`None`] if the value has since been dropped.
/// Returns [`None`] if the value stored in the allocation has since been dropped.
///
/// [`Rc`]: struct.Rc.html
/// [`None`]: ../../std/option/enum.Option.html
Expand Down Expand Up @@ -1787,7 +1792,7 @@ impl<T: ?Sized> Weak<T> {
}
}

/// Gets the number of strong (`Rc`) pointers pointing to this value.
/// Gets the number of strong (`Rc`) pointers pointing to this allocation.
///
/// If `self` was created using [`Weak::new`], this will return 0.
///
Expand All @@ -1801,11 +1806,11 @@ impl<T: ?Sized> Weak<T> {
}
}

/// Gets the number of `Weak` pointers pointing to this value.
/// 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
/// value.
/// allocation.
///
/// [`Weak::new`]: #method.new
#[unstable(feature = "weak_counts", issue = "57977")]
Expand All @@ -1830,14 +1835,14 @@ impl<T: ?Sized> Weak<T> {
}
}

/// Returns `true` if the two `Weak`s point to the same value (not just
/// values that compare as equal), or if both don't point to any value
/// Returns `true` if the two `Weak`s point to the same allocation (similar to
/// [`ptr::eq`]), or if both don't point to any allocation
/// (because they were created with `Weak::new()`).
///
/// # Notes
///
/// Since this compares pointers it means that `Weak::new()` will equal each
/// other, even though they don't point to any value.
/// other, even though they don't point to any allocation.
///
/// # Examples
///
Expand Down Expand Up @@ -1869,6 +1874,8 @@ impl<T: ?Sized> Weak<T> {
/// let third = Rc::downgrade(&third_rc);
/// assert!(!first.ptr_eq(&third));
/// ```
///
/// [`ptr::eq`]: ../../std/ptr/fn.eq.html
#[inline]
#[stable(feature = "weak_ptr_eq", since = "1.39.0")]
pub fn ptr_eq(&self, other: &Self) -> bool {
Expand Down Expand Up @@ -1918,7 +1925,7 @@ impl<T: ?Sized> Drop for Weak<T> {

#[stable(feature = "rc_weak", since = "1.4.0")]
impl<T: ?Sized> Clone for Weak<T> {
/// Makes a clone of the `Weak` pointer that points to the same value.
/// Makes a clone of the `Weak` pointer that points to the same allocation.
///
/// # Examples
///
Expand Down