about summary refs log tree commit diff
path: root/src/libcore/ops
diff options
context:
space:
mode:
authorlukaramu <lukaramu@users.noreply.github.com>2017-08-07 17:09:43 +0200
committerlukaramu <lukaramu@users.noreply.github.com>2017-08-07 23:10:16 +0200
commit5990be523d00edaf69cfd6d3e28d9fb78eb67bcd (patch)
treee789e035dc85f97957ab7c959ba4f5825a84a8fd /src/libcore/ops
parentf2ff646f5f71fd89b19ec11d7bb03128156f1af9 (diff)
downloadrust-5990be523d00edaf69cfd6d3e28d9fb78eb67bcd.tar.gz
rust-5990be523d00edaf69cfd6d3e28d9fb78eb67bcd.zip
Expand docs on `Deref` and `DerefMut`
Part of #29365.
* Expanded the explanaition sections, adapting some parts from the book,
  the reference, as well as the API guidelines. As such, the docs now
  explicitly state that `Deref` and `DerefMut` should only be implemented
  for smart pointers and that they should not fail. Additionally, there
  is now a short primer on `Deref` coercion.
* Added links to `DerefMut` from `Deref` and vice versa
* Added links to relevant reference sections
* Removed "stuttering" in summary sentences
* Changed summary sentences of `Deref::deref` and `Deref::deref_mut` to
  be in 3rd person singular
* Removed explicit uses of `fn main()` in the examples
Diffstat (limited to 'src/libcore/ops')
-rw-r--r--src/libcore/ops/deref.rs102
1 files changed, 78 insertions, 24 deletions
diff --git a/src/libcore/ops/deref.rs b/src/libcore/ops/deref.rs
index 18cf20ac411..ac5ff1556f4 100644
--- a/src/libcore/ops/deref.rs
+++ b/src/libcore/ops/deref.rs
@@ -8,16 +8,44 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-/// The `Deref` trait is used to specify the functionality of dereferencing
-/// operations, like `*v`.
+/// Used for immutable dereferencing operations, like `*v`.
 ///
-/// `Deref` also enables ['`Deref` coercions'][coercions].
+/// In addition to being used for explicit dereferencing operations with the
+/// (unary) `*` operator in immutable contexts, `Deref` is also used implicitly
+/// by the compiler in many circumstances. This mechanism is called
+/// ['`Deref` coercion'][more]. In mutable contexts, [`DerefMut`] is used.
 ///
-/// [coercions]: ../../book/first-edition/deref-coercions.html
+/// Implementing `Deref` for smart pointers makes accessing the data behind them
+/// convenient, which is why they implement `Deref`. On the other hand, the
+/// rules regarding `Deref` and [`DerefMut`] were designed specifically to
+/// accomodate smart pointers. Because of this, **`Deref` should only be
+/// implemented for smart pointers** to avoid confusion.
+///
+/// For similar reasons, **this trait should never fail**. Failure during
+/// dereferencing can be extremely confusing when `Deref` is invoked implicitly.
+///
+/// # More on `Deref` coercion
+///
+/// If `T` implements `Deref<Target = U>`, and `x` is a value of type `T`, then:
+/// * In immutable contexts, `*x` on non-pointer types is equivalent to
+///   `*Deref::deref(&x)`.
+/// * Values of type `&T` are coerced to values of type `&U`
+/// * `T` implicitly implements all the (immutable) methods of the type `U`.
+///
+/// For more details, visit [the chapter in *The Rust Programming Language*]
+/// [book] as well as the reference sections on [the dereference operator]
+/// [ref-deref-op], [the `Deref` trait][ref-deref-trait], and [type coercions].
+///
+/// [book]: ../../book/second-edition/ch15-02-deref.html
+/// [`DerefMut`]: trait.DerefMut.html
+/// [more]: #more-on-deref-coercion
+/// [ref-deref-op]: ../../reference/expressions.html#the-dereference-operator
+/// [ref-deref-trait]: ../../reference/the-deref-trait.html
+/// [type coercions]: ../../reference/type-coercions.html
 ///
 /// # Examples
 ///
-/// A struct with a single field which is accessible via dereferencing the
+/// A struct with a single field which is accessible by dereferencing the
 /// struct.
 ///
 /// ```
@@ -35,19 +63,17 @@
 ///     }
 /// }
 ///
-/// fn main() {
-///     let x = DerefExample { value: 'a' };
-///     assert_eq!('a', *x);
-/// }
+/// let x = DerefExample { value: 'a' };
+/// assert_eq!('a', *x);
 /// ```
 #[lang = "deref"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Deref {
-    /// The resulting type after dereferencing
+    /// The resulting type after dereferencing.
     #[stable(feature = "rust1", since = "1.0.0")]
     type Target: ?Sized;
 
-    /// The method called to dereference a value
+    /// Dereferences the value.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn deref(&self) -> &Self::Target;
 }
@@ -66,16 +92,46 @@ impl<'a, T: ?Sized> Deref for &'a mut T {
     fn deref(&self) -> &T { *self }
 }
 
-/// The `DerefMut` trait is used to specify the functionality of dereferencing
-/// mutably like `*v = 1;`
-///
-/// `DerefMut` also enables ['`Deref` coercions'][coercions].
-///
-/// [coercions]: ../../book/first-edition/deref-coercions.html
+/// Used for mutable dereferencing operations, like in `*v = 1;`.
+///
+/// In addition to being used for explicit dereferencing operations with the
+/// (unary) `*` operator in mutable contexts, `DerefMut` is also used implicitly
+/// by the compiler in many circumstances. This mechanism is called
+/// ['`Deref` coercion'][more]. In immutable contexts, [`Deref`] is used.
+///
+/// Implementing `DerefMut` for smart pointers makes mutating the data behind
+/// them convenient, which is why they implement `DerefMut`. On the other hand,
+/// the rules regarding [`Deref`] and `DerefMut` were designed specifically to
+/// accomodate smart pointers. Because of this, **`DerefMut` should only be
+/// implemented for smart pointers** to avoid confusion.
+///
+/// For similar reasons, **this trait should never fail**. Failure during
+/// dereferencing can be extremely confusing when `DerefMut` is invoked
+/// implicitly.
+///
+/// # More on `Deref` coercion
+///
+/// If `T` implements `MutDeref<Target = U>`, and `x` is a value of type `T`,
+/// then:
+/// * In mutable contexts, `*x` on non-pointer types is equivalent to
+///   `*Deref::deref(&x)`.
+/// * Values of type `&mut T` are coerced to values of type `&mut U`
+/// * `T` implicitly implements all the (mutable) methods of the type `U`.
+///
+/// For more details, visit [the chapter in *The Rust Programming Language*]
+/// [book] as well as the reference sections on [the dereference operator]
+/// [ref-deref-op], [the `Deref` trait][ref-deref-trait], and [type coercions].
+///
+/// [book]: ../../book/second-edition/ch15-02-deref.html
+/// [`Deref`]: trait.Deref.html
+/// [more]: #more-on-deref-coercion
+/// [ref-deref-op]: ../../reference/expressions.html#the-dereference-operator
+/// [ref-deref-trait]: ../../reference/the-deref-trait.html
+/// [type coercions]: ../../reference/type-coercions.html
 ///
 /// # Examples
 ///
-/// A struct with a single field which is modifiable via dereferencing the
+/// A struct with a single field which is modifiable by dereferencing the
 /// struct.
 ///
 /// ```
@@ -99,16 +155,14 @@ impl<'a, T: ?Sized> Deref for &'a mut T {
 ///     }
 /// }
 ///
-/// fn main() {
-///     let mut x = DerefMutExample { value: 'a' };
-///     *x = 'b';
-///     assert_eq!('b', *x);
-/// }
+/// let mut x = DerefMutExample { value: 'a' };
+/// *x = 'b';
+/// assert_eq!('b', *x);
 /// ```
 #[lang = "deref_mut"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait DerefMut: Deref {
-    /// The method called to mutably dereference a value
+    /// Mutably dereferences the value.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn deref_mut(&mut self) -> &mut Self::Target;
 }