1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Overloadable operators.
13 //! Implementing these traits allows you to overload certain operators.
15 //! Some of these traits are imported by the prelude, so they are available in
16 //! every Rust program. Only operators backed by traits can be overloaded. For
17 //! example, the addition operator (`+`) can be overloaded through the [`Add`]
18 //! trait, but since the assignment operator (`=`) has no backing trait, there
19 //! is no way of overloading its semantics. Additionally, this module does not
20 //! provide any mechanism to create new operators. If traitless overloading or
21 //! custom operators are required, you should look toward macros or compiler
22 //! plugins to extend Rust's syntax.
24 //! Note that the `&&` and `||` operators short-circuit, i.e. they only
25 //! evaluate their second operand if it contributes to the result. Since this
26 //! behavior is not enforceable by traits, `&&` and `||` are not supported as
27 //! overloadable operators.
29 //! Many of the operators take their operands by value. In non-generic
30 //! contexts involving built-in types, this is usually not a problem.
31 //! However, using these operators in generic code, requires some
32 //! attention if values have to be reused as opposed to letting the operators
33 //! consume them. One option is to occasionally use [`clone`].
34 //! Another option is to rely on the types involved providing additional
35 //! operator implementations for references. For example, for a user-defined
36 //! type `T` which is supposed to support addition, it is probably a good
37 //! idea to have both `T` and `&T` implement the traits [`Add<T>`][`Add`] and
38 //! [`Add<&T>`][`Add`] so that generic code can be written without unnecessary
43 //! This example creates a `Point` struct that implements [`Add`] and [`Sub`],
44 //! and then demonstrates adding and subtracting two `Point`s.
47 //! use std::ops::{Add, Sub};
55 //! impl Add for Point {
56 //! type Output = Point;
58 //! fn add(self, other: Point) -> Point {
59 //! Point {x: self.x + other.x, y: self.y + other.y}
63 //! impl Sub for Point {
64 //! type Output = Point;
66 //! fn sub(self, other: Point) -> Point {
67 //! Point {x: self.x - other.x, y: self.y - other.y}
71 //! println!("{:?}", Point {x: 1, y: 0} + Point {x: 2, y: 3});
72 //! println!("{:?}", Point {x: 1, y: 0} - Point {x: 2, y: 3});
76 //! See the documentation for each trait for an example implementation.
78 //! The [`Fn`], [`FnMut`], and [`FnOnce`] traits are implemented by types that can be
79 //! invoked like functions. Note that [`Fn`] takes `&self`, [`FnMut`] takes `&mut
80 //! self` and [`FnOnce`] takes `self`. These correspond to the three kinds of
81 //! methods that can be invoked on an instance: call-by-reference,
82 //! call-by-mutable-reference, and call-by-value. The most common use of these
83 //! traits is to act as bounds to higher-level functions that take functions or
84 //! closures as arguments.
86 //! Taking a [`Fn`] as a parameter:
89 //! fn call_with_one<F>(func: F) -> usize
90 //! where F: Fn(usize) -> usize
95 //! let double = |x| x * 2;
96 //! assert_eq!(call_with_one(double), 2);
99 //! Taking a [`FnMut`] as a parameter:
102 //! fn do_twice<F>(mut func: F)
109 //! let mut x: usize = 1;
111 //! let add_two_to_x = || x += 2;
112 //! do_twice(add_two_to_x);
115 //! assert_eq!(x, 5);
118 //! Taking a [`FnOnce`] as a parameter:
121 //! fn consume_with_relish<F>(func: F)
122 //! where F: FnOnce() -> String
124 //! // `func` consumes its captured variables, so it cannot be run more
126 //! println!("Consumed: {}", func());
128 //! println!("Delicious!");
130 //! // Attempting to invoke `func()` again will throw a `use of moved
131 //! // value` error for `func`
134 //! let x = String::from("x");
135 //! let consume_and_return_x = move || x;
136 //! consume_with_relish(consume_and_return_x);
138 //! // `consume_and_return_x` can no longer be invoked at this point
141 //! [`Fn`]: trait.Fn.html
142 //! [`FnMut`]: trait.FnMut.html
143 //! [`FnOnce`]: trait.FnOnce.html
144 //! [`Add`]: trait.Add.html
145 //! [`Sub`]: trait.Sub.html
146 //! [`clone`]: ../clone/trait.Clone.html#tymethod.clone
148 #![stable(feature = "rust1", since = "1.0.0")]
159 #[stable(feature = "rust1", since = "1.0.0")]
160 pub use self::arith::{Add, Sub, Mul, Div, Rem, Neg};
161 #[stable(feature = "op_assign_traits", since = "1.8.0")]
162 pub use self::arith::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
164 #[stable(feature = "rust1", since = "1.0.0")]
165 pub use self::bit::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
166 #[stable(feature = "op_assign_traits", since = "1.8.0")]
167 pub use self::bit::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign};
169 #[stable(feature = "rust1", since = "1.0.0")]
170 pub use self::deref::{Deref, DerefMut};
172 #[stable(feature = "rust1", since = "1.0.0")]
173 pub use self::function::{Fn, FnMut, FnOnce};
175 #[stable(feature = "rust1", since = "1.0.0")]
176 pub use self::index::{Index, IndexMut};
178 #[stable(feature = "rust1", since = "1.0.0")]
179 pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
181 #[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
182 pub use self::range::{RangeInclusive, RangeToInclusive};
184 #[unstable(feature = "question_mark_carrier", issue = "31436")]
186 pub use self::try::Carrier;
187 #[unstable(feature = "try_trait", issue = "42327")]
188 pub use self::try::Try;
190 #[unstable(feature = "placement_new_protocol", issue = "27779")]
191 pub use self::place::{Place, Placer, InPlace, Boxed, BoxPlace};
195 /// The `Drop` trait is used to run some code when a value goes out of scope.
196 /// This is sometimes called a 'destructor'.
198 /// When a value goes out of scope, if it implements this trait, it will have
199 /// its `drop` method called. Then any fields the value contains will also
200 /// be dropped recursively.
202 /// Because of the recursive dropping, you do not need to implement this trait
203 /// unless your type needs its own destructor logic.
207 /// A trivial implementation of `Drop`. The `drop` method is called when `_x`
208 /// goes out of scope, and therefore `main` prints `Dropping!`.
213 /// impl Drop for HasDrop {
214 /// fn drop(&mut self) {
215 /// println!("Dropping!");
220 /// let _x = HasDrop;
224 /// Showing the recursive nature of `Drop`. When `outer` goes out of scope, the
225 /// `drop` method will be called first for `Outer`, then for `Inner`. Therefore
226 /// `main` prints `Dropping Outer!` and then `Dropping Inner!`.
230 /// struct Outer(Inner);
232 /// impl Drop for Inner {
233 /// fn drop(&mut self) {
234 /// println!("Dropping Inner!");
238 /// impl Drop for Outer {
239 /// fn drop(&mut self) {
240 /// println!("Dropping Outer!");
245 /// let _x = Outer(Inner);
249 /// Because variables are dropped in the reverse order they are declared,
250 /// `main` will print `Declared second!` and then `Declared first!`.
253 /// struct PrintOnDrop(&'static str);
256 /// let _first = PrintOnDrop("Declared first!");
257 /// let _second = PrintOnDrop("Declared second!");
261 #[stable(feature = "rust1", since = "1.0.0")]
263 /// A method called when the value goes out of scope.
265 /// When this method has been called, `self` has not yet been deallocated.
266 /// If it were, `self` would be a dangling reference.
268 /// After this function is over, the memory of `self` will be deallocated.
270 /// This function cannot be called explicitly. This is compiler error
271 /// [E0040]. However, the [`std::mem::drop`] function in the prelude can be
272 /// used to call the argument's `Drop` implementation.
274 /// [E0040]: ../../error-index.html#E0040
275 /// [`std::mem::drop`]: ../../std/mem/fn.drop.html
279 /// Given that a `panic!` will call `drop()` as it unwinds, any `panic!` in
280 /// a `drop()` implementation will likely abort.
281 #[stable(feature = "rust1", since = "1.0.0")]
285 /// Trait that indicates that this is a pointer or a wrapper for one,
286 /// where unsizing can be performed on the pointee.
288 /// See the [DST coercion RfC][dst-coerce] and [the nomicon entry on coercion][nomicon-coerce]
289 /// for more details.
291 /// For builtin pointer types, pointers to `T` will coerce to pointers to `U` if `T: Unsize<U>`
292 /// by converting from a thin pointer to a fat pointer.
294 /// For custom types, the coercion here works by coercing `Foo<T>` to `Foo<U>`
295 /// provided an impl of `CoerceUnsized<Foo<U>> for Foo<T>` exists.
296 /// Such an impl can only be written if `Foo<T>` has only a single non-phantomdata
297 /// field involving `T`. If the type of that field is `Bar<T>`, an implementation
298 /// of `CoerceUnsized<Bar<U>> for Bar<T>` must exist. The coercion will work by
299 /// by coercing the `Bar<T>` field into `Bar<U>` and filling in the rest of the fields
300 /// from `Foo<T>` to create a `Foo<U>`. This will effectively drill down to a pointer
301 /// field and coerce that.
303 /// Generally, for smart pointers you will implement
304 /// `CoerceUnsized<Ptr<U>> for Ptr<T> where T: Unsize<U>, U: ?Sized`, with an
305 /// optional `?Sized` bound on `T` itself. For wrapper types that directly embed `T`
306 /// like `Cell<T>` and `RefCell<T>`, you
307 /// can directly implement `CoerceUnsized<Wrap<U>> for Wrap<T> where T: CoerceUnsized<U>`.
308 /// This will let coercions of types like `Cell<Box<T>>` work.
310 /// [`Unsize`][unsize] is used to mark types which can be coerced to DSTs if behind
311 /// pointers. It is implemented automatically by the compiler.
313 /// [dst-coerce]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
314 /// [unsize]: ../marker/trait.Unsize.html
315 /// [nomicon-coerce]: ../../nomicon/coercions.html
316 #[unstable(feature = "coerce_unsized", issue = "27732")]
317 #[lang="coerce_unsized"]
318 pub trait CoerceUnsized<T> {
323 #[unstable(feature = "coerce_unsized", issue = "27732")]
324 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
326 #[unstable(feature = "coerce_unsized", issue = "27732")]
327 impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
329 #[unstable(feature = "coerce_unsized", issue = "27732")]
330 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
331 // &mut T -> *const U
332 #[unstable(feature = "coerce_unsized", issue = "27732")]
333 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
336 #[unstable(feature = "coerce_unsized", issue = "27732")]
337 impl<'a, 'b: 'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
339 #[unstable(feature = "coerce_unsized", issue = "27732")]
340 impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
343 #[unstable(feature = "coerce_unsized", issue = "27732")]
344 impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
345 // *mut T -> *const U
346 #[unstable(feature = "coerce_unsized", issue = "27732")]
347 impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
349 // *const T -> *const U
350 #[unstable(feature = "coerce_unsized", issue = "27732")]
351 impl<T: ?Sized+Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}