Skip to content
Closed
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
190589f
Use structured suggestion for restricting bounds
estebank Oct 7, 2019
5b7ffd9
Handle more cases
estebank Oct 8, 2019
dbd75c8
Handle more cases involving `impl` and `trait`
estebank Oct 8, 2019
99ab45b
Handle `Self` restriction needed
estebank Oct 8, 2019
ca1885d
Update some tests involving `Self`
estebank Oct 8, 2019
b81df6b
Consider trait aliases
estebank Oct 8, 2019
daa8491
Update NLL tests
estebank Oct 8, 2019
5cc99ee
Handle missing projection restriction
estebank Oct 9, 2019
bc744bc
Suggest associated bound restrictions in `impl`s
estebank Oct 9, 2019
ab7d8f0
Deduplicate some code and apply review comments
estebank Oct 10, 2019
39a9e2e
Remove useless `help`
estebank Oct 10, 2019
8cabb42
Remove trailing whitespace
estebank Oct 10, 2019
9c525ee
review comments
estebank Oct 15, 2019
9ed463a
Do not suggest restriction on spans originating in macros
estebank Oct 15, 2019
9ecd1d2
Simplify code
estebank Oct 15, 2019
c6dce78
Fix comparison after rebase
estebank Oct 15, 2019
470e9d2
Rc: value -> allocation
RalfJung Oct 17, 2019
868a772
more consistency and clarification
RalfJung Oct 17, 2019
5697432
BTreeSet symmetric_difference & union optimized, cleaned
ssomers Oct 8, 2019
696cba6
the exampleis about drop, not (de)allocation
RalfJung Oct 19, 2019
fac34eb
bump miri
RalfJung Oct 19, 2019
52a31f7
some more Rc tweaks
RalfJung Oct 19, 2019
1b38463
do all the same edits with Arc
RalfJung Oct 19, 2019
ef8ac78
Rollup merge of #65192 - estebank:restrict-bound, r=matthewjasper
Centril Oct 19, 2019
7c0186a
Rollup merge of #65226 - ssomers:master, r=bluss
Centril Oct 19, 2019
df2c324
Rollup merge of #65505 - RalfJung:rc, r=Centril
Centril Oct 19, 2019
a9d40b4
Rollup merge of #65594 - RalfJung:miri, r=RalfJung
Centril Oct 19, 2019
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
Prev Previous commit
Next Next commit
Rc: value -> allocation
  • Loading branch information
RalfJung committed Oct 17, 2019
commit 470e9d2789cf589b701594ce69b76bb530c67483
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`,
/// 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