diff options
| author | Marcin Fatyga <marcinf@google.com> | 2016-11-01 15:26:22 +0100 |
|---|---|---|
| committer | Marcin Fatyga <marcinf@google.com> | 2016-11-01 15:26:22 +0100 |
| commit | 655effedf25e2039d283b839429bf2f42b7012a4 (patch) | |
| tree | 34fd087d891556c70a14b26a90d1bdccd0a7ccb2 /src/liballoc | |
| parent | 4e2822c5c28bb342e5862ba7cc0b90b865c68be1 (diff) | |
| parent | ac968c466451cb9aafd9e8598ddb396ed0e6fe31 (diff) | |
| download | rust-655effedf25e2039d283b839429bf2f42b7012a4.tar.gz rust-655effedf25e2039d283b839429bf2f42b7012a4.zip | |
Merge branch 'master' of https://github.com/rust-lang/rust
Conflicts: src/libcoretest/lib.rs
Diffstat (limited to 'src/liballoc')
| -rw-r--r-- | src/liballoc/arc.rs | 429 | ||||
| -rw-r--r-- | src/liballoc/boxed.rs | 8 | ||||
| -rw-r--r-- | src/liballoc/lib.rs | 1 | ||||
| -rw-r--r-- | src/liballoc/raw_vec.rs | 15 | ||||
| -rw-r--r-- | src/liballoc/rc.rs | 510 |
5 files changed, 638 insertions, 325 deletions
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 5f9ccd1820c..7a07e007ce1 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -10,35 +10,11 @@ #![stable(feature = "rust1", since = "1.0.0")] -//! Threadsafe reference-counted boxes (the `Arc<T>` type). +//! Thread-safe reference-counting pointers. //! -//! The `Arc<T>` type provides shared ownership of an immutable value through -//! atomic reference counting. +//! See the [`Arc<T>`][arc] documentation for more details. //! -//! `Weak<T>` is a weak reference to the `Arc<T>` box, and it is created by -//! the `downgrade` method. -//! # Examples -//! -//! Sharing some immutable data between threads: -//! -// Note that we **do not** run these tests here. The windows builders get super -// unhappy of a thread outlives the main thread and then exits at the same time -// (something deadlocks) so we just avoid this entirely by not running these -// tests. -//! ```no_run -//! use std::sync::Arc; -//! use std::thread; -//! -//! let five = Arc::new(5); -//! -//! for _ in 0..10 { -//! let five = five.clone(); -//! -//! thread::spawn(move || { -//! println!("{:?}", five); -//! }); -//! } -//! ``` +//! [arc]: struct.Arc.html use boxed::Box; @@ -62,72 +38,114 @@ use heap::deallocate; const MAX_REFCOUNT: usize = (isize::MAX) as usize; -/// An atomically reference counted wrapper for shared state. -/// Destruction is deterministic, and will occur as soon as the last owner is -/// gone. It is marked as `Send` because it uses atomic reference counting. +/// A thread-safe reference-counting pointer. /// -/// If you do not need thread-safety, and just need shared ownership, consider -/// the [`Rc<T>` type](../rc/struct.Rc.html). It is the same as `Arc<T>`, but -/// does not use atomics, making it both thread-unsafe as well as significantly -/// faster when updating the reference count. +/// The type `Arc<T>` provides shared ownership of a value of type `T`, +/// allocated in the heap. Invoking [`clone`][clone] on `Arc` produces +/// a new pointer to the same value in the heap. When the last `Arc` +/// pointer to a given value is destroyed, the pointed-to value is +/// also destroyed. /// -/// Note: the inherent methods defined on `Arc<T>` are all associated functions, -/// which means that you have to call them as e.g. `Arc::get_mut(&value)` -/// instead of `value.get_mut()`. This is so that there are no conflicts with -/// methods on the inner type `T`, which are what you want to call in the -/// majority of cases. +/// Shared references in Rust disallow mutation by default, and `Arc` is no +/// exception. If you need to mutate through an `Arc`, use [`Mutex`][mutex], +/// [`RwLock`][rwlock], or one of the [`Atomic`][atomic] types. /// -/// # Examples +/// `Arc` uses atomic operations for reference counting, so `Arc`s can be +/// sent between threads. In other words, `Arc<T>` implements [`Send`][send] +/// as long as `T` implements `Send` and [`Sync`][sync]. The disadvantage is +/// that atomic operations are more expensive than ordinary memory accesses. +/// If you are not sharing reference-counted values between threads, consider +/// using [`rc::Rc`][rc] for lower overhead. `Rc` is a safe default, because +/// the compiler will catch any attempt to send an `Rc` between threads. +/// However, a library might choose `Arc` in order to give library consumers +/// more flexibility. +/// +/// The [`downgrade`][downgrade] method can be used to create a non-owning +/// [`Weak`][weak] pointer. A `Weak` pointer can be [`upgrade`][upgrade]d +/// to an `Arc`, but this will return [`None`][option] if the value has +/// already been dropped. /// -/// In this example, a large vector of data will be shared by several threads. First we -/// wrap it with a `Arc::new` and then clone the `Arc<T>` reference for every thread (which will -/// increase the reference count atomically). +/// A cycle between `Arc` pointers will never be deallocated. For this reason, +/// `Weak` is used to break cycles. For example, a tree could have strong +/// `Arc` pointers from parent nodes to children, and `Weak` pointers from +/// children back to their parents. +/// +/// `Arc<T>` automatically dereferences to `T` (via the [`Deref`][deref] trait), +/// so you can call `T`'s methods on a value of type `Arc<T>`. To avoid name +/// clashes with `T`'s methods, the methods of `Arc<T>` itself are [associated +/// functions][assoc], called using function-like syntax: /// /// ``` /// use std::sync::Arc; -/// use std::thread; +/// let my_arc = Arc::new(()); +/// +/// Arc::downgrade(&my_arc); +/// ``` /// -/// fn main() { -/// let numbers: Vec<_> = (0..100).collect(); -/// let shared_numbers = Arc::new(numbers); +/// `Weak<T>` does not auto-dereference to `T`, because the value may have +/// already been destroyed. /// -/// for _ in 0..10 { -/// // prepare a copy of reference here and it will be moved to the thread -/// let child_numbers = shared_numbers.clone(); +/// [arc]: struct.Arc.html +/// [weak]: struct.Weak.html +/// [rc]: ../../std/rc/struct.Rc.html +/// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone +/// [mutex]: ../../std/sync/struct.Mutex.html +/// [rwlock]: ../../std/sync/struct.RwLock.html +/// [atomic]: ../../std/sync/atomic/index.html +/// [send]: ../../std/marker/trait.Send.html +/// [sync]: ../../std/marker/trait.Sync.html +/// [deref]: ../../std/ops/trait.Deref.html +/// [downgrade]: struct.Arc.html#method.downgrade +/// [upgrade]: struct.Weak.html#method.upgrade +/// [option]: ../../std/option/enum.Option.html +/// [assoc]: ../../book/method-syntax.html#associated-functions /// -/// thread::spawn(move || { -/// let local_numbers = &child_numbers[..]; +/// # Examples /// -/// // Work with the local numbers -/// }); -/// } -/// } -/// ``` -/// You can also share mutable data between threads safely -/// by putting it inside `Mutex` and then share `Mutex` immutably -/// with `Arc<T>` as shown below. +/// Sharing some immutable data between threads: /// -// See comment at the top of this file for why the test is no_run +// Note that we **do not** run these tests here. The windows builders get super +// unhappy if a thread outlives the main thread and then exits at the same time +// (something deadlocks) so we just avoid this entirely by not running these +// tests. /// ```no_run -/// use std::sync::{Arc, Mutex}; +/// use std::sync::Arc; /// use std::thread; /// -/// let five = Arc::new(Mutex::new(5)); +/// let five = Arc::new(5); /// /// for _ in 0..10 { /// let five = five.clone(); /// /// thread::spawn(move || { -/// let mut number = five.lock().unwrap(); +/// println!("{:?}", five); +/// }); +/// } +/// ``` /// -/// *number += 1; +/// Sharing a mutable `AtomicUsize`: /// -/// println!("{}", *number); // prints 6 +/// ```no_run +/// use std::sync::Arc; +/// use std::sync::atomic::{AtomicUsize, Ordering}; +/// use std::thread; +/// +/// let val = Arc::new(AtomicUsize::new(5)); +/// +/// for _ in 0..10 { +/// let val = val.clone(); +/// +/// thread::spawn(move || { +/// let v = val.fetch_add(1, Ordering::SeqCst); +/// println!("{:?}", v); /// }); /// } /// ``` - -#[cfg_attr(stage0, unsafe_no_drop_flag)] +/// +/// See the [`rc` documentation][rc_examples] for more examples of reference +/// counting in general. +/// +/// [rc_examples]: ../../std/rc/index.html#examples #[stable(feature = "rust1", since = "1.0.0")] pub struct Arc<T: ?Sized> { ptr: Shared<ArcInner<T>>, @@ -141,19 +159,18 @@ unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {} #[unstable(feature = "coerce_unsized", issue = "27732")] impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {} -/// A weak pointer to an `Arc`. +/// A weak version of [`Arc`][arc]. /// -/// Weak pointers will not keep the data inside of the `Arc` alive, and can be -/// used to break cycles between `Arc` pointers. +/// `Weak` pointers do not count towards determining if the inner value +/// should be dropped. /// -/// A `Weak<T>` pointer can be upgraded to an `Arc<T>` pointer, but -/// will return `None` if the value has already been dropped. +/// The typical way to obtain a `Weak` pointer is to call +/// [`Arc::downgrade`][downgrade]. /// -/// For example, a tree with parent pointers can be represented by putting the -/// nodes behind strong `Arc<T>` pointers, and then storing the parent pointers -/// as `Weak<T>` pointers. - -#[cfg_attr(stage0, unsafe_no_drop_flag)] +/// See the [`Arc`][arc] documentation for more details. +/// +/// [arc]: struct.Arc.html +/// [downgrade]: struct.Arc.html#method.downgrade #[stable(feature = "arc_weak", since = "1.4.0")] pub struct Weak<T: ?Sized> { ptr: Shared<ArcInner<T>>, @@ -211,12 +228,15 @@ impl<T> Arc<T> { Arc { ptr: unsafe { Shared::new(Box::into_raw(x)) } } } - /// Unwraps the contained value if the `Arc<T>` has exactly one strong reference. + /// Returns the contained value, if the `Arc` has exactly one strong reference. /// - /// Otherwise, an `Err` is returned with the same `Arc<T>`. + /// Otherwise, an [`Err`][result] is returned with the same `Arc` that was + /// passed in. /// /// This will succeed even if there are outstanding weak references. /// + /// [result]: ../../std/result/enum.Result.html + /// /// # Examples /// /// ``` @@ -227,7 +247,7 @@ impl<T> Arc<T> { /// /// let x = Arc::new(4); /// let _y = x.clone(); - /// assert_eq!(Arc::try_unwrap(x), Err(Arc::new(4))); + /// assert_eq!(*Arc::try_unwrap(x).unwrap_err(), 4); /// ``` #[inline] #[stable(feature = "arc_unique", since = "1.4.0")] @@ -253,7 +273,9 @@ impl<T> Arc<T> { } impl<T: ?Sized> Arc<T> { - /// Downgrades the `Arc<T>` to a `Weak<T>` reference. + /// Creates a new [`Weak`][weak] pointer to this value. + /// + /// [weak]: struct.Weak.html /// /// # Examples /// @@ -291,7 +313,27 @@ impl<T: ?Sized> Arc<T> { } } - /// Get the number of weak references to this value. + /// Gets the number of [`Weak`][weak] pointers to this value. + /// + /// Be careful how you use this information, because another thread + /// may change the weak count at any time. + /// + /// [weak]: struct.Weak.html + /// + /// # Examples + /// + /// ``` + /// #![feature(arc_counts)] + /// + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// let _weak_five = Arc::downgrade(&five); + /// + /// // This assertion is deterministic because we haven't shared + /// // the `Arc` or `Weak` between threads. + /// assert_eq!(1, Arc::weak_count(&five)); + /// ``` #[inline] #[unstable(feature = "arc_counts", reason = "not clearly useful, and racy", issue = "28356")] @@ -299,7 +341,25 @@ impl<T: ?Sized> Arc<T> { this.inner().weak.load(SeqCst) - 1 } - /// Get the number of strong references to this value. + /// Gets the number of strong (`Arc`) pointers to this value. + /// + /// Be careful how you use this information, because another thread + /// may change the strong count at any time. + /// + /// # Examples + /// + /// ``` + /// #![feature(arc_counts)] + /// + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// let _also_five = five.clone(); + /// + /// // This assertion is deterministic because we haven't shared + /// // the `Arc` between threads. + /// assert_eq!(2, Arc::strong_count(&five)); + /// ``` #[inline] #[unstable(feature = "arc_counts", reason = "not clearly useful, and racy", issue = "28356")] @@ -336,8 +396,8 @@ impl<T: ?Sized> Arc<T> { #[unstable(feature = "ptr_eq", reason = "newly added", issue = "36497")] - /// Return whether two `Arc` references point to the same value - /// (not just values that compare equal). + /// Returns true if the two `Arc`s point to the same value (not + /// just values that compare as equal). /// /// # Examples /// @@ -362,9 +422,10 @@ impl<T: ?Sized> Arc<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized> Clone for Arc<T> { - /// Makes a clone of the `Arc<T>`. + /// Makes a clone of the `Arc` pointer. /// - /// This increases the strong reference count. + /// This creates another pointer to the same inner value, increasing the + /// strong reference count. /// /// # Examples /// @@ -420,11 +481,17 @@ impl<T: ?Sized> Deref for Arc<T> { } impl<T: Clone> Arc<T> { - /// Make a mutable reference into the given `Arc<T>`. - /// If the `Arc<T>` has more than one strong reference, or any weak - /// references, the inner data is cloned. + /// Makes a mutable reference into the given `Arc`. + /// + /// If there are other `Arc` or [`Weak`][weak] pointers to the same value, + /// then `make_mut` will invoke [`clone`][clone] on the inner value to + /// ensure unique ownership. This is also referred to as clone-on-write. + /// + /// See also [`get_mut`][get_mut], which will fail rather than cloning. /// - /// This is also referred to as a copy-on-write. + /// [weak]: struct.Weak.html + /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone + /// [get_mut]: struct.Arc.html#method.get_mut /// /// # Examples /// @@ -439,10 +506,9 @@ impl<T: Clone> Arc<T> { /// *Arc::make_mut(&mut data) += 1; // Won't clone anything /// *Arc::make_mut(&mut other_data) *= 2; // Won't clone anything /// - /// // Note: data and other_data now point to different numbers + /// // Now `data` and `other_data` point to different values. /// assert_eq!(*data, 8); /// assert_eq!(*other_data, 12); - /// /// ``` #[inline] #[stable(feature = "arc_unique", since = "1.4.0")] @@ -501,8 +567,19 @@ impl<T: Clone> Arc<T> { } impl<T: ?Sized> Arc<T> { - /// Returns a mutable reference to the contained value if the `Arc<T>` has - /// one strong reference and no weak references. + /// Returns a mutable reference to the inner value, if there are + /// no other `Arc` or [`Weak`][weak] pointers to the same value. + /// + /// Returns [`None`][option] otherwise, because it is not safe to + /// mutate a shared value. + /// + /// See also [`make_mut`][make_mut], which will [`clone`][clone] + /// the inner value when it's shared. + /// + /// [weak]: struct.Weak.html + /// [option]: ../../std/option/enum.Option.html + /// [make_mut]: struct.Arc.html#method.make_mut + /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone /// /// # Examples /// @@ -564,30 +641,32 @@ impl<T: ?Sized> Arc<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized> Drop for Arc<T> { - /// Drops the `Arc<T>`. + /// Drops the `Arc`. /// /// This will decrement the strong reference count. If the strong reference - /// count becomes zero and the only other references are `Weak<T>` ones, - /// `drop`s the inner value. + /// count reaches zero then the only other references (if any) are + /// [`Weak`][weak], so we `drop` the inner value. + /// + /// [weak]: struct.Weak.html /// /// # Examples /// /// ``` /// use std::sync::Arc; /// - /// { - /// let five = Arc::new(5); - /// - /// // stuff + /// struct Foo; /// - /// drop(five); // explicit drop + /// impl Drop for Foo { + /// fn drop(&mut self) { + /// println!("dropped!"); + /// } /// } - /// { - /// let five = Arc::new(5); /// - /// // stuff + /// let foo = Arc::new(Foo); + /// let foo2 = foo.clone(); /// - /// } // implicit drop + /// drop(foo); // Doesn't print anything + /// drop(foo2); // Prints "dropped!" /// ``` #[unsafe_destructor_blind_to_params] #[inline] @@ -625,10 +704,14 @@ impl<T: ?Sized> Drop for Arc<T> { } impl<T> Weak<T> { - /// Constructs a new `Weak<T>` without an accompanying instance of T. + /// Constructs a new `Weak<T>`, without an accompanying instance of `T`. /// - /// This allocates memory for T, but does not initialize it. Calling - /// Weak<T>::upgrade() on the return value always gives None. + /// This allocates memory for `T`, but does not initialize it. Calling + /// [`upgrade`][upgrade] on the return value always gives + /// [`None`][option]. + /// + /// [upgrade]: struct.Weak.html#method.upgrade + /// [option]: ../../std/option/enum.Option.html /// /// # Examples /// @@ -636,6 +719,7 @@ impl<T> Weak<T> { /// use std::sync::Weak; /// /// let empty: Weak<i64> = Weak::new(); + /// assert!(empty.upgrade().is_none()); /// ``` #[stable(feature = "downgraded_weak", since = "1.10.0")] pub fn new() -> Weak<T> { @@ -652,12 +736,13 @@ impl<T> Weak<T> { } impl<T: ?Sized> Weak<T> { - /// Upgrades a weak reference to a strong reference. + /// Upgrades the `Weak` pointer to an [`Arc`][arc], if possible. /// - /// Upgrades the `Weak<T>` reference to an `Arc<T>`, if possible. + /// Returns [`None`][option] if the strong count has reached zero and the + /// inner value was destroyed. /// - /// Returns `None` if there were no strong references and the data was - /// destroyed. + /// [arc]: struct.Arc.html + /// [option]: ../../std/option/enum.Option.html /// /// # Examples /// @@ -669,6 +754,13 @@ impl<T: ?Sized> Weak<T> { /// let weak_five = Arc::downgrade(&five); /// /// let strong_five: Option<Arc<_>> = weak_five.upgrade(); + /// assert!(strong_five.is_some()); + /// + /// // Destroy all strong pointers. + /// drop(strong_five); + /// drop(five); + /// + /// assert!(weak_five.upgrade().is_none()); /// ``` #[stable(feature = "arc_weak", since = "1.4.0")] pub fn upgrade(&self) -> Option<Arc<T>> { @@ -711,9 +803,10 @@ impl<T: ?Sized> Weak<T> { #[stable(feature = "arc_weak", since = "1.4.0")] impl<T: ?Sized> Clone for Weak<T> { - /// Makes a clone of the `Weak<T>`. + /// Makes a clone of the `Weak` pointer. /// - /// This increases the weak reference count. + /// This creates another pointer to the same inner value, increasing the + /// weak reference count. /// /// # Examples /// @@ -745,7 +838,23 @@ impl<T: ?Sized> Clone for Weak<T> { #[stable(feature = "downgraded_weak", since = "1.10.0")] impl<T> Default for Weak<T> { - /// Constructs a new `Weak<T>` without an accompanying instance of T. + /// Constructs a new `Weak<T>`, without an accompanying instance of `T`. + /// + /// This allocates memory for `T`, but does not initialize it. Calling + /// [`upgrade`][upgrade] on the return value always gives + /// [`None`][option]. + /// + /// [upgrade]: struct.Weak.html#method.upgrade + /// [option]: ../../std/option/enum.Option.html + /// + /// # Examples + /// + /// ``` + /// use std::sync::Weak; + /// + /// let empty: Weak<i64> = Default::default(); + /// assert!(empty.upgrade().is_none()); + /// ``` fn default() -> Weak<T> { Weak::new() } @@ -753,7 +862,7 @@ impl<T> Default for Weak<T> { #[stable(feature = "arc_weak", since = "1.4.0")] impl<T: ?Sized> Drop for Weak<T> { - /// Drops the `Weak<T>`. + /// Drops the `Weak` pointer. /// /// This will decrement the weak reference count. /// @@ -762,21 +871,22 @@ impl<T: ?Sized> Drop for Weak<T> { /// ``` /// use std::sync::Arc; /// - /// { - /// let five = Arc::new(5); - /// let weak_five = Arc::downgrade(&five); - /// - /// // stuff + /// struct Foo; /// - /// drop(weak_five); // explicit drop + /// impl Drop for Foo { + /// fn drop(&mut self) { + /// println!("dropped!"); + /// } /// } - /// { - /// let five = Arc::new(5); - /// let weak_five = Arc::downgrade(&five); /// - /// // stuff + /// let foo = Arc::new(Foo); + /// let weak_foo = Arc::downgrade(&foo); + /// let other_weak_foo = weak_foo.clone(); /// - /// } // implicit drop + /// drop(weak_foo); // Doesn't print anything + /// drop(foo); // Prints "dropped!" + /// + /// assert!(other_weak_foo.upgrade().is_none()); /// ``` fn drop(&mut self) { let ptr = *self.ptr; @@ -798,9 +908,9 @@ impl<T: ?Sized> Drop for Weak<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized + PartialEq> PartialEq for Arc<T> { - /// Equality for two `Arc<T>`s. + /// Equality for two `Arc`s. /// - /// Two `Arc<T>`s are equal if their inner value are equal. + /// Two `Arc`s are equal if their inner values are equal. /// /// # Examples /// @@ -809,15 +919,15 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> { /// /// let five = Arc::new(5); /// - /// five == Arc::new(5); + /// assert!(five == Arc::new(5)); /// ``` fn eq(&self, other: &Arc<T>) -> bool { *(*self) == *(*other) } - /// Inequality for two `Arc<T>`s. + /// Inequality for two `Arc`s. /// - /// Two `Arc<T>`s are unequal if their inner value are unequal. + /// Two `Arc`s are unequal if their inner values are unequal. /// /// # Examples /// @@ -826,7 +936,7 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> { /// /// let five = Arc::new(5); /// - /// five != Arc::new(5); + /// assert!(five != Arc::new(6)); /// ``` fn ne(&self, other: &Arc<T>) -> bool { *(*self) != *(*other) @@ -834,7 +944,7 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> { } #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> { - /// Partial comparison for two `Arc<T>`s. + /// Partial comparison for two `Arc`s. /// /// The two are compared by calling `partial_cmp()` on their inner values. /// @@ -842,16 +952,17 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> { /// /// ``` /// use std::sync::Arc; + /// use std::cmp::Ordering; /// /// let five = Arc::new(5); /// - /// five.partial_cmp(&Arc::new(5)); + /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&Arc::new(6))); /// ``` fn partial_cmp(&self, other: &Arc<T>) -> Option<Ordering> { (**self).partial_cmp(&**other) } - /// Less-than comparison for two `Arc<T>`s. + /// Less-than comparison for two `Arc`s. /// /// The two are compared by calling `<` on their inner values. /// @@ -862,13 +973,13 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> { /// /// let five = Arc::new(5); /// - /// five < Arc::new(5); + /// assert!(five < Arc::new(6)); /// ``` fn lt(&self, other: &Arc<T>) -> bool { *(*self) < *(*other) } - /// 'Less-than or equal to' comparison for two `Arc<T>`s. + /// 'Less than or equal to' comparison for two `Arc`s. /// /// The two are compared by calling `<=` on their inner values. /// @@ -879,13 +990,13 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> { /// /// let five = Arc::new(5); /// - /// five <= Arc::new(5); + /// assert!(five <= Arc::new(5)); /// ``` fn le(&self, other: &Arc<T>) -> bool { *(*self) <= *(*other) } - /// Greater-than comparison for two `Arc<T>`s. + /// Greater-than comparison for two `Arc`s. /// /// The two are compared by calling `>` on their inner values. /// @@ -896,13 +1007,13 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> { /// /// let five = Arc::new(5); /// - /// five > Arc::new(5); + /// assert!(five > Arc::new(4)); /// ``` fn gt(&self, other: &Arc<T>) -> bool { *(*self) > *(*other) } - /// 'Greater-than or equal to' comparison for two `Arc<T>`s. + /// 'Greater than or equal to' comparison for two `Arc`s. /// /// The two are compared by calling `>=` on their inner values. /// @@ -913,7 +1024,7 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> { /// /// let five = Arc::new(5); /// - /// five >= Arc::new(5); + /// assert!(five >= Arc::new(5)); /// ``` fn ge(&self, other: &Arc<T>) -> bool { *(*self) >= *(*other) @@ -921,6 +1032,20 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> { } #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized + Ord> Ord for Arc<T> { + /// Comparison for two `Arc`s. + /// + /// The two are compared by calling `cmp()` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// use std::cmp::Ordering; + /// + /// let five = Arc::new(5); + /// + /// assert_eq!(Ordering::Less, five.cmp(&Arc::new(6))); + /// ``` fn cmp(&self, other: &Arc<T>) -> Ordering { (**self).cmp(&**other) } @@ -951,7 +1076,16 @@ impl<T: ?Sized> fmt::Pointer for Arc<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: Default> Default for Arc<T> { - /// Creates a new `Arc<T>`, with the `Default` value for T. + /// Creates a new `Arc<T>`, with the `Default` value for `T`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let x: Arc<i32> = Default::default(); + /// assert_eq!(*x, 0); + /// ``` fn default() -> Arc<T> { Arc::new(Default::default()) } @@ -1002,6 +1136,7 @@ mod tests { } #[test] + #[cfg_attr(target_os = "emscripten", ignore)] fn manually_share_arc() { let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let arc_v = Arc::new(v); diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index bc9b6e805ef..28f4dda1408 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -244,12 +244,14 @@ impl<T: ?Sized> Box<T> { /// the destructor of `T` and free the allocated memory. Since the /// way `Box` allocates and releases memory is unspecified, the /// only valid pointer to pass to this function is the one taken - /// from another `Box` via the `Box::into_raw` function. + /// from another `Box` via the [`Box::into_raw`] function. /// /// This function is unsafe because improper use may lead to /// memory problems. For example, a double-free may occur if the /// function is called twice on the same raw pointer. /// + /// [`Box::into_raw`]: struct.Box.html#method.into_raw + /// /// # Examples /// /// ``` @@ -269,12 +271,14 @@ impl<T: ?Sized> Box<T> { /// memory previously managed by the `Box`. In particular, the /// caller should properly destroy `T` and release the memory. The /// proper way to do so is to convert the raw pointer back into a - /// `Box` with the `Box::from_raw` function. + /// `Box` with the [`Box::from_raw`] function. /// /// Note: this is an associated function, which means that you have /// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This /// is so that there is no conflict with a method on the inner type. /// + /// [`Box::from_raw`]: struct.Box.html#method.from_raw + /// /// # Examples /// /// ``` diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index c6453da3f46..31491106d97 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -88,7 +88,6 @@ #![feature(staged_api)] #![feature(unboxed_closures)] #![feature(unique)] -#![cfg_attr(stage0, feature(unsafe_no_drop_flag))] #![feature(unsize)] #![cfg_attr(not(test), feature(fused, fn_traits, placement_new_protocol))] diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index 23542215fa8..f23ea0ea8bf 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -44,7 +44,6 @@ use core::cmp; /// `shrink_to_fit`, and `from_box` will actually set RawVec's private capacity /// field. This allows zero-sized types to not be special-cased by consumers of /// this type. -#[cfg_attr(stage0, unsafe_no_drop_flag)] pub struct RawVec<T> { ptr: Unique<T>, cap: usize, @@ -58,11 +57,7 @@ impl<T> RawVec<T> { pub fn new() -> Self { unsafe { // !0 is usize::MAX. This branch should be stripped at compile time. - let cap = if mem::size_of::<T>() == 0 { - !0 - } else { - 0 - }; + let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 }; // heap::EMPTY doubles as "unallocated" and "zero-sized allocation" RawVec { @@ -210,11 +205,7 @@ impl<T> RawVec<T> { let (new_cap, ptr) = if self.cap == 0 { // skip to 4 because tiny Vec's are dumb; but not if that would cause overflow - let new_cap = if elem_size > (!0) / 8 { - 1 - } else { - 4 - }; + let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 }; let ptr = heap::allocate(new_cap * elem_size, align); (new_cap, ptr) } else { @@ -348,7 +339,7 @@ impl<T> RawVec<T> { let elem_size = mem::size_of::<T>(); // Nothing we can really do about these checks :( let required_cap = used_cap.checked_add(needed_extra_cap) - .expect("capacity overflow"); + .expect("capacity overflow"); // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`. let double_cap = self.cap * 2; // `double_cap` guarantees exponential growth. diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 32e5587ff41..740d13c4762 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -10,90 +10,139 @@ #![allow(deprecated)] -//! Unsynchronized reference-counted boxes (the `Rc<T>` type) which are usable -//! only within a single thread. +//! Single-threaded reference-counting pointers. //! -//! The `Rc<T>` type provides shared ownership of an immutable value. -//! Destruction is deterministic, and will occur as soon as the last owner is -//! gone. It is marked as non-sendable because it avoids the overhead of atomic -//! reference counting. +//! 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. //! -//! The `downgrade` method can be used to create a non-owning `Weak<T>` pointer -//! to the box. A `Weak<T>` pointer can be upgraded to an `Rc<T>` pointer, but -//! will return `None` if the value has already been dropped. +//! Shared references in Rust disallow mutation by default, and `Rc` is no +//! exception. If you need to mutate through an `Rc`, use [`Cell`][cell] or +//! [`RefCell`][refcell]. //! -//! For example, a tree with parent pointers can be represented by putting the -//! nodes behind strong `Rc<T>` pointers, and then storing the parent pointers -//! as `Weak<T>` pointers. +//! `Rc` uses non-atomic reference counting. This means that overhead is very +//! low, but an `Rc` cannot be sent between threads, and consequently `Rc` +//! does not implement [`Send`][send]. As a result, the Rust compiler +//! will check *at compile time* that you are not sending `Rc`s between +//! threads. If you need multi-threaded, atomic reference counting, use +//! [`sync::Arc`][arc]. +//! +//! The [`downgrade`][downgrade] method can be used to create a non-owning +//! [`Weak`][weak] pointer. A `Weak` pointer can be [`upgrade`][upgrade]d +//! to an `Rc`, but this will return [`None`][option] if the value has +//! already been dropped. +//! +//! A cycle between `Rc` pointers will never be deallocated. For this reason, +//! `Weak` is used to break cycles. For example, a tree could have strong +//! `Rc` pointers from parent nodes to children, and `Weak` pointers from +//! children back to their parents. +//! +//! `Rc<T>` automatically dereferences to `T` (via the [`Deref`][deref] trait), +//! so you can call `T`'s methods on a value of type `Rc<T>`. To avoid name +//! clashes with `T`'s methods, the methods of `Rc<T>` itself are [associated +//! functions][assoc], called using function-like syntax: +//! +//! ``` +//! use std::rc::Rc; +//! let my_rc = Rc::new(()); +//! +//! Rc::downgrade(&my_rc); +//! ``` +//! +//! `Weak<T>` does not auto-dereference to `T`, because the value may have +//! already been destroyed. +//! +//! [rc]: struct.Rc.html +//! [weak]: struct.Weak.html +//! [clone]: ../../std/clone/trait.Clone.html#tymethod.clone +//! [cell]: ../../std/cell/struct.Cell.html +//! [refcell]: ../../std/cell/struct.RefCell.html +//! [send]: ../../std/marker/trait.Send.html +//! [arc]: ../../std/sync/struct.Arc.html +//! [deref]: ../../std/ops/trait.Deref.html +//! [downgrade]: struct.Rc.html#method.downgrade +//! [upgrade]: struct.Weak.html#method.upgrade +//! [option]: ../../std/option/enum.Option.html +//! [assoc]: ../../book/method-syntax.html#associated-functions //! //! # Examples //! //! Consider a scenario where a set of `Gadget`s are owned by a given `Owner`. //! We want to have our `Gadget`s point to their `Owner`. We can't do this with //! unique ownership, because more than one gadget may belong to the same -//! `Owner`. `Rc<T>` allows us to share an `Owner` between multiple `Gadget`s, +//! `Owner`. `Rc` allows us to share an `Owner` between multiple `Gadget`s, //! and have the `Owner` remain allocated as long as any `Gadget` points at it. //! -//! ```rust +//! ``` //! use std::rc::Rc; //! //! struct Owner { -//! name: String +//! name: String, //! // ...other fields //! } //! //! struct Gadget { //! id: i32, -//! owner: Rc<Owner> +//! owner: Rc<Owner>, //! // ...other fields //! } //! //! fn main() { -//! // Create a reference counted Owner. -//! let gadget_owner : Rc<Owner> = Rc::new( -//! Owner { name: String::from("Gadget Man") } +//! // Create a reference-counted `Owner`. +//! let gadget_owner: Rc<Owner> = Rc::new( +//! Owner { +//! name: "Gadget Man".to_string(), +//! } //! ); //! -//! // Create Gadgets belonging to gadget_owner. To increment the reference -//! // count we clone the `Rc<T>` object. -//! let gadget1 = Gadget { id: 1, owner: gadget_owner.clone() }; -//! let gadget2 = Gadget { id: 2, owner: gadget_owner.clone() }; +//! // Create `Gadget`s belonging to `gadget_owner`. Cloning the `Rc<Owner>` +//! // value gives us a new pointer to the same `Owner` value, incrementing +//! // the reference count in the process. +//! let gadget1 = Gadget { +//! id: 1, +//! owner: gadget_owner.clone(), +//! }; +//! let gadget2 = Gadget { +//! id: 2, +//! owner: gadget_owner.clone(), +//! }; //! +//! // Dispose of our local variable `gadget_owner`. //! drop(gadget_owner); //! -//! // Despite dropping gadget_owner, we're still able to print out the name -//! // of the Owner of the Gadgets. This is because we've only dropped the -//! // reference count object, not the Owner it wraps. As long as there are -//! // other `Rc<T>` objects pointing at the same Owner, it will remain -//! // allocated. Notice that the `Rc<T>` wrapper around Gadget.owner gets -//! // automatically dereferenced for us. +//! // 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 +//! // allocated. The field projection `gadget1.owner.name` works because +//! // `Rc<Owner>` automatically dereferences to `Owner`. //! println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name); //! println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name); //! -//! // At the end of the method, gadget1 and gadget2 get destroyed, and with -//! // them the last counted references to our Owner. Gadget Man now gets -//! // destroyed as well. +//! // At the end of the function, `gadget1` and `gadget2` are destroyed, and +//! // with them the last counted references to our `Owner`. Gadget Man now +//! // gets destroyed as well. //! } //! ``` //! //! If our requirements change, and we also need to be able to traverse from -//! Owner → Gadget, we will run into problems: an `Rc<T>` pointer from Owner -//! → Gadget introduces a cycle between the objects. This means that their -//! reference counts can never reach 0, and the objects will remain allocated: a -//! memory leak. In order to get around this, we can use `Weak<T>` pointers. -//! These pointers don't contribute to the total count. +//! `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` +//! pointers. //! //! Rust actually makes it somewhat difficult to produce this loop in the first -//! place: in order to end up with two objects that point at each other, one of -//! them needs to be mutable. This is problematic because `Rc<T>` enforces -//! memory safety by only giving out shared references to the object it wraps, +//! place. In order to end up with two values that point at each other, one of +//! them needs to be mutable. This is difficult because `Rc` enforces +//! memory safety by only giving out shared references to the value it wraps, //! and these don't allow direct mutation. We need to wrap the part of the -//! object we wish to mutate in a `RefCell`, which provides *interior +//! value we wish to mutate in a [`RefCell`][refcell], which provides *interior //! mutability*: a method to achieve mutability through a shared reference. -//! `RefCell` enforces Rust's borrowing rules at runtime. Read the `Cell` -//! documentation for more details on interior mutability. +//! `RefCell` enforces Rust's borrowing rules at runtime. //! -//! ```rust +//! ``` //! use std::rc::Rc; //! use std::rc::Weak; //! use std::cell::RefCell; @@ -111,41 +160,58 @@ //! } //! //! fn main() { -//! // Create a reference counted Owner. Note the fact that we've put the -//! // Owner's vector of Gadgets inside a RefCell so that we can mutate it -//! // through a shared reference. -//! let gadget_owner : Rc<Owner> = Rc::new( +//! // Create a reference-counted `Owner`. Note that we've put the `Owner`'s +//! // vector of `Gadget`s inside a `RefCell` so that we can mutate it through +//! // a shared reference. +//! let gadget_owner: Rc<Owner> = Rc::new( //! Owner { //! name: "Gadget Man".to_string(), -//! gadgets: RefCell::new(Vec::new()), +//! gadgets: RefCell::new(vec![]), +//! } +//! ); +//! +//! // Create `Gadget`s belonging to `gadget_owner`, as before. +//! let gadget1 = Rc::new( +//! Gadget { +//! id: 1, +//! owner: gadget_owner.clone(), +//! } +//! ); +//! let gadget2 = Rc::new( +//! Gadget { +//! id: 2, +//! owner: gadget_owner.clone(), //! } //! ); //! -//! // Create Gadgets belonging to gadget_owner as before. -//! let gadget1 = Rc::new(Gadget{id: 1, owner: gadget_owner.clone()}); -//! let gadget2 = Rc::new(Gadget{id: 2, owner: gadget_owner.clone()}); +//! // Add the `Gadget`s to their `Owner`. +//! { +//! let mut gadgets = gadget_owner.gadgets.borrow_mut(); +//! gadgets.push(Rc::downgrade(&gadget1)); +//! gadgets.push(Rc::downgrade(&gadget2)); //! -//! // Add the Gadgets to their Owner. To do this we mutably borrow from -//! // the RefCell holding the Owner's Gadgets. -//! gadget_owner.gadgets.borrow_mut().push(Rc::downgrade(&gadget1)); -//! gadget_owner.gadgets.borrow_mut().push(Rc::downgrade(&gadget2)); +//! // `RefCell` dynamic borrow ends here. +//! } //! -//! // Iterate over our Gadgets, printing their details out -//! for gadget_opt in gadget_owner.gadgets.borrow().iter() { +//! // Iterate over our `Gadget`s, printing their details out. +//! for gadget_weak in gadget_owner.gadgets.borrow().iter() { //! -//! // gadget_opt is a Weak<Gadget>. Since weak pointers can't guarantee -//! // that their object is still allocated, we need to call upgrade() -//! // on them to turn them into a strong reference. This returns an -//! // Option, which contains a reference to our object if it still -//! // exists. -//! let gadget = gadget_opt.upgrade().unwrap(); +//! // `gadget_weak` is a `Weak<Gadget>`. Since `Weak` pointers can't +//! // guarantee the value is still allocated, we need to call +//! // `upgrade`, which returns an `Option<Rc<Gadget>>`. +//! // +//! // In this case we know the value still exists, so we simply +//! // `unwrap` the `Option`. In a more complicated program, you might +//! // need graceful error handling for a `None` result. +//! +//! let gadget = gadget_weak.upgrade().unwrap(); //! println!("Gadget {} owned by {}", gadget.id, gadget.owner.name); //! } //! -//! // At the end of the method, gadget_owner, gadget1 and gadget2 get -//! // destroyed. There are now no strong (`Rc<T>`) references to the gadgets. -//! // Once they get destroyed, the Gadgets get destroyed. This zeroes the -//! // reference count on Gadget Man, they get destroyed as well. +//! // At the end of the function, `gadget_owner`, `gadget1`, and `gadget2` +//! // are destroyed. There are now no strong (`Rc`) pointers to the +//! // gadgets, so they are destroyed. This zeroes the reference count on +//! // Gadget Man, so he gets destroyed as well. //! } //! ``` @@ -164,13 +230,14 @@ use core::hash::{Hash, Hasher}; use core::intrinsics::{abort, assume}; use core::marker; use core::marker::Unsize; -use core::mem::{self, align_of_val, forget, size_of_val, uninitialized}; +use core::mem::{self, align_of_val, forget, size_of, size_of_val, uninitialized}; use core::ops::Deref; use core::ops::CoerceUnsized; use core::ptr::{self, Shared}; use core::convert::From; use heap::deallocate; +use raw_vec::RawVec; struct RcBox<T: ?Sized> { strong: Cell<usize>, @@ -179,16 +246,14 @@ struct RcBox<T: ?Sized> { } -/// A reference-counted pointer type over an immutable value. +/// A single-threaded reference-counting pointer. /// -/// See the [module level documentation](./index.html) for more details. +/// See the [module-level documentation](./index.html) for more details. /// -/// Note: the inherent methods defined on `Rc<T>` are all associated functions, -/// which means that you have to call them as e.g. `Rc::get_mut(&value)` instead -/// of `value.get_mut()`. This is so that there are no conflicts with methods -/// on the inner type `T`, which are what you want to call in the majority of -/// cases. -#[cfg_attr(stage0, unsafe_no_drop_flag)] +/// The inherent methods of `Rc` are all associated functions, which means +/// that you have to call them as e.g. `Rc::get_mut(&value)` instead of +/// `value.get_mut()`. This avoids conflicts with methods of the inner +/// type `T`. #[stable(feature = "rust1", since = "1.0.0")] pub struct Rc<T: ?Sized> { ptr: Shared<RcBox<T>>, @@ -229,12 +294,15 @@ impl<T> Rc<T> { } } - /// Unwraps the contained value if the `Rc<T>` has exactly one strong reference. + /// Returns the contained value, if the `Rc` has exactly one strong reference. /// - /// Otherwise, an `Err` is returned with the same `Rc<T>`. + /// Otherwise, an [`Err`][result] is returned with the same `Rc` that was + /// passed in. /// /// This will succeed even if there are outstanding weak references. /// + /// [result]: ../../std/result/enum.Result.html + /// /// # Examples /// /// ``` @@ -245,7 +313,7 @@ impl<T> Rc<T> { /// /// let x = Rc::new(4); /// let _y = x.clone(); - /// assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4))); + /// assert_eq!(*Rc::try_unwrap(x).unwrap_err(), 4); /// ``` #[inline] #[stable(feature = "rc_unique", since = "1.4.0")] @@ -268,7 +336,11 @@ impl<T> Rc<T> { } } - /// Checks if `Rc::try_unwrap` would return `Ok`. + /// Checks whether [`Rc::try_unwrap`][try_unwrap] would return + /// [`Ok`][result]. + /// + /// [try_unwrap]: struct.Rc.html#method.try_unwrap + /// [result]: ../../std/result/enum.Result.html /// /// # Examples /// @@ -284,7 +356,7 @@ impl<T> Rc<T> { /// let x = Rc::new(4); /// let _y = x.clone(); /// assert!(!Rc::would_unwrap(&x)); - /// assert_eq!(Rc::try_unwrap(x), Err(Rc::new(4))); + /// assert_eq!(*Rc::try_unwrap(x).unwrap_err(), 4); /// ``` #[unstable(feature = "rc_would_unwrap", reason = "just added for niche usecase", @@ -294,8 +366,35 @@ impl<T> Rc<T> { } } +impl Rc<str> { + /// Constructs a new `Rc<str>` from a string slice. + #[doc(hidden)] + #[unstable(feature = "rustc_private", + reason = "for internal use in rustc", + issue = "0")] + pub fn __from_str(value: &str) -> Rc<str> { + unsafe { + // Allocate enough space for `RcBox<str>`. + let aligned_len = 2 + (value.len() + size_of::<usize>() - 1) / size_of::<usize>(); + let vec = RawVec::<usize>::with_capacity(aligned_len); + let ptr = vec.ptr(); + forget(vec); + // Initialize fields of `RcBox<str>`. + *ptr.offset(0) = 1; // strong: Cell::new(1) + *ptr.offset(1) = 1; // weak: Cell::new(1) + ptr::copy_nonoverlapping(value.as_ptr(), ptr.offset(2) as *mut u8, value.len()); + // Combine the allocation address and the string length into a fat pointer to `RcBox`. + let rcbox_ptr: *mut RcBox<str> = mem::transmute([ptr as usize, value.len()]); + assert!(aligned_len * size_of::<usize>() == size_of_val(&*rcbox_ptr)); + Rc { ptr: Shared::new(rcbox_ptr) } + } + } +} + impl<T: ?Sized> Rc<T> { - /// Creates a new `Weak<T>` reference from this value. + /// Creates a new [`Weak`][weak] pointer to this value. + /// + /// [weak]: struct.Weak.html /// /// # Examples /// @@ -312,7 +411,22 @@ impl<T: ?Sized> Rc<T> { Weak { ptr: this.ptr } } - /// Get the number of weak references to this value. + /// Gets the number of [`Weak`][weak] pointers to this value. + /// + /// [weak]: struct.Weak.html + /// + /// # Examples + /// + /// ``` + /// #![feature(rc_counts)] + /// + /// use std::rc::Rc; + /// + /// let five = Rc::new(5); + /// let _weak_five = Rc::downgrade(&five); + /// + /// assert_eq!(1, Rc::weak_count(&five)); + /// ``` #[inline] #[unstable(feature = "rc_counts", reason = "not clearly useful", issue = "28356")] @@ -320,7 +434,20 @@ impl<T: ?Sized> Rc<T> { this.weak() - 1 } - /// Get the number of strong references to this value. + /// Gets the number of strong (`Rc`) pointers to this value. + /// + /// # Examples + /// + /// ``` + /// #![feature(rc_counts)] + /// + /// use std::rc::Rc; + /// + /// let five = Rc::new(5); + /// let _also_five = five.clone(); + /// + /// assert_eq!(2, Rc::strong_count(&five)); + /// ``` #[inline] #[unstable(feature = "rc_counts", reason = "not clearly useful", issue = "28356")] @@ -328,8 +455,10 @@ impl<T: ?Sized> Rc<T> { this.strong() } - /// Returns true if there are no other `Rc` or `Weak<T>` values that share - /// the same inner value. + /// Returns true if there are no other `Rc` or [`Weak`][weak] pointers to + /// this inner value. + /// + /// [weak]: struct.Weak.html /// /// # Examples /// @@ -349,10 +478,19 @@ impl<T: ?Sized> Rc<T> { Rc::weak_count(this) == 0 && Rc::strong_count(this) == 1 } - /// Returns a mutable reference to the contained value if the `Rc<T>` has - /// one strong reference and no weak references. + /// Returns a mutable reference to the inner value, if there are + /// no other `Rc` or [`Weak`][weak] pointers to the same value. + /// + /// Returns [`None`][option] otherwise, because it is not safe to + /// mutate a shared value. + /// + /// See also [`make_mut`][make_mut], which will [`clone`][clone] + /// the inner value when it's shared. /// - /// Returns `None` if the `Rc<T>` is not unique. + /// [weak]: struct.Weak.html + /// [option]: ../../std/option/enum.Option.html + /// [make_mut]: struct.Rc.html#method.make_mut + /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone /// /// # Examples /// @@ -381,8 +519,8 @@ impl<T: ?Sized> Rc<T> { #[unstable(feature = "ptr_eq", reason = "newly added", issue = "36497")] - /// Return whether two `Rc` references point to the same value - /// (not just values that compare equal). + /// Returns true if the two `Rc`s point to the same value (not + /// just values that compare as equal). /// /// # Examples /// @@ -406,11 +544,17 @@ impl<T: ?Sized> Rc<T> { } impl<T: Clone> Rc<T> { - /// Make a mutable reference into the given `Rc<T>` by cloning the inner - /// data if the `Rc<T>` doesn't have one strong reference and no weak - /// references. + /// Makes a mutable reference into the given `Rc`. + /// + /// If there are other `Rc` or [`Weak`][weak] pointers to the same value, + /// then `make_mut` will invoke [`clone`][clone] on the inner value to + /// ensure unique ownership. This is also referred to as clone-on-write. + /// + /// See also [`get_mut`][get_mut], which will fail rather than cloning. /// - /// This is also referred to as a copy-on-write. + /// [weak]: struct.Weak.html + /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone + /// [get_mut]: struct.Rc.html#method.get_mut /// /// # Examples /// @@ -419,16 +563,15 @@ impl<T: Clone> Rc<T> { /// /// let mut data = Rc::new(5); /// - /// *Rc::make_mut(&mut data) += 1; // Won't clone anything - /// let mut other_data = data.clone(); // Won't clone inner data - /// *Rc::make_mut(&mut data) += 1; // Clones inner data - /// *Rc::make_mut(&mut data) += 1; // Won't clone anything - /// *Rc::make_mut(&mut other_data) *= 2; // Won't clone anything + /// *Rc::make_mut(&mut data) += 1; // Won't clone anything + /// let mut other_data = data.clone(); // Won't clone inner data + /// *Rc::make_mut(&mut data) += 1; // Clones inner data + /// *Rc::make_mut(&mut data) += 1; // Won't clone anything + /// *Rc::make_mut(&mut other_data) *= 2; // Won't clone anything /// - /// // Note: data and other_data now point to different numbers + /// // Now `data` and `other_data` point to different values. /// assert_eq!(*data, 8); /// assert_eq!(*other_data, 12); - /// /// ``` #[inline] #[stable(feature = "rc_unique", since = "1.4.0")] @@ -470,30 +613,32 @@ impl<T: ?Sized> Deref for Rc<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized> Drop for Rc<T> { - /// Drops the `Rc<T>`. + /// Drops the `Rc`. /// /// This will decrement the strong reference count. If the strong reference - /// count becomes zero and the only other references are `Weak<T>` ones, - /// `drop`s the inner value. + /// count reaches zero then the only other references (if any) are + /// [`Weak`][weak], so we `drop` the inner value. + /// + /// [weak]: struct.Weak.html /// /// # Examples /// /// ``` /// use std::rc::Rc; /// - /// { - /// let five = Rc::new(5); - /// - /// // stuff + /// struct Foo; /// - /// drop(five); // explicit drop + /// impl Drop for Foo { + /// fn drop(&mut self) { + /// println!("dropped!"); + /// } /// } - /// { - /// let five = Rc::new(5); /// - /// // stuff + /// let foo = Rc::new(Foo); + /// let foo2 = foo.clone(); /// - /// } // implicit drop + /// drop(foo); // Doesn't print anything + /// drop(foo2); // Prints "dropped!" /// ``` #[unsafe_destructor_blind_to_params] fn drop(&mut self) { @@ -519,10 +664,10 @@ impl<T: ?Sized> Drop for Rc<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized> Clone for Rc<T> { - /// Makes a clone of the `Rc<T>`. + /// Makes a clone of the `Rc` pointer. /// - /// When you clone an `Rc<T>`, it will create another pointer to the data and - /// increase the strong reference counter. + /// This creates another pointer to the same inner value, increasing the + /// strong reference count. /// /// # Examples /// @@ -550,6 +695,7 @@ impl<T: Default> Default for Rc<T> { /// use std::rc::Rc; /// /// let x: Rc<i32> = Default::default(); + /// assert_eq!(*x, 0); /// ``` #[inline] fn default() -> Rc<T> { @@ -559,9 +705,9 @@ impl<T: Default> Default for Rc<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized + PartialEq> PartialEq for Rc<T> { - /// Equality for two `Rc<T>`s. + /// Equality for two `Rc`s. /// - /// Two `Rc<T>`s are equal if their inner value are equal. + /// Two `Rc`s are equal if their inner values are equal. /// /// # Examples /// @@ -570,16 +716,16 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> { /// /// let five = Rc::new(5); /// - /// five == Rc::new(5); + /// assert!(five == Rc::new(5)); /// ``` #[inline(always)] fn eq(&self, other: &Rc<T>) -> bool { **self == **other } - /// Inequality for two `Rc<T>`s. + /// Inequality for two `Rc`s. /// - /// Two `Rc<T>`s are unequal if their inner value are unequal. + /// Two `Rc`s are unequal if their inner values are unequal. /// /// # Examples /// @@ -588,7 +734,7 @@ impl<T: ?Sized + PartialEq> PartialEq for Rc<T> { /// /// let five = Rc::new(5); /// - /// five != Rc::new(5); + /// assert!(five != Rc::new(6)); /// ``` #[inline(always)] fn ne(&self, other: &Rc<T>) -> bool { @@ -601,7 +747,7 @@ impl<T: ?Sized + Eq> Eq for Rc<T> {} #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized + PartialOrd> PartialOrd for Rc<T> { - /// Partial comparison for two `Rc<T>`s. + /// Partial comparison for two `Rc`s. /// /// The two are compared by calling `partial_cmp()` on their inner values. /// @@ -609,17 +755,18 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Rc<T> { /// /// ``` /// use std::rc::Rc; + /// use std::cmp::Ordering; /// /// let five = Rc::new(5); /// - /// five.partial_cmp(&Rc::new(5)); + /// assert_eq!(Some(Ordering::Less), five.partial_cmp(&Rc::new(6))); /// ``` #[inline(always)] fn partial_cmp(&self, other: &Rc<T>) -> Option<Ordering> { (**self).partial_cmp(&**other) } - /// Less-than comparison for two `Rc<T>`s. + /// Less-than comparison for two `Rc`s. /// /// The two are compared by calling `<` on their inner values. /// @@ -630,14 +777,14 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Rc<T> { /// /// let five = Rc::new(5); /// - /// five < Rc::new(5); + /// assert!(five < Rc::new(6)); /// ``` #[inline(always)] fn lt(&self, other: &Rc<T>) -> bool { **self < **other } - /// 'Less-than or equal to' comparison for two `Rc<T>`s. + /// 'Less than or equal to' comparison for two `Rc`s. /// /// The two are compared by calling `<=` on their inner values. /// @@ -648,14 +795,14 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Rc<T> { /// /// let five = Rc::new(5); /// - /// five <= Rc::new(5); + /// assert!(five <= Rc::new(5)); /// ``` #[inline(always)] fn le(&self, other: &Rc<T>) -> bool { **self <= **other } - /// Greater-than comparison for two `Rc<T>`s. + /// Greater-than comparison for two `Rc`s. /// /// The two are compared by calling `>` on their inner values. /// @@ -666,14 +813,14 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Rc<T> { /// /// let five = Rc::new(5); /// - /// five > Rc::new(5); + /// assert!(five > Rc::new(4)); /// ``` #[inline(always)] fn gt(&self, other: &Rc<T>) -> bool { **self > **other } - /// 'Greater-than or equal to' comparison for two `Rc<T>`s. + /// 'Greater than or equal to' comparison for two `Rc`s. /// /// The two are compared by calling `>=` on their inner values. /// @@ -684,7 +831,7 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Rc<T> { /// /// let five = Rc::new(5); /// - /// five >= Rc::new(5); + /// assert!(five >= Rc::new(5)); /// ``` #[inline(always)] fn ge(&self, other: &Rc<T>) -> bool { @@ -694,7 +841,7 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Rc<T> { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized + Ord> Ord for Rc<T> { - /// Comparison for two `Rc<T>`s. + /// Comparison for two `Rc`s. /// /// The two are compared by calling `cmp()` on their inner values. /// @@ -702,10 +849,11 @@ impl<T: ?Sized + Ord> Ord for Rc<T> { /// /// ``` /// use std::rc::Rc; + /// use std::cmp::Ordering; /// /// let five = Rc::new(5); /// - /// five.partial_cmp(&Rc::new(5)); + /// assert_eq!(Ordering::Less, five.cmp(&Rc::new(6))); /// ``` #[inline] fn cmp(&self, other: &Rc<T>) -> Ordering { @@ -748,13 +896,18 @@ impl<T> From<T> for Rc<T> { } } -/// A weak version of `Rc<T>`. +/// A weak version of [`Rc`][rc]. +/// +/// `Weak` pointers do not count towards determining if the inner value +/// should be dropped. +/// +/// The typical way to obtain a `Weak` pointer is to call +/// [`Rc::downgrade`][downgrade]. /// -/// Weak references do not count when determining if the inner value should be -/// dropped. +/// See the [module-level documentation](./index.html) for more details. /// -/// See the [module level documentation](./index.html) for more. -#[cfg_attr(stage0, unsafe_no_drop_flag)] +/// [rc]: struct.Rc.html +/// [downgrade]: struct.Rc.html#method.downgrade #[stable(feature = "rc_weak", since = "1.4.0")] pub struct Weak<T: ?Sized> { ptr: Shared<RcBox<T>>, @@ -769,10 +922,14 @@ impl<T: ?Sized> !marker::Sync for Weak<T> {} impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Weak<U>> for Weak<T> {} impl<T> Weak<T> { - /// Constructs a new `Weak<T>` without an accompanying instance of T. + /// Constructs a new `Weak<T>`, without an accompanying instance of `T`. /// - /// This allocates memory for T, but does not initialize it. Calling - /// Weak<T>::upgrade() on the return value always gives None. + /// This allocates memory for `T`, but does not initialize it. Calling + /// [`upgrade`][upgrade] on the return value always gives + /// [`None`][option]. + /// + /// [upgrade]: struct.Weak.html#method.upgrade + /// [option]: ../../std/option/enum.Option.html /// /// # Examples /// @@ -780,6 +937,7 @@ impl<T> Weak<T> { /// use std::rc::Weak; /// /// let empty: Weak<i64> = Weak::new(); + /// assert!(empty.upgrade().is_none()); /// ``` #[stable(feature = "downgraded_weak", since = "1.10.0")] pub fn new() -> Weak<T> { @@ -796,12 +954,13 @@ impl<T> Weak<T> { } impl<T: ?Sized> Weak<T> { - /// Upgrades a weak reference to a strong reference. + /// Upgrades the `Weak` pointer to an [`Rc`][rc], if possible. /// - /// Upgrades the `Weak<T>` reference to an `Rc<T>`, if possible. + /// Returns [`None`][option] if the strong count has reached zero and the + /// inner value was destroyed. /// - /// Returns `None` if there were no strong references and the data was - /// destroyed. + /// [rc]: struct.Rc.html + /// [option]: ../../std/option/enum.Option.html /// /// # Examples /// @@ -813,6 +972,13 @@ impl<T: ?Sized> Weak<T> { /// let weak_five = Rc::downgrade(&five); /// /// let strong_five: Option<Rc<_>> = weak_five.upgrade(); + /// assert!(strong_five.is_some()); + /// + /// // Destroy all strong pointers. + /// drop(strong_five); + /// drop(five); + /// + /// assert!(weak_five.upgrade().is_none()); /// ``` #[stable(feature = "rc_weak", since = "1.4.0")] pub fn upgrade(&self) -> Option<Rc<T>> { @@ -827,7 +993,7 @@ impl<T: ?Sized> Weak<T> { #[stable(feature = "rc_weak", since = "1.4.0")] impl<T: ?Sized> Drop for Weak<T> { - /// Drops the `Weak<T>`. + /// Drops the `Weak` pointer. /// /// This will decrement the weak reference count. /// @@ -836,21 +1002,22 @@ impl<T: ?Sized> Drop for Weak<T> { /// ``` /// use std::rc::Rc; /// - /// { - /// let five = Rc::new(5); - /// let weak_five = Rc::downgrade(&five); + /// struct Foo; /// - /// // stuff - /// - /// drop(weak_five); // explicit drop + /// impl Drop for Foo { + /// fn drop(&mut self) { + /// println!("dropped!"); + /// } /// } - /// { - /// let five = Rc::new(5); - /// let weak_five = Rc::downgrade(&five); /// - /// // stuff + /// let foo = Rc::new(Foo); + /// let weak_foo = Rc::downgrade(&foo); + /// let other_weak_foo = weak_foo.clone(); + /// + /// drop(weak_foo); // Doesn't print anything + /// drop(foo); // Prints "dropped!" /// - /// } // implicit drop + /// assert!(other_weak_foo.upgrade().is_none()); /// ``` fn drop(&mut self) { unsafe { @@ -868,9 +1035,10 @@ 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<T>`. + /// Makes a clone of the `Weak` pointer. /// - /// This increases the weak reference count. + /// This creates another pointer to the same inner value, increasing the + /// weak reference count. /// /// # Examples /// @@ -897,7 +1065,23 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Weak<T> { #[stable(feature = "downgraded_weak", since = "1.10.0")] impl<T> Default for Weak<T> { - /// Creates a new `Weak<T>`. + /// Constructs a new `Weak<T>`, without an accompanying instance of `T`. + /// + /// This allocates memory for `T`, but does not initialize it. Calling + /// [`upgrade`][upgrade] on the return value always gives + /// [`None`][option]. + /// + /// [upgrade]: struct.Weak.html#method.upgrade + /// [option]: ../../std/option/enum.Option.html + /// + /// # Examples + /// + /// ``` + /// use std::rc::Weak; + /// + /// let empty: Weak<i64> = Default::default(); + /// assert!(empty.upgrade().is_none()); + /// ``` fn default() -> Weak<T> { Weak::new() } |
