diff --git a/src/doc/reference.md b/src/doc/reference.md index 20970ab7a3512..08ff982d4d73b 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -3110,10 +3110,12 @@ the lambda expression captures its environment by reference, effectively borrowing pointers to all outer variables mentioned inside the function. Alternately, the compiler may infer that a lambda expression should copy or move values (depending on their type) from the environment into the lambda -expression's captured environment. +expression's captured environment. A lambda can be forced to capture its +environment by moving values by prefixing it with the `move` keyword. In this example, we define a function `ten_times` that takes a higher-order -function argument, and we then call it with a lambda expression as an argument: +function argument, and we then call it with a lambda expression as an argument, +followed by a lambda expression that moves values from its environment. ``` fn ten_times(f: F) where F: Fn(i32) { @@ -3123,6 +3125,9 @@ fn ten_times(f: F) where F: Fn(i32) { } ten_times(|j| println!("hello, {}", j)); + +let word = "konnichiwa".to_owned(); +ten_times(move |j| println!("{}, {}", word, j)); ``` ### Infinite loops @@ -3961,12 +3966,12 @@ implementation in the returned type `U`. ## The `Send` trait -The `Send` trait indicates that a value of this type is safe to send from one +The `Send` trait indicates that a value of this type is safe to send from one thread to another. -## The 'Sync' trait +## The `Sync` trait -The 'Sync' trait indicates that a value of this type is safe to share between +The `Sync` trait indicates that a value of this type is safe to share between multiple threads. # Memory model diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 29e18781ce2a5..7a07e007ce1c4 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` type). +//! Thread-safe reference-counting pointers. //! -//! The `Arc` type provides shared ownership of an immutable value through -//! atomic reference counting. +//! See the [`Arc`][arc] documentation for more details. //! -//! `Weak` is a weak reference to the `Arc` 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,71 +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` type](../rc/struct.Rc.html). It is the same as `Arc`, but -/// does not use atomics, making it both thread-unsafe as well as significantly -/// faster when updating the reference count. +/// The type `Arc` 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` 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` 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` 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` automatically dereferences to `T` (via the [`Deref`][deref] trait), +/// so you can call `T`'s methods on a value of type `Arc`. To avoid name +/// clashes with `T`'s methods, the methods of `Arc` 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` 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` 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); /// }); /// } /// ``` - +/// +/// 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 { ptr: Shared>, @@ -140,18 +159,18 @@ unsafe impl Sync for Arc {} #[unstable(feature = "coerce_unsized", issue = "27732")] impl, U: ?Sized> CoerceUnsized> for Arc {} -/// 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` pointer can be upgraded to an `Arc` 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` pointers, and then storing the parent pointers -/// as `Weak` pointers. - +/// 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 { ptr: Shared>, @@ -209,12 +228,15 @@ impl Arc { Arc { ptr: unsafe { Shared::new(Box::into_raw(x)) } } } - /// Unwraps the contained value if the `Arc` 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`. + /// 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 /// /// ``` @@ -225,7 +247,7 @@ impl Arc { /// /// 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")] @@ -251,7 +273,9 @@ impl Arc { } impl Arc { - /// Downgrades the `Arc` to a `Weak` reference. + /// Creates a new [`Weak`][weak] pointer to this value. + /// + /// [weak]: struct.Weak.html /// /// # Examples /// @@ -289,7 +313,27 @@ impl Arc { } } - /// 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")] @@ -297,7 +341,25 @@ impl Arc { 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")] @@ -334,8 +396,8 @@ impl Arc { #[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 /// @@ -360,9 +422,10 @@ impl Arc { #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Arc { - /// Makes a clone of the `Arc`. + /// 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 /// @@ -418,11 +481,17 @@ impl Deref for Arc { } impl Arc { - /// Make a mutable reference into the given `Arc`. - /// If the `Arc` 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 /// @@ -437,10 +506,9 @@ impl Arc { /// *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")] @@ -499,8 +567,19 @@ impl Arc { } impl Arc { - /// Returns a mutable reference to the contained value if the `Arc` 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 /// @@ -562,30 +641,32 @@ impl Arc { #[stable(feature = "rust1", since = "1.0.0")] impl Drop for Arc { - /// Drops the `Arc`. + /// Drops the `Arc`. /// /// This will decrement the strong reference count. If the strong reference - /// count becomes zero and the only other references are `Weak` 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] @@ -623,10 +704,14 @@ impl Drop for Arc { } impl Weak { - /// Constructs a new `Weak` without an accompanying instance of T. + /// Constructs a new `Weak`, without an accompanying instance of `T`. /// - /// This allocates memory for T, but does not initialize it. Calling - /// Weak::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 /// @@ -634,6 +719,7 @@ impl Weak { /// use std::sync::Weak; /// /// let empty: Weak = Weak::new(); + /// assert!(empty.upgrade().is_none()); /// ``` #[stable(feature = "downgraded_weak", since = "1.10.0")] pub fn new() -> Weak { @@ -650,12 +736,13 @@ impl Weak { } impl Weak { - /// Upgrades a weak reference to a strong reference. + /// Upgrades the `Weak` pointer to an [`Arc`][arc], if possible. /// - /// Upgrades the `Weak` reference to an `Arc`, 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 /// @@ -667,6 +754,13 @@ impl Weak { /// let weak_five = Arc::downgrade(&five); /// /// let strong_five: Option> = 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> { @@ -709,9 +803,10 @@ impl Weak { #[stable(feature = "arc_weak", since = "1.4.0")] impl Clone for Weak { - /// Makes a clone of the `Weak`. + /// 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 /// @@ -743,7 +838,23 @@ impl Clone for Weak { #[stable(feature = "downgraded_weak", since = "1.10.0")] impl Default for Weak { - /// Constructs a new `Weak` without an accompanying instance of T. + /// Constructs a new `Weak`, 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 = Default::default(); + /// assert!(empty.upgrade().is_none()); + /// ``` fn default() -> Weak { Weak::new() } @@ -751,7 +862,7 @@ impl Default for Weak { #[stable(feature = "arc_weak", since = "1.4.0")] impl Drop for Weak { - /// Drops the `Weak`. + /// Drops the `Weak` pointer. /// /// This will decrement the weak reference count. /// @@ -760,21 +871,22 @@ impl Drop for Weak { /// ``` /// 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; @@ -796,9 +908,9 @@ impl Drop for Weak { #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for Arc { - /// Equality for two `Arc`s. + /// Equality for two `Arc`s. /// - /// Two `Arc`s are equal if their inner value are equal. + /// Two `Arc`s are equal if their inner values are equal. /// /// # Examples /// @@ -807,15 +919,15 @@ impl PartialEq for Arc { /// /// let five = Arc::new(5); /// - /// five == Arc::new(5); + /// assert!(five == Arc::new(5)); /// ``` fn eq(&self, other: &Arc) -> bool { *(*self) == *(*other) } - /// Inequality for two `Arc`s. + /// Inequality for two `Arc`s. /// - /// Two `Arc`s are unequal if their inner value are unequal. + /// Two `Arc`s are unequal if their inner values are unequal. /// /// # Examples /// @@ -824,7 +936,7 @@ impl PartialEq for Arc { /// /// let five = Arc::new(5); /// - /// five != Arc::new(5); + /// assert!(five != Arc::new(6)); /// ``` fn ne(&self, other: &Arc) -> bool { *(*self) != *(*other) @@ -832,7 +944,7 @@ impl PartialEq for Arc { } #[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for Arc { - /// Partial comparison for two `Arc`s. + /// Partial comparison for two `Arc`s. /// /// The two are compared by calling `partial_cmp()` on their inner values. /// @@ -840,16 +952,17 @@ impl PartialOrd for Arc { /// /// ``` /// 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) -> Option { (**self).partial_cmp(&**other) } - /// Less-than comparison for two `Arc`s. + /// Less-than comparison for two `Arc`s. /// /// The two are compared by calling `<` on their inner values. /// @@ -860,13 +973,13 @@ impl PartialOrd for Arc { /// /// let five = Arc::new(5); /// - /// five < Arc::new(5); + /// assert!(five < Arc::new(6)); /// ``` fn lt(&self, other: &Arc) -> bool { *(*self) < *(*other) } - /// 'Less-than or equal to' comparison for two `Arc`s. + /// 'Less than or equal to' comparison for two `Arc`s. /// /// The two are compared by calling `<=` on their inner values. /// @@ -877,13 +990,13 @@ impl PartialOrd for Arc { /// /// let five = Arc::new(5); /// - /// five <= Arc::new(5); + /// assert!(five <= Arc::new(5)); /// ``` fn le(&self, other: &Arc) -> bool { *(*self) <= *(*other) } - /// Greater-than comparison for two `Arc`s. + /// Greater-than comparison for two `Arc`s. /// /// The two are compared by calling `>` on their inner values. /// @@ -894,13 +1007,13 @@ impl PartialOrd for Arc { /// /// let five = Arc::new(5); /// - /// five > Arc::new(5); + /// assert!(five > Arc::new(4)); /// ``` fn gt(&self, other: &Arc) -> bool { *(*self) > *(*other) } - /// 'Greater-than or equal to' comparison for two `Arc`s. + /// 'Greater than or equal to' comparison for two `Arc`s. /// /// The two are compared by calling `>=` on their inner values. /// @@ -911,7 +1024,7 @@ impl PartialOrd for Arc { /// /// let five = Arc::new(5); /// - /// five >= Arc::new(5); + /// assert!(five >= Arc::new(5)); /// ``` fn ge(&self, other: &Arc) -> bool { *(*self) >= *(*other) @@ -919,6 +1032,20 @@ impl PartialOrd for Arc { } #[stable(feature = "rust1", since = "1.0.0")] impl Ord for Arc { + /// 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) -> Ordering { (**self).cmp(&**other) } @@ -949,7 +1076,16 @@ impl fmt::Pointer for Arc { #[stable(feature = "rust1", since = "1.0.0")] impl Default for Arc { - /// Creates a new `Arc`, with the `Default` value for T. + /// Creates a new `Arc`, with the `Default` value for `T`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let x: Arc = Default::default(); + /// assert_eq!(*x, 0); + /// ``` fn default() -> Arc { Arc::new(Default::default()) } diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 4a4de419f2ede..699f777138d00 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -12,12 +12,12 @@ //! Single-threaded reference-counting pointers. //! -//! The type [`Rc`][rc] provides shared ownership of a value, 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 type [`Rc`][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. //! -//! Shared pointers in Rust disallow mutation by default, and `Rc` is no +//! 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]. //! @@ -44,8 +44,9 @@ //! functions][assoc], called using function-like syntax: //! //! ``` -//! # use std::rc::Rc; -//! # let my_rc = Rc::new(()); +//! use std::rc::Rc; +//! let my_rc = Rc::new(()); +//! //! Rc::downgrade(&my_rc); //! ``` //! @@ -294,10 +295,13 @@ impl Rc { /// Returns the contained value, if the `Rc` has exactly one strong reference. /// - /// Otherwise, an `Err` is returned with the same `Rc` that was passed in. + /// 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 /// /// ``` @@ -331,7 +335,11 @@ impl Rc { } } - /// Checks whether `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 /// @@ -582,8 +590,10 @@ impl Drop for Rc { /// Drops the `Rc`. /// /// This will decrement the strong reference count. If the strong reference - /// count reaches zero then the only other references (if any) are `Weak`, - /// so we `drop` 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 /// diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 79c1c5fb5e2e1..155a858c1bb20 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2432,6 +2432,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mut expected_arg_tys = expected_arg_tys; let expected_arg_count = fn_inputs.len(); + let sp_args = if args.len() > 0 { + let (first, args) = args.split_at(1); + let mut sp_tmp = first[0].span; + for arg in args { + let sp_opt = self.sess().codemap().merge_spans(sp_tmp, arg.span); + if ! sp_opt.is_some() { + break; + } + sp_tmp = sp_opt.unwrap(); + }; + sp_tmp + } else { + sp + }; + fn parameter_count_error<'tcx>(sess: &Session, sp: Span, fn_inputs: &[Ty<'tcx>], expected_count: usize, arg_count: usize, error_code: &str, variadic: bool) { @@ -2464,7 +2479,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]); match tuple_type.sty { ty::TyTuple(arg_types) if arg_types.len() != args.len() => { - parameter_count_error(tcx.sess, sp, fn_inputs, arg_types.len(), args.len(), + parameter_count_error(tcx.sess, sp_args, fn_inputs, arg_types.len(), args.len(), "E0057", false); expected_arg_tys = &[]; self.err_args(args.len()) @@ -2493,14 +2508,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if supplied_arg_count >= expected_arg_count { fn_inputs.to_vec() } else { - parameter_count_error(tcx.sess, sp, fn_inputs, expected_arg_count, + parameter_count_error(tcx.sess, sp_args, fn_inputs, expected_arg_count, supplied_arg_count, "E0060", true); expected_arg_tys = &[]; self.err_args(supplied_arg_count) } } else { - parameter_count_error(tcx.sess, sp, fn_inputs, expected_arg_count, supplied_arg_count, - "E0061", false); + parameter_count_error(tcx.sess, sp_args, fn_inputs, expected_arg_count, + supplied_arg_count, "E0061", false); expected_arg_tys = &[]; self.err_args(supplied_arg_count) }; diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index cad5fae690fb8..f8133ea49ceba 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -585,6 +585,7 @@ a.test-arrow { } a.test-arrow:hover{ background-color: #4e8bca; + text-decoration: none; } .section-header:hover a:after { diff --git a/src/test/ui/span/E0057.rs b/src/test/ui/span/E0057.rs new file mode 100644 index 0000000000000..1fb5498b099c9 --- /dev/null +++ b/src/test/ui/span/E0057.rs @@ -0,0 +1,16 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let f = |x| x * 3; + let a = f(); //~ ERROR E0057 + let b = f(4); + let c = f(2, 3); //~ ERROR E0057 +} diff --git a/src/test/ui/span/E0057.stderr b/src/test/ui/span/E0057.stderr new file mode 100644 index 0000000000000..656fdbe2b29bd --- /dev/null +++ b/src/test/ui/span/E0057.stderr @@ -0,0 +1,18 @@ +error[E0057]: this function takes 1 parameter but 0 parameters were supplied + --> $DIR/E0057.rs:13:13 + | +13 | let a = f(); //~ ERROR E0057 + | ^^^ + | + = note: the following parameter type was expected: (_,) + +error[E0057]: this function takes 1 parameter but 2 parameters were supplied + --> $DIR/E0057.rs:15:15 + | +15 | let c = f(2, 3); //~ ERROR E0057 + | ^^^^ + | + = note: the following parameter type was expected: (_,) + +error: aborting due to 2 previous errors +