mod.rs - source
Description: Source of the Rust file `library/core/src/ops/mod.rs`.

#
core/ops/
mod.rs

    1//! Overloadable operators.
    2//!
    3//! Implementing these traits allows you to overload certain operators.
    4//!
    5//! Some of these traits are imported by the prelude, so they are available in
    6//! every Rust program. Only operators backed by traits can be overloaded. For
    7//! example, the addition operator (`+`) can be overloaded through the [`Add`]
    8//! trait, but since the assignment operator (`=`) has no backing trait, there
    9//! is no way of overloading its semantics. Additionally, this module does not
    10//! provide any mechanism to create new operators. If traitless overloading or
    11//! custom operators are required, you should look toward macros to extend
    12//! Rust's syntax.
    13//!
    14//! Implementations of operator traits should be unsurprising in their
    15//! respective contexts, keeping in mind their usual meanings and
    16//! [operator precedence]. For example, when implementing [`Mul`], the operation
    17//! should have some resemblance to multiplication (and share expected
    18//! properties like associativity).
    19//!
    20//! Note that the `&&` and `||` operators are currently not supported for
    21//! overloading. Due to their short circuiting nature, they require a different
    22//! design from traits for other operators like [`BitAnd`]. Designs for them are
    23//! under discussion.
    24//!
    25//! Many of the operators take their operands by value. In non-generic
    26//! contexts involving built-in types, this is usually not a problem.
    27//! However, using these operators in generic code, requires some
    28//! attention if values have to be reused as opposed to letting the operators
    29//! consume them. One option is to occasionally use [`clone`].
    30//! Another option is to rely on the types involved providing additional
    31//! operator implementations for references. For example, for a user-defined
    32//! type `T` which is supposed to support addition, it is probably a good
    33//! idea to have both `T` and `&T` implement the traits [`Add<T>`][`Add`] and
    34//! [`Add<&T>`][`Add`] so that generic code can be written without unnecessary
    35//! cloning.
    36//!
    37//! # Examples
    38//!
    39//! This example creates a `Point` struct that implements [`Add`] and [`Sub`],
    40//! and then demonstrates adding and subtracting two `Point`s.
    41//!
    42//! ```rust
    43//! use std::ops::{Add, Sub};
    44//!
    45//! #[derive(Debug, Copy, Clone, PartialEq)]
    46//! struct Point {
    47//!     x: i32,
    48//!     y: i32,
    49//! }
    50//!
    51//! impl Add for Point {
    52//!     type Output = Self;
    53//!
    54//!     fn add(self, other: Self) -> Self {
    55//!         Self {x: self.x + other.x, y: self.y + other.y}
    56//!     }
    57//! }
    58//!
    59//! impl Sub for Point {
    60//!     type Output = Self;
    61//!
    62//!     fn sub(self, other: Self) -> Self {
    63//!         Self {x: self.x - other.x, y: self.y - other.y}
    64//!     }
    65//! }
    66//!
    67//! assert_eq!(Point {x: 3, y: 3}, Point {x: 1, y: 0} + Point {x: 2, y: 3});
    68//! assert_eq!(Point {x: -1, y: -3}, Point {x: 1, y: 0} - Point {x: 2, y: 3});
    69//! ```
    70//!
    71//! See the documentation for each trait for an example implementation.
    72//!
    73//! The [`Fn`], [`FnMut`], and [`FnOnce`] traits are implemented by types that can be
    74//! invoked like functions. Note that [`Fn`] takes `&self`, [`FnMut`] takes `&mut
    75//! self` and [`FnOnce`] takes `self`. These correspond to the three kinds of
    76//! methods that can be invoked on an instance: call-by-reference,
    77//! call-by-mutable-reference, and call-by-value. The most common use of these
    78//! traits is to act as bounds to higher-level functions that take functions or
    79//! closures as arguments.
    80//!
    81//! Taking a [`Fn`] as a parameter:
    82//!
    83//! ```rust
    84//! fn call_with_one<F>(func: F) -> usize
    85//!     where F: Fn(usize) -> usize
    86//! {
    87//!     func(1)
    88//! }
    89//!
    90//! let double = |x| x * 2;
    91//! assert_eq!(call_with_one(double), 2);
    92//! ```
    93//!
    94//! Taking a [`FnMut`] as a parameter:
    95//!
    96//! ```rust
    97//! fn do_twice<F>(mut func: F)
    98//!     where F: FnMut()
    99//! {
    100//!     func();
    101//!     func();
    102//! }
    103//!
    104//! let mut x: usize = 1;
    105//! {
    106//!     let add_two_to_x = || x += 2;
    107//!     do_twice(add_two_to_x);
    108//! }
    109//!
    110//! assert_eq!(x, 5);
    111//! ```
    112//!
    113//! Taking a [`FnOnce`] as a parameter:
    114//!
    115//! ```rust
    116//! fn consume_with_relish<F>(func: F)
    117//!     where F: FnOnce() -> String
    118//! {
    119//!     // `func` consumes its captured variables, so it cannot be run more
    120//!     // than once
    121//!     println!("Consumed: {}", func());
    122//!
    123//!     println!("Delicious!");
    124//!
    125//!     // Attempting to invoke `func()` again will throw a `use of moved
    126//!     // value` error for `func`
    127//! }
    128//!
    129//! let x = String::from("x");
    130//! let consume_and_return_x = move || x;
    131//! consume_with_relish(consume_and_return_x);
    132//!
    133//! // `consume_and_return_x` can no longer be invoked at this point
    134//! ```
    135//!
    136//! [`clone`]: Clone::clone
    137//! [operator precedence]: ../../reference/expressions.html#expression-precedence
    138
    139#![stable(feature = "rust1", since = "1.0.0")]
    140
    141mod arith;
    142mod async_function;
    143mod bit;
    144mod control_flow;
    145mod coroutine;
    146mod deref;
    147mod drop;
    148mod function;
    149mod index;
    150mod index_range;
    151mod range;
    152mod reborrow;
    153mod try_trait;
    154mod unsize;
    155
    156#[stable(feature = "rust1", since = "1.0.0")]
    157pub use self::arith::{Add, Div, Mul, Neg, Rem, Sub};
    158#[stable(feature = "op_assign_traits", since = "1.8.0")]
    159pub use self::arith::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
    160#[unstable(feature = "async_fn_traits", issue = "none")]
    161pub use self::async_function::{AsyncFn, AsyncFnMut, AsyncFnOnce};
    162#[stable(feature = "rust1", since = "1.0.0")]
    163pub use self::bit::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
    164#[stable(feature = "op_assign_traits", since = "1.8.0")]
    165pub use self::bit::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign};
    166#[stable(feature = "control_flow_enum_type", since = "1.55.0")]
    167pub use self::control_flow::ControlFlow;
    168#[unstable(feature = "coroutine_trait", issue = "43122")]
    169pub use self::coroutine::{Coroutine, CoroutineState};
    170#[unstable(feature = "deref_pure_trait", issue = "87121")]
    171pub use self::deref::DerefPure;
    172#[unstable(feature = "legacy_receiver_trait", issue = "none")]
    173pub use self::deref::LegacyReceiver;
    174#[unstable(feature = "arbitrary_self_types", issue = "44874")]
    175pub use self::deref::Receiver;
    176#[stable(feature = "rust1", since = "1.0.0")]
    177pub use self::deref::{Deref, DerefMut};
    178#[stable(feature = "rust1", since = "1.0.0")]
    179pub use self::drop::Drop;
    180#[stable(feature = "rust1", since = "1.0.0")]
    181pub use self::function::{Fn, FnMut, FnOnce};
    182#[stable(feature = "rust1", since = "1.0.0")]
    183pub use self::index::{Index, IndexMut};
    184pub(crate) use self::index_range::IndexRange;
    185#[unstable(feature = "range_into_bounds", issue = "136903")]
    186pub use self::range::IntoBounds;
    187#[stable(feature = "inclusive_range", since = "1.26.0")]
    188pub use self::range::{Bound, RangeBounds, RangeInclusive, RangeToInclusive};
    189#[unstable(feature = "one_sided_range", issue = "69780")]
    190pub use self::range::{OneSidedRange, OneSidedRangeBound};
    191#[stable(feature = "rust1", since = "1.0.0")]
    192pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
    193#[unstable(feature = "reborrow", issue = "145612")]
    194pub use self::reborrow::{CoerceShared, Reborrow};
    195#[unstable(feature = "try_trait_v2_residual", issue = "91285")]
    196pub use self::try_trait::Residual;
    197#[unstable(feature = "try_trait_v2_yeet", issue = "96374")]
    198pub use self::try_trait::Yeet;
    199pub(crate) use self::try_trait::{ChangeOutputType, NeverShortCircuit};
    200#[unstable(feature = "try_trait_v2", issue = "84277", old_name = "try_trait")]
    201pub use self::try_trait::{FromResidual, Try};
    202#[unstable(feature = "coerce_unsized", issue = "18598")]
    203pub use self::unsize::CoerceUnsized;
    204#[unstable(feature = "dispatch_from_dyn", issue = "none")]
    205pub use self::unsize::DispatchFromDyn;