deref.rs - source (original) (raw)

core/ops/

deref.rs

1use crate:📑:PointeeSized;
2
3/// Used for immutable dereferencing operations, like `*v`.
4///
5/// In addition to being used for explicit dereferencing operations with the
6/// (unary) `*` operator in immutable contexts, `Deref` is also used implicitly
7/// by the compiler in many circumstances. This mechanism is called
8/// ["`Deref` coercion"][coercion]. In mutable contexts, [`DerefMut`] is used and
9/// mutable deref coercion similarly occurs.
10///
11/// **Warning:** Deref coercion is a powerful language feature which has
12/// far-reaching implications for every type that implements `Deref`. The
13/// compiler will silently insert calls to `Deref::deref`. For this reason, one
14/// should be careful about implementing `Deref` and only do so when deref
15/// coercion is desirable. See [below][implementing] for advice on when this is
16/// typically desirable or undesirable.
17///
18/// Types that implement `Deref` or `DerefMut` are often called "smart
19/// pointers" and the mechanism of deref coercion has been specifically designed
20/// to facilitate the pointer-like behavior that name suggests. Often, the
21/// purpose of a "smart pointer" type is to change the ownership semantics
22/// of a contained value (for example, [`Rc`][rc] or [`Cow`][cow]) or the
23/// storage semantics of a contained value (for example, [`Box`][box]).
24///
25/// # Deref coercion
26///
27/// If `T` implements `Deref<Target = U>`, and `v` is a value of type `T`, then:
28///
29/// * In immutable contexts, `*v` (where `T` is neither a reference nor a raw
30///   pointer) is equivalent to `*Deref::deref(&v)`.
31/// * Values of type `&T` are coerced to values of type `&U`
32/// * `T` implicitly implements all the methods of the type `U` which take the
33///   `&self` receiver.
34///
35/// For more details, visit [the chapter in *The Rust Programming Language*][book]
36/// as well as the reference sections on [the dereference operator][ref-deref-op],
37/// [method resolution], and [type coercions].
38///
39/// # When to implement `Deref` or `DerefMut`
40///
41/// The same advice applies to both deref traits. In general, deref traits
42/// **should** be implemented if:
43///
44/// 1. a value of the type transparently behaves like a value of the target
45///    type;
46/// 1. the implementation of the deref function is cheap; and
47/// 1. users of the type will not be surprised by any deref coercion behavior.
48///
49/// In general, deref traits **should not** be implemented if:
50///
51/// 1. the deref implementations could fail unexpectedly; or
52/// 1. the type has methods that are likely to collide with methods on the
53///    target type; or
54/// 1. committing to deref coercion as part of the public API is not desirable.
55///
56/// Note that there's a large difference between implementing deref traits
57/// generically over many target types, and doing so only for specific target
58/// types.
59///
60/// Generic implementations, such as for [`Box<T>`][box] (which is generic over
61/// every type and dereferences to `T`) should be careful to provide few or no
62/// methods, since the target type is unknown and therefore every method could
63/// collide with one on the target type, causing confusion for users.
64/// `impl<T> Box<T>` has no methods (though several associated functions),
65/// partly for this reason.
66///
67/// Specific implementations, such as for [`String`][string] (whose `Deref`
68/// implementation has `Target = str`) can have many methods, since avoiding
69/// collision is much easier. `String` and `str` both have many methods, and
70/// `String` additionally behaves as if it has every method of `str` because of
71/// deref coercion. The implementing type may also be generic while the
72/// implementation is still specific in this sense; for example, [`Vec<T>`][vec]
73/// dereferences to `[T]`, so methods of `T` are not applicable.
74///
75/// Consider also that deref coercion means that deref traits are a much larger
76/// part of a type's public API than any other trait as it is implicitly called
77/// by the compiler. Therefore, it is advisable to consider whether this is
78/// something you are comfortable supporting as a public API.
79///
80/// The [`AsRef`] and [`Borrow`][core::borrow::Borrow] traits have very similar
81/// signatures to `Deref`. It may be desirable to implement either or both of
82/// these, whether in addition to or rather than deref traits. See their
83/// documentation for details.
84///
85/// # Fallibility
86///
87/// **This trait's method should never unexpectedly fail**. Deref coercion means
88/// the compiler will often insert calls to `Deref::deref` implicitly. Failure
89/// during dereferencing can be extremely confusing when `Deref` is invoked
90/// implicitly. In the majority of uses it should be infallible, though it may
91/// be acceptable to panic if the type is misused through programmer error, for
92/// example.
93///
94/// However, infallibility is not enforced and therefore not guaranteed.
95/// As such, `unsafe` code should not rely on infallibility in general for
96/// soundness.
97///
98/// [book]: ../../book/ch15-02-deref.html
99/// [coercion]: #deref-coercion
100/// [implementing]: #when-to-implement-deref-or-derefmut
101/// [ref-deref-op]: ../../reference/expressions/operator-expr.html#the-dereference-operator
102/// [method resolution]: ../../reference/expressions/method-call-expr.html
103/// [type coercions]: ../../reference/type-coercions.html
104/// [box]: ../../alloc/boxed/struct.Box.html
105/// [string]: ../../alloc/string/struct.String.html
106/// [vec]: ../../alloc/vec/struct.Vec.html
107/// [rc]: ../../alloc/rc/struct.Rc.html
108/// [cow]: ../../alloc/borrow/enum.Cow.html
109///
110/// # Examples
111///
112/// A struct with a single field which is accessible by dereferencing the
113/// struct.
114///
115/// ```
116/// use std::ops::Deref;
117///
118/// struct DerefExample<T> {
119///     value: T
120/// }
121///
122/// impl<T> Deref for DerefExample<T> {
123///     type Target = T;
124///
125///     fn deref(&self) -> &Self::Target {
126///         &self.value
127///     }
128/// }
129///
130/// let x = DerefExample { value: 'a' };
131/// assert_eq!('a', *x);
132/// ```
133#[lang = "deref"]
134#[doc(alias = "*")]
135#[doc(alias = "&*")]
136#[stable(feature = "rust1", since = "1.0.0")]
137#[rustc_diagnostic_item = "Deref"]
138#[const_trait]
139#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
140pub trait Deref: PointeeSized {
141    /// The resulting type after dereferencing.
142    #[stable(feature = "rust1", since = "1.0.0")]
143    #[rustc_diagnostic_item = "deref_target"]
144    #[lang = "deref_target"]
145    type Target: ?Sized;
146
147    /// Dereferences the value.
148    #[must_use]
149    #[stable(feature = "rust1", since = "1.0.0")]
150    #[rustc_diagnostic_item = "deref_method"]
151    fn deref(&self) -> &Self::Target;
152}
153
154#[stable(feature = "rust1", since = "1.0.0")]
155#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
156impl<T: ?Sized> const Deref for &T {
157    type Target = T;
158
159    #[rustc_diagnostic_item = "noop_method_deref"]
160    fn deref(&self) -> &T {
161        *self
162    }
163}
164
165#[stable(feature = "rust1", since = "1.0.0")]
166impl<T: ?Sized> !DerefMut for &T {}
167
168#[stable(feature = "rust1", since = "1.0.0")]
169#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
170impl<T: ?Sized> const Deref for &mut T {
171    type Target = T;
172
173    fn deref(&self) -> &T {
174        *self
175    }
176}
177
178/// Used for mutable dereferencing operations, like in `*v = 1;`.
179///
180/// In addition to being used for explicit dereferencing operations with the
181/// (unary) `*` operator in mutable contexts, `DerefMut` is also used implicitly
182/// by the compiler in many circumstances. This mechanism is called
183/// ["mutable deref coercion"][coercion]. In immutable contexts, [`Deref`] is used.
184///
185/// **Warning:** Deref coercion is a powerful language feature which has
186/// far-reaching implications for every type that implements `DerefMut`. The
187/// compiler will silently insert calls to `DerefMut::deref_mut`. For this
188/// reason, one should be careful about implementing `DerefMut` and only do so
189/// when mutable deref coercion is desirable. See [the `Deref` docs][implementing]
190/// for advice on when this is typically desirable or undesirable.
191///
192/// Types that implement `DerefMut` or `Deref` are often called "smart
193/// pointers" and the mechanism of deref coercion has been specifically designed
194/// to facilitate the pointer-like behavior that name suggests. Often, the
195/// purpose of a "smart pointer" type is to change the ownership semantics
196/// of a contained value (for example, [`Rc`][rc] or [`Cow`][cow]) or the
197/// storage semantics of a contained value (for example, [`Box`][box]).
198///
199/// # Mutable deref coercion
200///
201/// If `T` implements `DerefMut<Target = U>`, and `v` is a value of type `T`,
202/// then:
203///
204/// * In mutable contexts, `*v` (where `T` is neither a reference nor a raw pointer)
205///   is equivalent to `*DerefMut::deref_mut(&mut v)`.
206/// * Values of type `&mut T` are coerced to values of type `&mut U`
207/// * `T` implicitly implements all the (mutable) methods of the type `U`.
208///
209/// For more details, visit [the chapter in *The Rust Programming Language*][book]
210/// as well as the reference sections on [the dereference operator][ref-deref-op],
211/// [method resolution] and [type coercions].
212///
213/// # Fallibility
214///
215/// **This trait's method should never unexpectedly fail**. Deref coercion means
216/// the compiler will often insert calls to `DerefMut::deref_mut` implicitly.
217/// Failure during dereferencing can be extremely confusing when `DerefMut` is
218/// invoked implicitly. In the majority of uses it should be infallible, though
219/// it may be acceptable to panic if the type is misused through programmer
220/// error, for example.
221///
222/// However, infallibility is not enforced and therefore not guaranteed.
223/// As such, `unsafe` code should not rely on infallibility in general for
224/// soundness.
225///
226/// [book]: ../../book/ch15-02-deref.html
227/// [coercion]: #mutable-deref-coercion
228/// [implementing]: Deref#when-to-implement-deref-or-derefmut
229/// [ref-deref-op]: ../../reference/expressions/operator-expr.html#the-dereference-operator
230/// [method resolution]: ../../reference/expressions/method-call-expr.html
231/// [type coercions]: ../../reference/type-coercions.html
232/// [box]: ../../alloc/boxed/struct.Box.html
233/// [string]: ../../alloc/string/struct.String.html
234/// [rc]: ../../alloc/rc/struct.Rc.html
235/// [cow]: ../../alloc/borrow/enum.Cow.html
236///
237/// # Examples
238///
239/// A struct with a single field which is modifiable by dereferencing the
240/// struct.
241///
242/// ```
243/// use std::ops::{Deref, DerefMut};
244///
245/// struct DerefMutExample<T> {
246///     value: T
247/// }
248///
249/// impl<T> Deref for DerefMutExample<T> {
250///     type Target = T;
251///
252///     fn deref(&self) -> &Self::Target {
253///         &self.value
254///     }
255/// }
256///
257/// impl<T> DerefMut for DerefMutExample<T> {
258///     fn deref_mut(&mut self) -> &mut Self::Target {
259///         &mut self.value
260///     }
261/// }
262///
263/// let mut x = DerefMutExample { value: 'a' };
264/// *x = 'b';
265/// assert_eq!('b', x.value);
266/// ```
267#[lang = "deref_mut"]
268#[doc(alias = "*")]
269#[stable(feature = "rust1", since = "1.0.0")]
270#[const_trait]
271#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
272pub trait DerefMut: ~const Deref + PointeeSized {
273    /// Mutably dereferences the value.
274    #[stable(feature = "rust1", since = "1.0.0")]
275    #[rustc_diagnostic_item = "deref_mut_method"]
276    fn deref_mut(&mut self) -> &mut Self::Target;
277}
278
279#[stable(feature = "rust1", since = "1.0.0")]
280#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
281impl<T: ?Sized> const DerefMut for &mut T {
282    fn deref_mut(&mut self) -> &mut T {
283        *self
284    }
285}
286
287/// Perma-unstable marker trait. Indicates that the type has a well-behaved [`Deref`]
288/// (and, if applicable, [`DerefMut`]) implementation. This is relied on for soundness
289/// of deref patterns.
290///
291/// FIXME(deref_patterns): The precise semantics are undecided; the rough idea is that
292/// successive calls to `deref`/`deref_mut` without intermediate mutation should be
293/// idempotent, in the sense that they return the same value as far as pattern-matching
294/// is concerned. Calls to `deref`/`deref_mut` must leave the pointer itself likewise
295/// unchanged.
296#[unstable(feature = "deref_pure_trait", issue = "87121")]
297#[lang = "deref_pure"]
298pub unsafe trait DerefPure: PointeeSized {}
299
300#[unstable(feature = "deref_pure_trait", issue = "87121")]
301unsafe impl<T: ?Sized> DerefPure for &T {}
302
303#[unstable(feature = "deref_pure_trait", issue = "87121")]
304unsafe impl<T: ?Sized> DerefPure for &mut T {}
305
306/// Indicates that a struct can be used as a method receiver.
307/// That is, a type can use this type as a type of `self`, like this:
308/// ```compile_fail
309/// # // This is currently compile_fail because the compiler-side parts
310/// # // of arbitrary_self_types are not implemented
311/// use std::ops::Receiver;
312///
313/// struct SmartPointer<T>(T);
314///
315/// impl<T> Receiver for SmartPointer<T> {
316///    type Target = T;
317/// }
318///
319/// struct MyContainedType;
320///
321/// impl MyContainedType {
322///   fn method(self: SmartPointer<Self>) {
323///     // ...
324///   }
325/// }
326///
327/// fn main() {
328///   let ptr = SmartPointer(MyContainedType);
329///   ptr.method();
330/// }
331/// ```
332/// This trait is blanket implemented for any type which implements
333/// [`Deref`], which includes stdlib pointer types like `Box<T>`,`Rc<T>`, `&T`,
334/// and `Pin<P>`. For that reason, it's relatively rare to need to
335/// implement this directly. You'll typically do this only if you need
336/// to implement a smart pointer type which can't implement [`Deref`]; perhaps
337/// because you're interfacing with another programming language and can't
338/// guarantee that references comply with Rust's aliasing rules.
339///
340/// When looking for method candidates, Rust will explore a chain of possible
341/// `Receiver`s, so for example each of the following methods work:
342/// ```
343/// use std::boxed::Box;
344/// use std::rc::Rc;
345///
346/// // Both `Box` and `Rc` (indirectly) implement Receiver
347///
348/// struct MyContainedType;
349///
350/// fn main() {
351///   let t = Rc::new(Box::new(MyContainedType));
352///   t.method_a();
353///   t.method_b();
354///   t.method_c();
355/// }
356///
357/// impl MyContainedType {
358///   fn method_a(&self) {
359///
360///   }
361///   fn method_b(self: &Box<Self>) {
362///
363///   }
364///   fn method_c(self: &Rc<Box<Self>>) {
365///
366///   }
367/// }
368/// ```
369#[lang = "receiver"]
370#[unstable(feature = "arbitrary_self_types", issue = "44874")]
371pub trait Receiver: PointeeSized {
372    /// The target type on which the method may be called.
373    #[rustc_diagnostic_item = "receiver_target"]
374    #[lang = "receiver_target"]
375    #[unstable(feature = "arbitrary_self_types", issue = "44874")]
376    type Target: ?Sized;
377}
378
379#[unstable(feature = "arbitrary_self_types", issue = "44874")]
380impl<P: ?Sized, T: ?Sized> Receiver for P
381where
382    P: Deref<Target = T>,
383{
384    type Target = T;
385}
386
387/// Indicates that a struct can be used as a method receiver, without the
388/// `arbitrary_self_types` feature. This is implemented by stdlib pointer types like `Box<T>`,
389/// `Rc<T>`, `&T`, and `Pin<P>`.
390///
391/// This trait will shortly be removed and replaced with a more generic
392/// facility based around the current "arbitrary self types" unstable feature.
393/// That new facility will use the replacement trait above called `Receiver`
394/// which is why this is now named `LegacyReceiver`.
395#[lang = "legacy_receiver"]
396#[unstable(feature = "legacy_receiver_trait", issue = "none")]
397#[doc(hidden)]
398pub trait LegacyReceiver: PointeeSized {
399    // Empty.
400}
401
402#[unstable(feature = "legacy_receiver_trait", issue = "none")]
403impl<T: PointeeSized> LegacyReceiver for &T {}
404
405#[unstable(feature = "legacy_receiver_trait", issue = "none")]
406impl<T: PointeeSized> LegacyReceiver for &mut T {}