311 lines
12 KiB
Rust
311 lines
12 KiB
Rust
/// Used for immutable dereferencing operations, like `*v`.
|
|
///
|
|
/// 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"][coercion]. In mutable contexts, [`DerefMut`] is used and
|
|
/// mutable deref coercion similarly occurs.
|
|
///
|
|
/// **Warning:** Deref coercion is a powerful language feature which has
|
|
/// far-reaching implications for every type that implements `Deref`. The
|
|
/// compiler will silently insert calls to `Deref::deref`. For this reason, one
|
|
/// should be careful about implementing `Deref` and only do so when deref
|
|
/// coercion is desirable. See [below][implementing] for advice on when this is
|
|
/// typically desirable or undesirable.
|
|
///
|
|
/// Types that implement `Deref` or `DerefMut` are often called "smart
|
|
/// pointers" and the mechanism of deref coercion has been specifically designed
|
|
/// to facilitate the pointer-like behaviour that name suggests. Often, the
|
|
/// purpose of a "smart pointer" type is to change the ownership semantics
|
|
/// of a contained value (for example, [`Rc`][rc] or [`Cow`][cow]) or the
|
|
/// storage semantics of a contained value (for example, [`Box`][box]).
|
|
///
|
|
/// # Deref coercion
|
|
///
|
|
/// If `T` implements `Deref<Target = U>`, and `v` is a value of type `T`, then:
|
|
///
|
|
/// * In immutable contexts, `*v` (where `T` is neither a reference nor a raw
|
|
/// pointer) is equivalent to `*Deref::deref(&v)`.
|
|
/// * Values of type `&T` are coerced to values of type `&U`
|
|
/// * `T` implicitly implements all the methods of the type `U` which take the
|
|
/// `&self` receiver.
|
|
///
|
|
/// 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],
|
|
/// [method resolution], and [type coercions].
|
|
///
|
|
/// # When to implement `Deref` or `DerefMut`
|
|
///
|
|
/// The same advice applies to both deref traits. In general, deref traits
|
|
/// **should** be implemented if:
|
|
///
|
|
/// 1. a value of the type transparently behaves like a value of the target
|
|
/// type;
|
|
/// 1. the implementation of the deref function is cheap; and
|
|
/// 1. users of the type will not be surprised by any deref coercion behaviour.
|
|
///
|
|
/// In general, deref traits **should not** be implemented if:
|
|
///
|
|
/// 1. the deref implementations could fail unexpectedly; or
|
|
/// 1. the type has methods that are likely to collide with methods on the
|
|
/// target type; or
|
|
/// 1. committing to deref coercion as part of the public API is not desirable.
|
|
///
|
|
/// Note that there's a large difference between implementing deref traits
|
|
/// generically over many target types, and doing so only for specific target
|
|
/// types.
|
|
///
|
|
/// Generic implementations, such as for [`Box<T>`][box] (which is generic over
|
|
/// every type and dereferences to `T`) should be careful to provide few or no
|
|
/// methods, since the target type is unknown and therefore every method could
|
|
/// collide with one on the target type, causing confusion for users.
|
|
/// `impl<T> Box<T>` has no methods (though several associated functions),
|
|
/// partly for this reason.
|
|
///
|
|
/// Specific implementations, such as for [`String`][string] (whose `Deref`
|
|
/// implementation has `Target = str`) can have many methods, since avoiding
|
|
/// collision is much easier. `String` and `str` both have many methods, and
|
|
/// `String` additionally behaves as if it has every method of `str` because of
|
|
/// deref coercion. The implementing type may also be generic while the
|
|
/// implementation is still specific in this sense; for example, [`Vec<T>`][vec]
|
|
/// dereferences to `[T]`, so methods of `T` are not applicable.
|
|
///
|
|
/// Consider also that deref coercion means that deref traits are a much larger
|
|
/// part of a type's public API than any other trait as it is implicitly called
|
|
/// by the compiler. Therefore, it is advisable to consider whether this is
|
|
/// something you are comfortable supporting as a public API.
|
|
///
|
|
/// The [`AsRef`] and [`Borrow`][core::borrow::Borrow] traits have very similar
|
|
/// signatures to `Deref`. It may be desirable to implement either or both of
|
|
/// these, whether in addition to or rather than deref traits. See their
|
|
/// documentation for details.
|
|
///
|
|
/// # Fallibility
|
|
///
|
|
/// **This trait's method should never unexpectedly fail**. Deref coercion means
|
|
/// the compiler will often insert calls to `Deref::deref` implicitly. Failure
|
|
/// during dereferencing can be extremely confusing when `Deref` is invoked
|
|
/// implicitly. In the majority of uses it should be infallible, though it may
|
|
/// be acceptable to panic if the type is misused through programmer error, for
|
|
/// example.
|
|
///
|
|
/// However, infallibility is not enforced and therefore not guaranteed.
|
|
/// As such, `unsafe` code should not rely on infallibility in general for
|
|
/// soundness.
|
|
///
|
|
/// [book]: ../../book/ch15-02-deref.html
|
|
/// [coercion]: #deref-coercion
|
|
/// [implementing]: #when-to-implement-deref-or-derefmut
|
|
/// [ref-deref-op]: ../../reference/expressions/operator-expr.html#the-dereference-operator
|
|
/// [method resolution]: ../../reference/expressions/method-call-expr.html
|
|
/// [type coercions]: ../../reference/type-coercions.html
|
|
/// [box]: ../../alloc/boxed/struct.Box.html
|
|
/// [string]: ../../alloc/string/struct.String.html
|
|
/// [vec]: ../../alloc/vec/struct.Vec.html
|
|
/// [rc]: ../../alloc/rc/struct.Rc.html
|
|
/// [cow]: ../../alloc/borrow/enum.Cow.html
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// A struct with a single field which is accessible by dereferencing the
|
|
/// struct.
|
|
///
|
|
/// ```
|
|
/// use std::ops::Deref;
|
|
///
|
|
/// struct DerefExample<T> {
|
|
/// value: T
|
|
/// }
|
|
///
|
|
/// impl<T> Deref for DerefExample<T> {
|
|
/// type Target = T;
|
|
///
|
|
/// fn deref(&self) -> &Self::Target {
|
|
/// &self.value
|
|
/// }
|
|
/// }
|
|
///
|
|
/// let x = DerefExample { value: 'a' };
|
|
/// assert_eq!('a', *x);
|
|
/// ```
|
|
#[lang = "deref"]
|
|
#[doc(alias = "*")]
|
|
#[doc(alias = "&*")]
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
#[rustc_diagnostic_item = "Deref"]
|
|
pub trait Deref {
|
|
/// The resulting type after dereferencing.
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
#[rustc_diagnostic_item = "deref_target"]
|
|
#[lang = "deref_target"]
|
|
type Target: ?Sized;
|
|
|
|
/// Dereferences the value.
|
|
#[must_use]
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
#[rustc_diagnostic_item = "deref_method"]
|
|
fn deref(&self) -> &Self::Target;
|
|
}
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
impl<T: ?Sized> Deref for &T {
|
|
type Target = T;
|
|
|
|
#[rustc_diagnostic_item = "noop_method_deref"]
|
|
fn deref(&self) -> &T {
|
|
*self
|
|
}
|
|
}
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
impl<T: ?Sized> !DerefMut for &T {}
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
impl<T: ?Sized> Deref for &mut T {
|
|
type Target = T;
|
|
|
|
fn deref(&self) -> &T {
|
|
*self
|
|
}
|
|
}
|
|
|
|
/// 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
|
|
/// ["mutable deref coercion"][coercion]. In immutable contexts, [`Deref`] is used.
|
|
///
|
|
/// **Warning:** Deref coercion is a powerful language feature which has
|
|
/// far-reaching implications for every type that implements `DerefMut`. The
|
|
/// compiler will silently insert calls to `DerefMut::deref_mut`. For this
|
|
/// reason, one should be careful about implementing `DerefMut` and only do so
|
|
/// when mutable deref coercion is desirable. See [the `Deref` docs][implementing]
|
|
/// for advice on when this is typically desirable or undesirable.
|
|
///
|
|
/// Types that implement `DerefMut` or `Deref` are often called "smart
|
|
/// pointers" and the mechanism of deref coercion has been specifically designed
|
|
/// to facilitate the pointer-like behaviour that name suggests. Often, the
|
|
/// purpose of a "smart pointer" type is to change the ownership semantics
|
|
/// of a contained value (for example, [`Rc`][rc] or [`Cow`][cow]) or the
|
|
/// storage semantics of a contained value (for example, [`Box`][box]).
|
|
///
|
|
/// # Mutable deref coercion
|
|
///
|
|
/// If `T` implements `DerefMut<Target = U>`, and `v` is a value of type `T`,
|
|
/// then:
|
|
///
|
|
/// * In mutable contexts, `*v` (where `T` is neither a reference nor a raw pointer)
|
|
/// is equivalent to `*DerefMut::deref_mut(&mut v)`.
|
|
/// * 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],
|
|
/// [method resolution] and [type coercions].
|
|
///
|
|
/// # Fallibility
|
|
///
|
|
/// **This trait's method should never unexpectedly fail**. Deref coercion means
|
|
/// the compiler will often insert calls to `DerefMut::deref_mut` implicitly.
|
|
/// Failure during dereferencing can be extremely confusing when `DerefMut` is
|
|
/// invoked implicitly. In the majority of uses it should be infallible, though
|
|
/// it may be acceptable to panic if the type is misused through programmer
|
|
/// error, for example.
|
|
///
|
|
/// However, infallibility is not enforced and therefore not guaranteed.
|
|
/// As such, `unsafe` code should not rely on infallibility in general for
|
|
/// soundness.
|
|
///
|
|
/// [book]: ../../book/ch15-02-deref.html
|
|
/// [coercion]: #mutable-deref-coercion
|
|
/// [implementing]: Deref#when-to-implement-deref-or-derefmut
|
|
/// [ref-deref-op]: ../../reference/expressions/operator-expr.html#the-dereference-operator
|
|
/// [method resolution]: ../../reference/expressions/method-call-expr.html
|
|
/// [type coercions]: ../../reference/type-coercions.html
|
|
/// [box]: ../../alloc/boxed/struct.Box.html
|
|
/// [string]: ../../alloc/string/struct.String.html
|
|
/// [rc]: ../../alloc/rc/struct.Rc.html
|
|
/// [cow]: ../../alloc/borrow/enum.Cow.html
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// A struct with a single field which is modifiable by dereferencing the
|
|
/// struct.
|
|
///
|
|
/// ```
|
|
/// use std::ops::{Deref, DerefMut};
|
|
///
|
|
/// struct DerefMutExample<T> {
|
|
/// value: T
|
|
/// }
|
|
///
|
|
/// impl<T> Deref for DerefMutExample<T> {
|
|
/// type Target = T;
|
|
///
|
|
/// fn deref(&self) -> &Self::Target {
|
|
/// &self.value
|
|
/// }
|
|
/// }
|
|
///
|
|
/// impl<T> DerefMut for DerefMutExample<T> {
|
|
/// fn deref_mut(&mut self) -> &mut Self::Target {
|
|
/// &mut self.value
|
|
/// }
|
|
/// }
|
|
///
|
|
/// let mut x = DerefMutExample { value: 'a' };
|
|
/// *x = 'b';
|
|
/// assert_eq!('b', x.value);
|
|
/// ```
|
|
#[lang = "deref_mut"]
|
|
#[doc(alias = "*")]
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
pub trait DerefMut: Deref {
|
|
/// Mutably dereferences the value.
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
#[rustc_diagnostic_item = "deref_mut_method"]
|
|
fn deref_mut(&mut self) -> &mut Self::Target;
|
|
}
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
impl<T: ?Sized> DerefMut for &mut T {
|
|
fn deref_mut(&mut self) -> &mut T {
|
|
*self
|
|
}
|
|
}
|
|
|
|
/// Perma-unstable marker trait. Indicates that the type has a well-behaved [`Deref`]
|
|
/// (and, if applicable, [`DerefMut`]) implementation. This is relied on for soundness
|
|
/// of deref patterns.
|
|
///
|
|
/// FIXME(deref_patterns): The precise semantics are undecided; the rough idea is that
|
|
/// successive calls to `deref`/`deref_mut` without intermediate mutation should be
|
|
/// idempotent, in the sense that they return the same value as far as pattern-matching
|
|
/// is concerned. Calls to `deref`/`deref_mut`` must leave the pointer itself likewise
|
|
/// unchanged.
|
|
#[unstable(feature = "deref_pure_trait", issue = "87121")]
|
|
#[cfg_attr(not(bootstrap), lang = "deref_pure")]
|
|
pub unsafe trait DerefPure {}
|
|
|
|
#[unstable(feature = "deref_pure_trait", issue = "87121")]
|
|
unsafe impl<T: ?Sized> DerefPure for &T {}
|
|
|
|
#[unstable(feature = "deref_pure_trait", issue = "87121")]
|
|
unsafe impl<T: ?Sized> DerefPure for &mut T {}
|
|
|
|
/// Indicates that a struct can be used as a method receiver, without the
|
|
/// `arbitrary_self_types` feature. This is implemented by stdlib pointer types like `Box<T>`,
|
|
/// `Rc<T>`, `&T`, and `Pin<P>`.
|
|
#[lang = "receiver"]
|
|
#[unstable(feature = "receiver_trait", issue = "none")]
|
|
#[doc(hidden)]
|
|
pub trait Receiver {
|
|
// Empty.
|
|
}
|
|
|
|
#[unstable(feature = "receiver_trait", issue = "none")]
|
|
impl<T: ?Sized> Receiver for &T {}
|
|
|
|
#[unstable(feature = "receiver_trait", issue = "none")]
|
|
impl<T: ?Sized> Receiver for &mut T {}
|