about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-05-27 03:56:19 -0700
committerbors <bors@rust-lang.org>2016-05-27 03:56:19 -0700
commitab7c35fa0fcd725cdc207487b760d85fd07ecdd7 (patch)
tree374bb44d05648bb9b73998a8dc0118c96d467786 /src/libcore
parent36d5dc7c9bcfd287b5c4e4ac3e2f0ab93bdaa0c9 (diff)
parent2c4fd94636f9f495474a943b716a9ab0ac1bec99 (diff)
downloadrust-ab7c35fa0fcd725cdc207487b760d85fd07ecdd7.tar.gz
rust-ab7c35fa0fcd725cdc207487b760d85fd07ecdd7.zip
Auto merge of #33900 - GuillaumeGomez:rollup, r=GuillaumeGomez
Rollup of 10 pull requests

- Successful merges: #33753, #33815, #33829, #33858, #33865, #33866, #33870, #33874, #33891, #33898
- Failed merges:
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/clone.rs32
-rw-r--r--src/libcore/cmp.rs168
-rw-r--r--src/libcore/default.rs138
-rw-r--r--src/libcore/fmt/mod.rs6
-rw-r--r--src/libcore/hash/mod.rs30
-rw-r--r--src/libcore/marker.rs39
6 files changed, 313 insertions, 100 deletions
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index e8ea993c694..e8cd36f3cd7 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -46,14 +46,42 @@
 
 use marker::Sized;
 
-/// A common trait for cloning an object.
+/// A common trait for the ability to explicitly duplicate an object.
 ///
-/// This trait can be used with `#[derive]`.
+/// Differs from `Copy` in that `Copy` is implicit and extremely inexpensive, while
+/// `Clone` is always explicit and may or may not be expensive. In order to enforce
+/// these characteristics, Rust does not allow you to reimplement `Copy`, but you
+/// may reimplement `Clone` and run arbitrary code.
+///
+/// Since `Clone` is more general than `Copy`, you can automatically make anything
+/// `Copy` be `Clone` as well.
+///
+/// ## Derivable
+///
+/// This trait can be used with `#[derive]` if all fields are `Clone`. The `derive`d
+/// implementation of `clone()` calls `clone()` on each field.
+///
+/// ## How can I implement `Clone`?
 ///
 /// Types that are `Copy` should have a trivial implementation of `Clone`. More formally:
 /// if `T: Copy`, `x: T`, and `y: &T`, then `let x = y.clone();` is equivalent to `let x = *y;`.
 /// Manual implementations should be careful to uphold this invariant; however, unsafe code
 /// must not rely on it to ensure memory safety.
+///
+/// An example is an array holding more than 32 elements of a type that is `Clone`; the standard
+/// library only implements `Clone` up until arrays of size 32. In this case, the implementation of
+/// `Clone` cannot be `derive`d, but can be implemented as:
+///
+/// ```
+/// #[derive(Copy)]
+/// struct Stats {
+///    frequencies: [i32; 100],
+/// }
+///
+/// impl Clone for Stats {
+///     fn clone(&self) -> Stats { *self }
+/// }
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Clone : Sized {
     /// Returns a copy of the value.
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index d3481ba3f05..8764766b2ef 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -53,12 +53,43 @@ use option::Option::{self, Some};
 /// symmetrically and transitively: if `T: PartialEq<U>` and `U: PartialEq<V>`
 /// then `U: PartialEq<T>` and `T: PartialEq<V>`.
 ///
+/// ## Derivable
+///
+/// This trait can be used with `#[derive]`. When `derive`d on structs, two
+/// instances are equal if all fields are equal, and not equal if any fields
+/// are not equal. When `derive`d on enums, each variant is equal to itself
+/// and not equal to the other variants.
+///
+/// ## How can I implement `PartialEq`?
+///
 /// PartialEq only requires the `eq` method to be implemented; `ne` is defined
 /// in terms of it by default. Any manual implementation of `ne` *must* respect
 /// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and
 /// only if `a != b`.
 ///
-/// This trait can be used with `#[derive]`.
+/// An example implementation for a domain in which two books are considered
+/// the same book if their ISBN matches, even if the formats differ:
+///
+/// ```
+/// enum BookFormat { Paperback, Hardback, Ebook }
+/// struct Book {
+///     isbn: i32,
+///     format: BookFormat,
+/// }
+///
+/// impl PartialEq for Book {
+///     fn eq(&self, other: &Book) -> bool {
+///         self.isbn == other.isbn
+///     }
+/// }
+///
+/// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
+/// let b2 = Book { isbn: 3, format: BookFormat::Ebook };
+/// let b3 = Book { isbn: 10, format: BookFormat::Paperback };
+///
+/// assert!(b1 == b2);
+/// assert!(b1 != b3);
+/// ```
 ///
 /// # Examples
 ///
@@ -96,7 +127,32 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
 /// This property cannot be checked by the compiler, and therefore `Eq` implies
 /// `PartialEq`, and has no extra methods.
 ///
-/// This trait can be used with `#[derive]`.
+/// ## Derivable
+///
+/// This trait can be used with `#[derive]`. When `derive`d, because `Eq` has
+/// no extra methods, it is only informing the compiler that this is an
+/// equivalence relation rather than a partial equivalence relation. Note that
+/// the `derive` strategy requires all fields are `PartialEq`, which isn't
+/// always desired.
+///
+/// ## How can I implement `Eq`?
+///
+/// If you cannot use the `derive` strategy, specify that your type implements
+/// `Eq`, which has no methods:
+///
+/// ```
+/// enum BookFormat { Paperback, Hardback, Ebook }
+/// struct Book {
+///     isbn: i32,
+///     format: BookFormat,
+/// }
+/// impl PartialEq for Book {
+///     fn eq(&self, other: &Book) -> bool {
+///         self.isbn == other.isbn
+///     }
+/// }
+/// impl Eq for Book {}
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Eq: PartialEq<Self> {
     // FIXME #13101: this method is used solely by #[deriving] to
@@ -190,8 +246,49 @@ impl Ordering {
 /// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true; and
 /// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
 ///
+/// ## Derivable
+///
 /// This trait can be used with `#[derive]`. When `derive`d, it will produce a lexicographic
 /// ordering based on the top-to-bottom declaration order of the struct's members.
+///
+/// ## How can I implement `Ord`?
+///
+/// `Ord` requires that the type also be `PartialOrd` and `Eq` (which requires `PartialEq`).
+///
+/// Then you must define an implementation for `cmp()`. You may find it useful to use
+/// `cmp()` on your type's fields.
+///
+/// Here's an example where you want to sort people by height only, disregarding `id`
+/// and `name`:
+///
+/// ```
+/// use std::cmp::Ordering;
+///
+/// #[derive(Eq)]
+/// struct Person {
+///     id: u32,
+///     name: String,
+///     height: u32,
+/// }
+///
+/// impl Ord for Person {
+///     fn cmp(&self, other: &Person) -> Ordering {
+///         self.height.cmp(&other.height)
+///     }
+/// }
+///
+/// impl PartialOrd for Person {
+///     fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
+///         Some(self.cmp(other))
+///     }
+/// }
+///
+/// impl PartialEq for Person {
+///     fn eq(&self, other: &Person) -> bool {
+///         self.height == other.height
+///     }
+/// }
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Ord: Eq + PartialOrd<Self> {
     /// This method returns an `Ordering` between `self` and `other`.
@@ -242,6 +339,13 @@ impl PartialOrd for Ordering {
 /// transitively: if `T: PartialOrd<U>` and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
 /// PartialOrd<V>`.
 ///
+/// ## Derivable
+///
+/// This trait can be used with `#[derive]`. When `derive`d, it will produce a lexicographic
+/// ordering based on the top-to-bottom declaration order of the struct's members.
+///
+/// ## How can I implement `Ord`?
+///
 /// PartialOrd only requires implementation of the `partial_cmp` method, with the others generated
 /// from default implementations.
 ///
@@ -249,8 +353,64 @@ impl PartialOrd for Ordering {
 /// total order. For example, for floating point numbers, `NaN < 0 == false` and `NaN >= 0 ==
 /// false` (cf. IEEE 754-2008 section 5.11).
 ///
-/// This trait can be used with `#[derive]`. When `derive`d, it will produce an ordering
-/// based on the top-to-bottom declaration order of the struct's members.
+/// `PartialOrd` requires your type to be `PartialEq`.
+///
+/// If your type is `Ord`, you can implement `partial_cmp()` by using `cmp()`:
+///
+/// ```
+/// use std::cmp::Ordering;
+///
+/// #[derive(Eq)]
+/// struct Person {
+///     id: u32,
+///     name: String,
+///     height: u32,
+/// }
+///
+/// impl PartialOrd for Person {
+///     fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
+///         Some(self.cmp(other))
+///     }
+/// }
+///
+/// impl Ord for Person {
+///     fn cmp(&self, other: &Person) -> Ordering {
+///         self.height.cmp(&other.height)
+///     }
+/// }
+///
+/// impl PartialEq for Person {
+///     fn eq(&self, other: &Person) -> bool {
+///         self.height == other.height
+///     }
+/// }
+/// ```
+///
+/// You may also find it useful to use `partial_cmp()` on your type`s fields. Here
+/// is an example of `Person` types who have a floating-point `height` field that
+/// is the only field to be used for sorting:
+///
+/// ```
+/// use std::cmp::Ordering;
+///
+/// struct Person {
+///     id: u32,
+///     name: String,
+///     height: f64,
+/// }
+///
+/// impl PartialOrd for Person {
+///     fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
+///         self.height.partial_cmp(&other.height)
+///     }
+/// }
+///
+/// impl PartialEq for Person {
+///     fn eq(&self, other: &Person) -> bool {
+///         self.height == other.height
+///     }
+/// }
+/// ```
 ///
 /// # Examples
 ///
diff --git a/src/libcore/default.rs b/src/libcore/default.rs
index 12c4a5ca200..485ddae07fb 100644
--- a/src/libcore/default.rs
+++ b/src/libcore/default.rs
@@ -9,76 +9,6 @@
 // except according to those terms.
 
 //! The `Default` trait for types which may have meaningful default values.
-//!
-//! Sometimes, you want to fall back to some kind of default value, and
-//! don't particularly care what it is. This comes up often with `struct`s
-//! that define a set of options:
-//!
-//! ```
-//! # #[allow(dead_code)]
-//! struct SomeOptions {
-//!     foo: i32,
-//!     bar: f32,
-//! }
-//! ```
-//!
-//! How can we define some default values? You can use `Default`:
-//!
-//! ```
-//! # #[allow(dead_code)]
-//! #[derive(Default)]
-//! struct SomeOptions {
-//!     foo: i32,
-//!     bar: f32,
-//! }
-//!
-//!
-//! fn main() {
-//!     let options: SomeOptions = Default::default();
-//! }
-//! ```
-//!
-//! Now, you get all of the default values. Rust implements `Default` for various primitives types.
-//! If you have your own type, you need to implement `Default` yourself:
-//!
-//! ```
-//! # #![allow(dead_code)]
-//! enum Kind {
-//!     A,
-//!     B,
-//!     C,
-//! }
-//!
-//! impl Default for Kind {
-//!     fn default() -> Kind { Kind::A }
-//! }
-//!
-//! #[derive(Default)]
-//! struct SomeOptions {
-//!     foo: i32,
-//!     bar: f32,
-//!     baz: Kind,
-//! }
-//!
-//!
-//! fn main() {
-//!     let options: SomeOptions = Default::default();
-//! }
-//! ```
-//!
-//! If you want to override a particular option, but still retain the other defaults:
-//!
-//! ```
-//! # #[allow(dead_code)]
-//! # #[derive(Default)]
-//! # struct SomeOptions {
-//! #     foo: i32,
-//! #     bar: f32,
-//! # }
-//! fn main() {
-//!     let options = SomeOptions { foo: 42, ..Default::default() };
-//! }
-//! ```
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -86,8 +16,72 @@ use marker::Sized;
 
 /// A trait for giving a type a useful default value.
 ///
-/// A struct can derive default implementations of `Default` for basic types using
-/// `#[derive(Default)]`.
+/// Sometimes, you want to fall back to some kind of default value, and
+/// don't particularly care what it is. This comes up often with `struct`s
+/// that define a set of options:
+///
+/// ```
+/// # #[allow(dead_code)]
+/// struct SomeOptions {
+///     foo: i32,
+///     bar: f32,
+/// }
+/// ```
+///
+/// How can we define some default values? You can use `Default`:
+///
+/// ```
+/// # #[allow(dead_code)]
+/// #[derive(Default)]
+/// struct SomeOptions {
+///     foo: i32,
+///     bar: f32,
+/// }
+///
+///
+/// fn main() {
+///     let options: SomeOptions = Default::default();
+/// }
+/// ```
+///
+/// Now, you get all of the default values. Rust implements `Default` for various primitives types.
+///
+/// If you want to override a particular option, but still retain the other defaults:
+///
+/// ```
+/// # #[allow(dead_code)]
+/// # #[derive(Default)]
+/// # struct SomeOptions {
+/// #     foo: i32,
+/// #     bar: f32,
+/// # }
+/// fn main() {
+///     let options = SomeOptions { foo: 42, ..Default::default() };
+/// }
+/// ```
+///
+/// ## Derivable
+///
+/// This trait can be used with `#[derive]` if all of the type's fields implement
+/// `Default`. When `derive`d, it will use the default value for each field's type.
+///
+/// ## How can I implement `Default`?
+///
+/// Provide an implementation for the `default()` method that returns the value of
+/// your type that should be the default:
+///
+/// ```
+/// # #![allow(dead_code)]
+/// enum Kind {
+///     A,
+///     B,
+///     C,
+/// }
+///
+/// impl Default for Kind {
+///     fn default() -> Kind { Kind::A }
+/// }
+/// ```
 ///
 /// # Examples
 ///
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index dde4d03dad8..6579e5dab54 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -318,7 +318,11 @@ impl<'a> Display for Arguments<'a> {
 ///
 /// [module]: ../../std/fmt/index.html
 ///
-/// This trait can be used with `#[derive]`.
+/// This trait can be used with `#[derive]` if all fields implement `Debug`. When
+/// `derive`d for structs, it will use the name of the `struct`, then `{`, then a
+/// comma-separated list of each field's name and `Debug` value, then `}`. For
+/// `enum`s, it will use the name of the variant and, if applicable, `(`, then the
+/// `Debug` values of the fields, then `)`.
 ///
 /// # Examples
 ///
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index 4d0fed98334..051eb974895 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -38,7 +38,7 @@
 //! ```
 //!
 //! If you need more control over how a value is hashed, you need to implement
-//! the trait `Hash`:
+//! the `Hash` trait:
 //!
 //! ```rust
 //! use std::hash::{Hash, Hasher, SipHasher};
@@ -97,7 +97,33 @@ mod sip;
 /// In other words, if two keys are equal, their hashes should also be equal.
 /// `HashMap` and `HashSet` both rely on this behavior.
 ///
-/// This trait can be used with `#[derive]`.
+/// ## Derivable
+///
+/// This trait can be used with `#[derive]` if all fields implement `Hash`.
+/// When `derive`d, the resulting hash will be the combination of the values
+/// from calling `.hash()` on each field.
+///
+/// ## How can I implement `Hash`?
+///
+/// If you need more control over how a value is hashed, you need to implement
+/// the `Hash` trait:
+///
+/// ```
+/// use std::hash::{Hash, Hasher};
+///
+/// struct Person {
+///     id: u32,
+///     name: String,
+///     phone: u64,
+/// }
+///
+/// impl Hash for Person {
+///     fn hash<H: Hasher>(&self, state: &mut H) {
+///         self.id.hash(state);
+///         self.phone.hash(state);
+///     }
+/// }
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Hash {
     /// Feeds this value into the state given, updating the hasher as necessary.
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 1ed2a219fac..c18d230be31 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -136,6 +136,26 @@ pub trait Unsize<T: ?Sized> {
 /// the trait `Copy` may not be implemented for this type; field `points` does not implement `Copy`
 /// ```
 ///
+/// ## When can my type _not_ be `Copy`?
+///
+/// Some types can't be copied safely. For example, copying `&mut T` would create an aliased
+/// mutable reference, and copying `String` would result in two attempts to free the same buffer.
+///
+/// Generalizing the latter case, any type implementing `Drop` can't be `Copy`, because it's
+/// managing some resource besides its own `size_of::<T>()` bytes.
+///
+/// ## When should my type be `Copy`?
+///
+/// Generally speaking, if your type _can_ implement `Copy`, it should. There's one important thing
+/// to consider though: if you think your type may _not_ be able to implement `Copy` in the future,
+/// then it might be prudent to not implement `Copy`. This is because removing `Copy` is a breaking
+/// change: that second example would fail to compile if we made `Foo` non-`Copy`.
+///
+/// ## Derivable
+///
+/// This trait can be used with `#[derive]` if all of its components implement `Copy` and the type
+/// implements `Clone`. The implementation will copy the bytes of each field using `memcpy`.
+///
 /// ## How can I implement `Copy`?
 ///
 /// There are two ways to implement `Copy` on your type:
@@ -155,25 +175,6 @@ pub trait Unsize<T: ?Sized> {
 ///
 /// There is a small difference between the two: the `derive` strategy will also place a `Copy`
 /// bound on type parameters, which isn't always desired.
-///
-/// ## When can my type _not_ be `Copy`?
-///
-/// Some types can't be copied safely. For example, copying `&mut T` would create an aliased
-/// mutable reference, and copying `String` would result in two attempts to free the same buffer.
-///
-/// Generalizing the latter case, any type implementing `Drop` can't be `Copy`, because it's
-/// managing some resource besides its own `size_of::<T>()` bytes.
-///
-/// ## When should my type be `Copy`?
-///
-/// Generally speaking, if your type _can_ implement `Copy`, it should. There's one important thing
-/// to consider though: if you think your type may _not_ be able to implement `Copy` in the future,
-/// then it might be prudent to not implement `Copy`. This is because removing `Copy` is a breaking
-/// change: that second example would fail to compile if we made `Foo` non-`Copy`.
-///
-/// # Derivable
-///
-/// This trait can be used with `#[derive]`.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "copy"]
 pub trait Copy : Clone {