1
Fork 0

Auto merge of #37024 - GuillaumeGomez:rollup, r=GuillaumeGomez

Rollup of 5 pull requests

- Successful merges: #36222, #36665, #36929, #37003, #37008
- Failed merges:
This commit is contained in:
bors 2016-10-07 04:24:24 -07:00 committed by GitHub
commit e51190cf07
7 changed files with 370 additions and 169 deletions

View file

@ -3110,10 +3110,12 @@ the lambda expression captures its environment by reference, effectively
borrowing pointers to all outer variables mentioned inside the function. borrowing pointers to all outer variables mentioned inside the function.
Alternately, the compiler may infer that a lambda expression should copy or Alternately, the compiler may infer that a lambda expression should copy or
move values (depending on their type) from the environment into the lambda 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 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: F) where F: Fn(i32) { fn ten_times<F>(f: F) where F: Fn(i32) {
@ -3123,6 +3125,9 @@ fn ten_times<F>(f: F) where F: Fn(i32) {
} }
ten_times(|j| println!("hello, {}", j)); ten_times(|j| println!("hello, {}", j));
let word = "konnichiwa".to_owned();
ten_times(move |j| println!("{}, {}", word, j));
``` ```
### Infinite loops ### Infinite loops
@ -3964,9 +3969,9 @@ implementation in the returned type `U`.
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. 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. multiple threads.
# Memory model # Memory model

View file

@ -10,35 +10,11 @@
#![stable(feature = "rust1", since = "1.0.0")] #![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 //! See the [`Arc<T>`][arc] documentation for more details.
//! atomic reference counting.
//! //!
//! `Weak<T>` is a weak reference to the `Arc<T>` box, and it is created by //! [arc]: struct.Arc.html
//! 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);
//! });
//! }
//! ```
use boxed::Box; use boxed::Box;
@ -62,71 +38,114 @@ use heap::deallocate;
const MAX_REFCOUNT: usize = (isize::MAX) as usize; const MAX_REFCOUNT: usize = (isize::MAX) as usize;
/// An atomically reference counted wrapper for shared state. /// A thread-safe reference-counting pointer.
/// 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.
/// ///
/// If you do not need thread-safety, and just need shared ownership, consider /// The type `Arc<T>` provides shared ownership of a value of type `T`,
/// the [`Rc<T>` type](../rc/struct.Rc.html). It is the same as `Arc<T>`, but /// allocated in the heap. Invoking [`clone`][clone] on `Arc` produces
/// does not use atomics, making it both thread-unsafe as well as significantly /// a new pointer to the same value in the heap. When the last `Arc`
/// faster when updating the reference count. /// 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, /// Shared references in Rust disallow mutation by default, and `Arc` is no
/// which means that you have to call them as e.g. `Arc::get_mut(&value)` /// exception. If you need to mutate through an `Arc`, use [`Mutex`][mutex],
/// instead of `value.get_mut()`. This is so that there are no conflicts with /// [`RwLock`][rwlock], or one of the [`Atomic`][atomic] types.
/// methods on the inner type `T`, which are what you want to call in the
/// majority of cases.
/// ///
/// # 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.
/// ///
/// In this example, a large vector of data will be shared by several threads. First we /// The [`downgrade`][downgrade] method can be used to create a non-owning
/// wrap it with a `Arc::new` and then clone the `Arc<T>` reference for every thread (which will /// [`Weak`][weak] pointer. A `Weak` pointer can be [`upgrade`][upgrade]d
/// increase the reference count atomically). /// to an `Arc`, but this will return [`None`][option] if the value has
/// already been dropped.
///
/// 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::sync::Arc;
/// use std::thread; /// let my_arc = Arc::new(());
/// ///
/// fn main() { /// Arc::downgrade(&my_arc);
/// let numbers: Vec<_> = (0..100).collect();
/// let shared_numbers = Arc::new(numbers);
///
/// for _ in 0..10 {
/// // prepare a copy of reference here and it will be moved to the thread
/// let child_numbers = shared_numbers.clone();
///
/// thread::spawn(move || {
/// let local_numbers = &child_numbers[..];
///
/// // 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.
/// ///
// See comment at the top of this file for why the test is no_run /// `Weak<T>` does not auto-dereference to `T`, because the value may have
/// already been destroyed.
///
/// [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
///
/// # Examples
///
/// Sharing some immutable data between threads:
///
// 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 /// ```no_run
/// use std::sync::{Arc, Mutex}; /// use std::sync::Arc;
/// use std::thread; /// use std::thread;
/// ///
/// let five = Arc::new(Mutex::new(5)); /// let five = Arc::new(5);
/// ///
/// for _ in 0..10 { /// for _ in 0..10 {
/// let five = five.clone(); /// let five = five.clone();
/// ///
/// thread::spawn(move || { /// thread::spawn(move || {
/// let mut number = five.lock().unwrap(); /// println!("{:?}", five);
///
/// *number += 1;
///
/// println!("{}", *number); // prints 6
/// }); /// });
/// } /// }
/// ``` /// ```
///
/// Sharing a mutable `AtomicUsize`:
///
/// ```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")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Arc<T: ?Sized> { pub struct Arc<T: ?Sized> {
ptr: Shared<ArcInner<T>>, ptr: Shared<ArcInner<T>>,
@ -140,18 +159,18 @@ unsafe impl<T: ?Sized + Sync + Send> Sync for Arc<T> {}
#[unstable(feature = "coerce_unsized", issue = "27732")] #[unstable(feature = "coerce_unsized", issue = "27732")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {} 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 /// `Weak` pointers do not count towards determining if the inner value
/// used to break cycles between `Arc` pointers. /// should be dropped.
/// ///
/// A `Weak<T>` pointer can be upgraded to an `Arc<T>` pointer, but /// The typical way to obtain a `Weak` pointer is to call
/// will return `None` if the value has already been dropped. /// [`Arc::downgrade`][downgrade].
/// ///
/// For example, a tree with parent pointers can be represented by putting the /// See the [`Arc`][arc] documentation for more details.
/// nodes behind strong `Arc<T>` pointers, and then storing the parent pointers ///
/// as `Weak<T>` pointers. /// [arc]: struct.Arc.html
/// [downgrade]: struct.Arc.html#method.downgrade
#[stable(feature = "arc_weak", since = "1.4.0")] #[stable(feature = "arc_weak", since = "1.4.0")]
pub struct Weak<T: ?Sized> { pub struct Weak<T: ?Sized> {
ptr: Shared<ArcInner<T>>, ptr: Shared<ArcInner<T>>,
@ -209,12 +228,15 @@ impl<T> Arc<T> {
Arc { ptr: unsafe { Shared::new(Box::into_raw(x)) } } 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. /// This will succeed even if there are outstanding weak references.
/// ///
/// [result]: ../../std/result/enum.Result.html
///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
@ -225,7 +247,7 @@ impl<T> Arc<T> {
/// ///
/// let x = Arc::new(4); /// let x = Arc::new(4);
/// let _y = x.clone(); /// let _y = x.clone();
/// assert_eq!(Arc::try_unwrap(x), Err(Arc::new(4))); /// assert_eq!(*Arc::try_unwrap(x).unwrap_err(), 4);
/// ``` /// ```
#[inline] #[inline]
#[stable(feature = "arc_unique", since = "1.4.0")] #[stable(feature = "arc_unique", since = "1.4.0")]
@ -251,7 +273,9 @@ impl<T> Arc<T> {
} }
impl<T: ?Sized> 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 /// # Examples
/// ///
@ -289,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] #[inline]
#[unstable(feature = "arc_counts", reason = "not clearly useful, and racy", #[unstable(feature = "arc_counts", reason = "not clearly useful, and racy",
issue = "28356")] issue = "28356")]
@ -297,7 +341,25 @@ impl<T: ?Sized> Arc<T> {
this.inner().weak.load(SeqCst) - 1 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] #[inline]
#[unstable(feature = "arc_counts", reason = "not clearly useful, and racy", #[unstable(feature = "arc_counts", reason = "not clearly useful, and racy",
issue = "28356")] issue = "28356")]
@ -334,8 +396,8 @@ impl<T: ?Sized> Arc<T> {
#[unstable(feature = "ptr_eq", #[unstable(feature = "ptr_eq",
reason = "newly added", reason = "newly added",
issue = "36497")] issue = "36497")]
/// Return whether two `Arc` references point to the same value /// Returns true if the two `Arc`s point to the same value (not
/// (not just values that compare equal). /// just values that compare as equal).
/// ///
/// # Examples /// # Examples
/// ///
@ -360,9 +422,10 @@ impl<T: ?Sized> Arc<T> {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Clone for Arc<T> { 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 /// # Examples
/// ///
@ -418,11 +481,17 @@ impl<T: ?Sized> Deref for Arc<T> {
} }
impl<T: Clone> Arc<T> { impl<T: Clone> Arc<T> {
/// Make a mutable reference into the given `Arc<T>`. /// Makes a mutable reference into the given `Arc`.
/// If the `Arc<T>` has more than one strong reference, or any weak
/// references, the inner data is cloned.
/// ///
/// This is also referred to as a copy-on-write. /// 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.
///
/// [weak]: struct.Weak.html
/// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone
/// [get_mut]: struct.Arc.html#method.get_mut
/// ///
/// # Examples /// # Examples
/// ///
@ -437,10 +506,9 @@ impl<T: Clone> Arc<T> {
/// *Arc::make_mut(&mut data) += 1; // Won't clone anything /// *Arc::make_mut(&mut data) += 1; // Won't clone anything
/// *Arc::make_mut(&mut other_data) *= 2; // 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!(*data, 8);
/// assert_eq!(*other_data, 12); /// assert_eq!(*other_data, 12);
///
/// ``` /// ```
#[inline] #[inline]
#[stable(feature = "arc_unique", since = "1.4.0")] #[stable(feature = "arc_unique", since = "1.4.0")]
@ -499,8 +567,19 @@ impl<T: Clone> Arc<T> {
} }
impl<T: ?Sized> Arc<T> { impl<T: ?Sized> Arc<T> {
/// Returns a mutable reference to the contained value if the `Arc<T>` has /// Returns a mutable reference to the inner value, if there are
/// one strong reference and no weak references. /// 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 /// # Examples
/// ///
@ -562,30 +641,32 @@ impl<T: ?Sized> Arc<T> {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Drop for Arc<T> { 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 /// This will decrement the strong reference count. If the strong reference
/// count becomes zero and the only other references are `Weak<T>` ones, /// count reaches zero then the only other references (if any) are
/// `drop`s the inner value. /// [`Weak`][weak], so we `drop` the inner value.
///
/// [weak]: struct.Weak.html
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use std::sync::Arc; /// use std::sync::Arc;
/// ///
/// { /// struct Foo;
/// let five = Arc::new(5);
/// ///
/// // stuff /// impl Drop for Foo {
/// /// fn drop(&mut self) {
/// drop(five); // explicit drop /// 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] #[unsafe_destructor_blind_to_params]
#[inline] #[inline]
@ -623,10 +704,14 @@ impl<T: ?Sized> Drop for Arc<T> {
} }
impl<T> 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 /// This allocates memory for `T`, but does not initialize it. Calling
/// Weak<T>::upgrade() on the return value always gives None. /// [`upgrade`][upgrade] on the return value always gives
/// [`None`][option].
///
/// [upgrade]: struct.Weak.html#method.upgrade
/// [option]: ../../std/option/enum.Option.html
/// ///
/// # Examples /// # Examples
/// ///
@ -634,6 +719,7 @@ impl<T> Weak<T> {
/// use std::sync::Weak; /// use std::sync::Weak;
/// ///
/// let empty: Weak<i64> = Weak::new(); /// let empty: Weak<i64> = Weak::new();
/// assert!(empty.upgrade().is_none());
/// ``` /// ```
#[stable(feature = "downgraded_weak", since = "1.10.0")] #[stable(feature = "downgraded_weak", since = "1.10.0")]
pub fn new() -> Weak<T> { pub fn new() -> Weak<T> {
@ -650,12 +736,13 @@ impl<T> Weak<T> {
} }
impl<T: ?Sized> 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 /// [arc]: struct.Arc.html
/// destroyed. /// [option]: ../../std/option/enum.Option.html
/// ///
/// # Examples /// # Examples
/// ///
@ -667,6 +754,13 @@ impl<T: ?Sized> Weak<T> {
/// let weak_five = Arc::downgrade(&five); /// let weak_five = Arc::downgrade(&five);
/// ///
/// let strong_five: Option<Arc<_>> = weak_five.upgrade(); /// 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")] #[stable(feature = "arc_weak", since = "1.4.0")]
pub fn upgrade(&self) -> Option<Arc<T>> { pub fn upgrade(&self) -> Option<Arc<T>> {
@ -709,9 +803,10 @@ impl<T: ?Sized> Weak<T> {
#[stable(feature = "arc_weak", since = "1.4.0")] #[stable(feature = "arc_weak", since = "1.4.0")]
impl<T: ?Sized> Clone for Weak<T> { 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 /// # Examples
/// ///
@ -743,7 +838,23 @@ impl<T: ?Sized> Clone for Weak<T> {
#[stable(feature = "downgraded_weak", since = "1.10.0")] #[stable(feature = "downgraded_weak", since = "1.10.0")]
impl<T> Default for Weak<T> { 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> { fn default() -> Weak<T> {
Weak::new() Weak::new()
} }
@ -751,7 +862,7 @@ impl<T> Default for Weak<T> {
#[stable(feature = "arc_weak", since = "1.4.0")] #[stable(feature = "arc_weak", since = "1.4.0")]
impl<T: ?Sized> Drop for Weak<T> { impl<T: ?Sized> Drop for Weak<T> {
/// Drops the `Weak<T>`. /// Drops the `Weak` pointer.
/// ///
/// This will decrement the weak reference count. /// This will decrement the weak reference count.
/// ///
@ -760,21 +871,22 @@ impl<T: ?Sized> Drop for Weak<T> {
/// ``` /// ```
/// use std::sync::Arc; /// use std::sync::Arc;
/// ///
/// { /// struct Foo;
/// let five = Arc::new(5);
/// let weak_five = Arc::downgrade(&five);
/// ///
/// // stuff /// impl Drop for Foo {
/// /// fn drop(&mut self) {
/// drop(weak_five); // explicit drop /// 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) { fn drop(&mut self) {
let ptr = *self.ptr; let ptr = *self.ptr;
@ -796,9 +908,9 @@ impl<T: ?Sized> Drop for Weak<T> {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + PartialEq> PartialEq for Arc<T> { 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 /// # Examples
/// ///
@ -807,15 +919,15 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
/// ///
/// let five = Arc::new(5); /// let five = Arc::new(5);
/// ///
/// five == Arc::new(5); /// assert!(five == Arc::new(5));
/// ``` /// ```
fn eq(&self, other: &Arc<T>) -> bool { fn eq(&self, other: &Arc<T>) -> bool {
*(*self) == *(*other) *(*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 /// # Examples
/// ///
@ -824,7 +936,7 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
/// ///
/// let five = Arc::new(5); /// let five = Arc::new(5);
/// ///
/// five != Arc::new(5); /// assert!(five != Arc::new(6));
/// ``` /// ```
fn ne(&self, other: &Arc<T>) -> bool { fn ne(&self, other: &Arc<T>) -> bool {
*(*self) != *(*other) *(*self) != *(*other)
@ -832,7 +944,7 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> { 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. /// The two are compared by calling `partial_cmp()` on their inner values.
/// ///
@ -840,16 +952,17 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {
/// ///
/// ``` /// ```
/// use std::sync::Arc; /// use std::sync::Arc;
/// use std::cmp::Ordering;
/// ///
/// let five = Arc::new(5); /// 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> { fn partial_cmp(&self, other: &Arc<T>) -> Option<Ordering> {
(**self).partial_cmp(&**other) (**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. /// The two are compared by calling `<` on their inner values.
/// ///
@ -860,13 +973,13 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {
/// ///
/// let five = Arc::new(5); /// let five = Arc::new(5);
/// ///
/// five < Arc::new(5); /// assert!(five < Arc::new(6));
/// ``` /// ```
fn lt(&self, other: &Arc<T>) -> bool { fn lt(&self, other: &Arc<T>) -> bool {
*(*self) < *(*other) *(*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. /// The two are compared by calling `<=` on their inner values.
/// ///
@ -877,13 +990,13 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {
/// ///
/// let five = Arc::new(5); /// let five = Arc::new(5);
/// ///
/// five <= Arc::new(5); /// assert!(five <= Arc::new(5));
/// ``` /// ```
fn le(&self, other: &Arc<T>) -> bool { fn le(&self, other: &Arc<T>) -> bool {
*(*self) <= *(*other) *(*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. /// The two are compared by calling `>` on their inner values.
/// ///
@ -894,13 +1007,13 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {
/// ///
/// let five = Arc::new(5); /// let five = Arc::new(5);
/// ///
/// five > Arc::new(5); /// assert!(five > Arc::new(4));
/// ``` /// ```
fn gt(&self, other: &Arc<T>) -> bool { fn gt(&self, other: &Arc<T>) -> bool {
*(*self) > *(*other) *(*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. /// The two are compared by calling `>=` on their inner values.
/// ///
@ -911,7 +1024,7 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {
/// ///
/// let five = Arc::new(5); /// let five = Arc::new(5);
/// ///
/// five >= Arc::new(5); /// assert!(five >= Arc::new(5));
/// ``` /// ```
fn ge(&self, other: &Arc<T>) -> bool { fn ge(&self, other: &Arc<T>) -> bool {
*(*self) >= *(*other) *(*self) >= *(*other)
@ -919,6 +1032,20 @@ impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + Ord> Ord for Arc<T> { 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 { fn cmp(&self, other: &Arc<T>) -> Ordering {
(**self).cmp(&**other) (**self).cmp(&**other)
} }
@ -949,7 +1076,16 @@ impl<T: ?Sized> fmt::Pointer for Arc<T> {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: Default> Default for Arc<T> { 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> { fn default() -> Arc<T> {
Arc::new(Default::default()) Arc::new(Default::default())
} }

View file

@ -12,12 +12,12 @@
//! Single-threaded reference-counting pointers. //! Single-threaded reference-counting pointers.
//! //!
//! The type [`Rc<T>`][rc] provides shared ownership of a value, allocated //! The type [`Rc<T>`][rc] provides shared ownership of a value of type `T`,
//! in the heap. Invoking [`clone`][clone] on `Rc` produces a new pointer //! allocated in the heap. Invoking [`clone`][clone] on `Rc` produces a new
//! to the same value in the heap. When the last `Rc` pointer to a given //! pointer to the same value in the heap. When the last `Rc` pointer to a
//! value is destroyed, the pointed-to value is also destroyed. //! 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 //! exception. If you need to mutate through an `Rc`, use [`Cell`][cell] or
//! [`RefCell`][refcell]. //! [`RefCell`][refcell].
//! //!
@ -44,8 +44,9 @@
//! functions][assoc], called using function-like syntax: //! functions][assoc], called using function-like syntax:
//! //!
//! ``` //! ```
//! # use std::rc::Rc; //! use std::rc::Rc;
//! # let my_rc = Rc::new(()); //! let my_rc = Rc::new(());
//!
//! Rc::downgrade(&my_rc); //! Rc::downgrade(&my_rc);
//! ``` //! ```
//! //!
@ -294,10 +295,13 @@ impl<T> Rc<T> {
/// Returns the contained value, if the `Rc` 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` 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. /// This will succeed even if there are outstanding weak references.
/// ///
/// [result]: ../../std/result/enum.Result.html
///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
@ -331,7 +335,11 @@ impl<T> Rc<T> {
} }
} }
/// 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 /// # Examples
/// ///
@ -582,8 +590,10 @@ impl<T: ?Sized> Drop for Rc<T> {
/// Drops the `Rc`. /// Drops the `Rc`.
/// ///
/// This will decrement the strong reference count. If the strong reference /// This will decrement the strong reference count. If the strong reference
/// count reaches zero then the only other references (if any) are `Weak`, /// count reaches zero then the only other references (if any) are
/// so we `drop` the inner value. /// [`Weak`][weak], so we `drop` the inner value.
///
/// [weak]: struct.Weak.html
/// ///
/// # Examples /// # Examples
/// ///

View file

@ -2432,6 +2432,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let mut expected_arg_tys = expected_arg_tys; let mut expected_arg_tys = expected_arg_tys;
let expected_arg_count = fn_inputs.len(); 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>], fn parameter_count_error<'tcx>(sess: &Session, sp: Span, fn_inputs: &[Ty<'tcx>],
expected_count: usize, arg_count: usize, error_code: &str, expected_count: usize, arg_count: usize, error_code: &str,
variadic: bool) { 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]); let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
match tuple_type.sty { match tuple_type.sty {
ty::TyTuple(arg_types) if arg_types.len() != args.len() => { 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); "E0057", false);
expected_arg_tys = &[]; expected_arg_tys = &[];
self.err_args(args.len()) self.err_args(args.len())
@ -2493,14 +2508,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
if supplied_arg_count >= expected_arg_count { if supplied_arg_count >= expected_arg_count {
fn_inputs.to_vec() fn_inputs.to_vec()
} else { } 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); supplied_arg_count, "E0060", true);
expected_arg_tys = &[]; expected_arg_tys = &[];
self.err_args(supplied_arg_count) self.err_args(supplied_arg_count)
} }
} else { } else {
parameter_count_error(tcx.sess, sp, fn_inputs, expected_arg_count, supplied_arg_count, parameter_count_error(tcx.sess, sp_args, fn_inputs, expected_arg_count,
"E0061", false); supplied_arg_count, "E0061", false);
expected_arg_tys = &[]; expected_arg_tys = &[];
self.err_args(supplied_arg_count) self.err_args(supplied_arg_count)
}; };

View file

@ -585,6 +585,7 @@ a.test-arrow {
} }
a.test-arrow:hover{ a.test-arrow:hover{
background-color: #4e8bca; background-color: #4e8bca;
text-decoration: none;
} }
.section-header:hover a:after { .section-header:hover a:after {

16
src/test/ui/span/E0057.rs Normal file
View file

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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
}

View file

@ -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