]> git.lizzy.rs Git - rust.git/blob - library/core/src/ops/deref.rs
Auto merge of #88988 - Mark-Simulacrum:avoid-into-ok, r=nagisa
[rust.git] / library / core / src / ops / deref.rs
1 /// Used for immutable dereferencing operations, like `*v`.
2 ///
3 /// In addition to being used for explicit dereferencing operations with the
4 /// (unary) `*` operator in immutable contexts, `Deref` is also used implicitly
5 /// by the compiler in many circumstances. This mechanism is called
6 /// ['`Deref` coercion'][more]. In mutable contexts, [`DerefMut`] is used.
7 ///
8 /// Implementing `Deref` for smart pointers makes accessing the data behind them
9 /// convenient, which is why they implement `Deref`. On the other hand, the
10 /// rules regarding `Deref` and [`DerefMut`] were designed specifically to
11 /// accommodate smart pointers. Because of this, **`Deref` should only be
12 /// implemented for smart pointers** to avoid confusion.
13 ///
14 /// For similar reasons, **this trait should never fail**. Failure during
15 /// dereferencing can be extremely confusing when `Deref` is invoked implicitly.
16 ///
17 /// # More on `Deref` coercion
18 ///
19 /// If `T` implements `Deref<Target = U>`, and `x` is a value of type `T`, then:
20 ///
21 /// * In immutable contexts, `*x` (where `T` is neither a reference nor a raw pointer)
22 ///   is equivalent to `*Deref::deref(&x)`.
23 /// * Values of type `&T` are coerced to values of type `&U`
24 /// * `T` implicitly implements all the (immutable) methods of the type `U`.
25 ///
26 /// For more details, visit [the chapter in *The Rust Programming Language*][book]
27 /// as well as the reference sections on [the dereference operator][ref-deref-op],
28 /// [method resolution] and [type coercions].
29 ///
30 /// [book]: ../../book/ch15-02-deref.html
31 /// [more]: #more-on-deref-coercion
32 /// [ref-deref-op]: ../../reference/expressions/operator-expr.html#the-dereference-operator
33 /// [method resolution]: ../../reference/expressions/method-call-expr.html
34 /// [type coercions]: ../../reference/type-coercions.html
35 ///
36 /// # Examples
37 ///
38 /// A struct with a single field which is accessible by dereferencing the
39 /// struct.
40 ///
41 /// ```
42 /// use std::ops::Deref;
43 ///
44 /// struct DerefExample<T> {
45 ///     value: T
46 /// }
47 ///
48 /// impl<T> Deref for DerefExample<T> {
49 ///     type Target = T;
50 ///
51 ///     fn deref(&self) -> &Self::Target {
52 ///         &self.value
53 ///     }
54 /// }
55 ///
56 /// let x = DerefExample { value: 'a' };
57 /// assert_eq!('a', *x);
58 /// ```
59 #[lang = "deref"]
60 #[doc(alias = "*")]
61 #[doc(alias = "&*")]
62 #[stable(feature = "rust1", since = "1.0.0")]
63 #[rustc_diagnostic_item = "Deref"]
64 pub trait Deref {
65     /// The resulting type after dereferencing.
66     #[stable(feature = "rust1", since = "1.0.0")]
67     #[rustc_diagnostic_item = "deref_target"]
68     #[lang = "deref_target"]
69     type Target: ?Sized;
70
71     /// Dereferences the value.
72     #[must_use]
73     #[stable(feature = "rust1", since = "1.0.0")]
74     #[rustc_diagnostic_item = "deref_method"]
75     fn deref(&self) -> &Self::Target;
76 }
77
78 #[stable(feature = "rust1", since = "1.0.0")]
79 #[rustc_const_unstable(feature = "const_deref", issue = "88955")]
80 impl<T: ?Sized> const Deref for &T {
81     type Target = T;
82
83     #[rustc_diagnostic_item = "noop_method_deref"]
84     fn deref(&self) -> &T {
85         *self
86     }
87 }
88
89 #[stable(feature = "rust1", since = "1.0.0")]
90 impl<T: ?Sized> !DerefMut for &T {}
91
92 #[stable(feature = "rust1", since = "1.0.0")]
93 #[rustc_const_unstable(feature = "const_deref", issue = "88955")]
94 impl<T: ?Sized> const Deref for &mut T {
95     type Target = T;
96
97     fn deref(&self) -> &T {
98         *self
99     }
100 }
101
102 /// Used for mutable dereferencing operations, like in `*v = 1;`.
103 ///
104 /// In addition to being used for explicit dereferencing operations with the
105 /// (unary) `*` operator in mutable contexts, `DerefMut` is also used implicitly
106 /// by the compiler in many circumstances. This mechanism is called
107 /// ['`Deref` coercion'][more]. In immutable contexts, [`Deref`] is used.
108 ///
109 /// Implementing `DerefMut` for smart pointers makes mutating the data behind
110 /// them convenient, which is why they implement `DerefMut`. On the other hand,
111 /// the rules regarding [`Deref`] and `DerefMut` were designed specifically to
112 /// accommodate smart pointers. Because of this, **`DerefMut` should only be
113 /// implemented for smart pointers** to avoid confusion.
114 ///
115 /// For similar reasons, **this trait should never fail**. Failure during
116 /// dereferencing can be extremely confusing when `DerefMut` is invoked
117 /// implicitly.
118 ///
119 /// # More on `Deref` coercion
120 ///
121 /// If `T` implements `DerefMut<Target = U>`, and `x` is a value of type `T`,
122 /// then:
123 ///
124 /// * In mutable contexts, `*x` (where `T` is neither a reference nor a raw pointer)
125 ///   is equivalent to `*DerefMut::deref_mut(&mut x)`.
126 /// * Values of type `&mut T` are coerced to values of type `&mut U`
127 /// * `T` implicitly implements all the (mutable) methods of the type `U`.
128 ///
129 /// For more details, visit [the chapter in *The Rust Programming Language*][book]
130 /// as well as the reference sections on [the dereference operator][ref-deref-op],
131 /// [method resolution] and [type coercions].
132 ///
133 /// [book]: ../../book/ch15-02-deref.html
134 /// [more]: #more-on-deref-coercion
135 /// [ref-deref-op]: ../../reference/expressions/operator-expr.html#the-dereference-operator
136 /// [method resolution]: ../../reference/expressions/method-call-expr.html
137 /// [type coercions]: ../../reference/type-coercions.html
138 ///
139 /// # Examples
140 ///
141 /// A struct with a single field which is modifiable by dereferencing the
142 /// struct.
143 ///
144 /// ```
145 /// use std::ops::{Deref, DerefMut};
146 ///
147 /// struct DerefMutExample<T> {
148 ///     value: T
149 /// }
150 ///
151 /// impl<T> Deref for DerefMutExample<T> {
152 ///     type Target = T;
153 ///
154 ///     fn deref(&self) -> &Self::Target {
155 ///         &self.value
156 ///     }
157 /// }
158 ///
159 /// impl<T> DerefMut for DerefMutExample<T> {
160 ///     fn deref_mut(&mut self) -> &mut Self::Target {
161 ///         &mut self.value
162 ///     }
163 /// }
164 ///
165 /// let mut x = DerefMutExample { value: 'a' };
166 /// *x = 'b';
167 /// assert_eq!('b', *x);
168 /// ```
169 #[lang = "deref_mut"]
170 #[doc(alias = "*")]
171 #[stable(feature = "rust1", since = "1.0.0")]
172 pub trait DerefMut: Deref {
173     /// Mutably dereferences the value.
174     #[stable(feature = "rust1", since = "1.0.0")]
175     fn deref_mut(&mut self) -> &mut Self::Target;
176 }
177
178 #[stable(feature = "rust1", since = "1.0.0")]
179 impl<T: ?Sized> DerefMut for &mut T {
180     fn deref_mut(&mut self) -> &mut T {
181         *self
182     }
183 }
184
185 /// Indicates that a struct can be used as a method receiver, without the
186 /// `arbitrary_self_types` feature. This is implemented by stdlib pointer types like `Box<T>`,
187 /// `Rc<T>`, `&T`, and `Pin<P>`.
188 #[lang = "receiver"]
189 #[unstable(feature = "receiver_trait", issue = "none")]
190 #[doc(hidden)]
191 pub trait Receiver {
192     // Empty.
193 }
194
195 #[unstable(feature = "receiver_trait", issue = "none")]
196 impl<T: ?Sized> Receiver for &T {}
197
198 #[unstable(feature = "receiver_trait", issue = "none")]
199 impl<T: ?Sized> Receiver for &mut T {}