about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorMartin Hoffmann <hn@nvnc.de>2018-02-27 16:24:52 +0100
committerMartin Hoffmann <hn@nvnc.de>2018-02-27 16:24:52 +0100
commit44be054a2acbeeb682d02a5f88ddedc0cb5c9bf2 (patch)
tree829c5d94a98cdcb2379ca48b23ec4ad179ffdd14 /src/libcore
parent7ae7e5393367cdc9a630cd56911ab42f499c091f (diff)
downloadrust-44be054a2acbeeb682d02a5f88ddedc0cb5c9bf2.tar.gz
rust-44be054a2acbeeb682d02a5f88ddedc0cb5c9bf2.zip
Further refinement of Borrow documentation.
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/borrow.rs68
1 files changed, 36 insertions, 32 deletions
diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs
index 1f692d019c3..c0f1989f879 100644
--- a/src/libcore/borrow.rs
+++ b/src/libcore/borrow.rs
@@ -17,36 +17,41 @@
 /// In Rust, it is common to provide different representations of a type for
 /// different use cases. For instance, storage location and management for a
 /// value can be specifically chosen as appropriate for a particular use via
-/// pointer types such as [`Box<T>`] or [`Rc<T>`] or one can opt into
-/// concurrency via synchronization types such as [`Mutex<T>`], avoiding the
-/// associated cost when in parallel doesn’t happen. Beyond these generic
+/// pointer types such as [`Box<T>`] or [`Rc<T>`]. Beyond these generic
 /// wrappers that can be used with any type, some types provide optional
 /// facets providing potentially costly functionality. An example for such a
 /// type is [`String`] which adds the ability to extend a string to the basic
 /// [`str`]. This requires keeping additional information unnecessary for a
-/// simple, imutable string.
+/// simple, immutable string.
 ///
 /// These types signal that they are a specialized representation of a basic
 /// type `T` by implementing `Borrow<T>`. The method `borrow` provides a way
-/// to convert a reference to the type into a reference to the underlying
-/// basic type.
+/// to convert a reference to the type into a reference to this basic type
+/// `T`.
 ///
-/// If a type implementing `Borrow<T>` implements other traits also
-/// implemented by `T`, these implementations behave identically if the trait
-/// is concerned with the data rather than its representation. For instance,
-/// the comparison traits such as `PartialEq` or `PartialOrd` must behave
-/// identical for `T` and any type implemeting `Borrow<T>`.
+/// Further, when providing implementations for additional traits, it needs
+/// to be considered whether they should behave identical to those of the
+/// underlying type as a consequence of acting as a representation of that
+/// underlying type.
 ///
-/// When writing generic code, a use of `Borrow` should always be justified
-/// by additional trait bounds, making it clear that the two types need to
-/// behave identically in a certain context. If the code should merely be
-/// able to operate on any type that can produce a reference to a given type,
-/// you should use [`AsRef`] instead.
+/// Generic code typically uses `Borrow<T>` when it not only needs access
+/// to a reference of the underlying type but relies on the identical
+/// behavior of these additional trait implementations. These traits are
+/// likely to appear as additional trait bounds.
 ///
-/// The companion trait [`BorrowMut`] provides the same guarantees for
-/// mutable references.
+/// If generic code merely needs to work for all types that can
+/// provide a reference to related type `T`, it is often better to use
+/// [`AsRef<T>`] as more types can safely implement it.
 ///
-/// [`AsRef`]: ../../std/convert/trait.AsRef.html
+/// If a type implementing `Borrow<T>` also wishes to allow mutable access
+/// to the underlying type `T`, it can do so by implementing the companion
+/// trait [`BorrowMut`].
+///
+/// Note also that it is perfectly fine for a single type to have multiple
+/// implementations of `Borrow<T>` for different `T`s. In fact, a blanket
+/// implementation lets every type be at least a borrow of itself.
+///
+/// [`AsRef<T>`]: ../../std/convert/trait.AsRef.html
 /// [`BorrowMut`]: trait.BorrowMut.html
 /// [`Box<T>`]: ../../std/boxed/struct.Box.html
 /// [`Mutex<T>`]: ../../std/sync/struct.Mutex.html
@@ -111,7 +116,7 @@
 /// data, called `Q` in the method signature above. It states that `K` is a
 /// representation of `Q` by requiring that `K: Borrow<Q>`. By additionally
 /// requiring `Q: Hash + Eq`, it demands that `K` and `Q` have
-/// implementations of the `Hash` and `Eq` traits that procude identical
+/// implementations of the `Hash` and `Eq` traits that produce identical
 /// results.
 ///
 /// The implementation of `get` relies in particular on identical
@@ -124,15 +129,15 @@
 /// type that wraps a string but compares ASCII letters ignoring their case:
 ///
 /// ```
-/// pub struct CIString(String);
+/// pub struct CaseInsensitiveString(String);
 ///
-/// impl PartialEq for CIString {
+/// impl PartialEq for CaseInsensitiveString {
 ///     fn eq(&self, other: &Self) -> bool {
 ///         self.0.eq_ignore_ascii_case(&other.0)
 ///     }
 /// }
 ///
-/// impl Eq for CIString { }
+/// impl Eq for CaseInsensitiveString { }
 /// ```
 ///
 /// Because two equal values need to produce the same hash value, the
@@ -140,8 +145,8 @@
 ///
 /// ```
 /// # use std::hash::{Hash, Hasher};
-/// # pub struct CIString(String);
-/// impl Hash for CIString {
+/// # pub struct CaseInsensitiveString(String);
+/// impl Hash for CaseInsensitiveString {
 ///     fn hash<H: Hasher>(&self, state: &mut H) {
 ///         for c in self.0.as_bytes() {
 ///             c.to_ascii_lowercase().hash(state)
@@ -150,13 +155,12 @@
 /// }
 /// ```
 ///
-/// Can `CIString` implement `Borrow<str>`? It certainly can provide a
-/// reference to a string slice via its contained owned string. But because
-/// its `Hash` implementation differs, it cannot fulfill the guarantee for
-/// `Borrow` that all common trait implementations must behave the same way
-/// and must not, in fact, implement `Borrow<str>`. If it wants to allow
-/// others access to the underlying `str`, it can do that via `AsRef<str>`
-/// which doesn’t carry any such restrictions.
+/// Can `CaseInsensitiveString` implement `Borrow<str>`? It certainly can
+/// provide a reference to a string slice via its contained owned string.
+/// But because its `Hash` implementation differs, it behaves differently
+/// from `str` and therefore must not, in fact, implement `Borrow<str>`.
+/// If it wants to allow others access to the underlying `str`, it can do
+/// that via `AsRef<str>` which doesn’t carry any extra requirements.
 ///
 /// [`Hash`]: ../../std/hash/trait.Hash.html
 /// [`HashMap<K, V>`]: ../../std/collections/struct.HashMap.html