Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5990be5

Browse files
author
lukaramu
committedAug 7, 2017
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
1 parent f2ff646 commit 5990be5

File tree

1 file changed

+78
-24
lines changed

1 file changed

+78
-24
lines changed
 

‎src/libcore/ops/deref.rs

+78-24
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,44 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
/// The `Deref` trait is used to specify the functionality of dereferencing
12-
/// operations, like `*v`.
11+
/// Used for immutable dereferencing operations, like `*v`.
1312
///
14-
/// `Deref` also enables ['`Deref` coercions'][coercions].
13+
/// In addition to being used for explicit dereferencing operations with the
14+
/// (unary) `*` operator in immutable contexts, `Deref` is also used implicitly
15+
/// by the compiler in many circumstances. This mechanism is called
16+
/// ['`Deref` coercion'][more]. In mutable contexts, [`DerefMut`] is used.
1517
///
16-
/// [coercions]: ../../book/first-edition/deref-coercions.html
18+
/// Implementing `Deref` for smart pointers makes accessing the data behind them
19+
/// convenient, which is why they implement `Deref`. On the other hand, the
20+
/// rules regarding `Deref` and [`DerefMut`] were designed specifically to
21+
/// accomodate smart pointers. Because of this, **`Deref` should only be
22+
/// implemented for smart pointers** to avoid confusion.
23+
///
24+
/// For similar reasons, **this trait should never fail**. Failure during
25+
/// dereferencing can be extremely confusing when `Deref` is invoked implicitly.
26+
///
27+
/// # More on `Deref` coercion
28+
///
29+
/// If `T` implements `Deref<Target = U>`, and `x` is a value of type `T`, then:
30+
/// * In immutable contexts, `*x` on non-pointer types is equivalent to
31+
/// `*Deref::deref(&x)`.
32+
/// * Values of type `&T` are coerced to values of type `&U`
33+
/// * `T` implicitly implements all the (immutable) methods of the type `U`.
34+
///
35+
/// For more details, visit [the chapter in *The Rust Programming Language*]
36+
/// [book] as well as the reference sections on [the dereference operator]
37+
/// [ref-deref-op], [the `Deref` trait][ref-deref-trait], and [type coercions].
38+
///
39+
/// [book]: ../../book/second-edition/ch15-02-deref.html
40+
/// [`DerefMut`]: trait.DerefMut.html
41+
/// [more]: #more-on-deref-coercion
42+
/// [ref-deref-op]: ../../reference/expressions.html#the-dereference-operator
43+
/// [ref-deref-trait]: ../../reference/the-deref-trait.html
44+
/// [type coercions]: ../../reference/type-coercions.html
1745
///
1846
/// # Examples
1947
///
20-
/// A struct with a single field which is accessible via dereferencing the
48+
/// A struct with a single field which is accessible by dereferencing the
2149
/// struct.
2250
///
2351
/// ```
@@ -35,19 +63,17 @@
3563
/// }
3664
/// }
3765
///
38-
/// fn main() {
39-
/// let x = DerefExample { value: 'a' };
40-
/// assert_eq!('a', *x);
41-
/// }
66+
/// let x = DerefExample { value: 'a' };
67+
/// assert_eq!('a', *x);
4268
/// ```
4369
#[lang = "deref"]
4470
#[stable(feature = "rust1", since = "1.0.0")]
4571
pub trait Deref {
46-
/// The resulting type after dereferencing
72+
/// The resulting type after dereferencing.
4773
#[stable(feature = "rust1", since = "1.0.0")]
4874
type Target: ?Sized;
4975

50-
/// The method called to dereference a value
76+
/// Dereferences the value.
5177
#[stable(feature = "rust1", since = "1.0.0")]
5278
fn deref(&self) -> &Self::Target;
5379
}
@@ -66,16 +92,46 @@ impl<'a, T: ?Sized> Deref for &'a mut T {
6692
fn deref(&self) -> &T { *self }
6793
}
6894

69-
/// The `DerefMut` trait is used to specify the functionality of dereferencing
70-
/// mutably like `*v = 1;`
71-
///
72-
/// `DerefMut` also enables ['`Deref` coercions'][coercions].
73-
///
74-
/// [coercions]: ../../book/first-edition/deref-coercions.html
95+
/// Used for mutable dereferencing operations, like in `*v = 1;`.
96+
///
97+
/// In addition to being used for explicit dereferencing operations with the
98+
/// (unary) `*` operator in mutable contexts, `DerefMut` is also used implicitly
99+
/// by the compiler in many circumstances. This mechanism is called
100+
/// ['`Deref` coercion'][more]. In immutable contexts, [`Deref`] is used.
101+
///
102+
/// Implementing `DerefMut` for smart pointers makes mutating the data behind
103+
/// them convenient, which is why they implement `DerefMut`. On the other hand,
104+
/// the rules regarding [`Deref`] and `DerefMut` were designed specifically to
105+
/// accomodate smart pointers. Because of this, **`DerefMut` should only be
106+
/// implemented for smart pointers** to avoid confusion.
107+
///
108+
/// For similar reasons, **this trait should never fail**. Failure during
109+
/// dereferencing can be extremely confusing when `DerefMut` is invoked
110+
/// implicitly.
111+
///
112+
/// # More on `Deref` coercion
113+
///
114+
/// If `T` implements `MutDeref<Target = U>`, and `x` is a value of type `T`,
115+
/// then:
116+
/// * In mutable contexts, `*x` on non-pointer types is equivalent to
117+
/// `*Deref::deref(&x)`.
118+
/// * Values of type `&mut T` are coerced to values of type `&mut U`
119+
/// * `T` implicitly implements all the (mutable) methods of the type `U`.
120+
///
121+
/// For more details, visit [the chapter in *The Rust Programming Language*]
122+
/// [book] as well as the reference sections on [the dereference operator]
123+
/// [ref-deref-op], [the `Deref` trait][ref-deref-trait], and [type coercions].
124+
///
125+
/// [book]: ../../book/second-edition/ch15-02-deref.html
126+
/// [`Deref`]: trait.Deref.html
127+
/// [more]: #more-on-deref-coercion
128+
/// [ref-deref-op]: ../../reference/expressions.html#the-dereference-operator
129+
/// [ref-deref-trait]: ../../reference/the-deref-trait.html
130+
/// [type coercions]: ../../reference/type-coercions.html
75131
///
76132
/// # Examples
77133
///
78-
/// A struct with a single field which is modifiable via dereferencing the
134+
/// A struct with a single field which is modifiable by dereferencing the
79135
/// struct.
80136
///
81137
/// ```
@@ -99,16 +155,14 @@ impl<'a, T: ?Sized> Deref for &'a mut T {
99155
/// }
100156
/// }
101157
///
102-
/// fn main() {
103-
/// let mut x = DerefMutExample { value: 'a' };
104-
/// *x = 'b';
105-
/// assert_eq!('b', *x);
106-
/// }
158+
/// let mut x = DerefMutExample { value: 'a' };
159+
/// *x = 'b';
160+
/// assert_eq!('b', *x);
107161
/// ```
108162
#[lang = "deref_mut"]
109163
#[stable(feature = "rust1", since = "1.0.0")]
110164
pub trait DerefMut: Deref {
111-
/// The method called to mutably dereference a value
165+
/// Mutably dereferences the value.
112166
#[stable(feature = "rust1", since = "1.0.0")]
113167
fn deref_mut(&mut self) -> &mut Self::Target;
114168
}

0 commit comments

Comments
 (0)
Please sign in to comment.