core/ops/
arith.rs

1/// The addition operator `+`.
2///
3/// Note that `Rhs` is `Self` by default, but this is not mandatory. For
4/// example, [`std::time::SystemTime`] implements `Add<Duration>`, which permits
5/// operations of the form `SystemTime = SystemTime + Duration`.
6///
7/// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
8///
9/// # Examples
10///
11/// ## `Add`able points
12///
13/// ```
14/// use std::ops::Add;
15///
16/// #[derive(Debug, Copy, Clone, PartialEq)]
17/// struct Point {
18///     x: i32,
19///     y: i32,
20/// }
21///
22/// impl Add for Point {
23///     type Output = Self;
24///
25///     fn add(self, other: Self) -> Self {
26///         Self {
27///             x: self.x + other.x,
28///             y: self.y + other.y,
29///         }
30///     }
31/// }
32///
33/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
34///            Point { x: 3, y: 3 });
35/// ```
36///
37/// ## Implementing `Add` with generics
38///
39/// Here is an example of the same `Point` struct implementing the `Add` trait
40/// using generics.
41///
42/// ```
43/// use std::ops::Add;
44///
45/// #[derive(Debug, Copy, Clone, PartialEq)]
46/// struct Point<T> {
47///     x: T,
48///     y: T,
49/// }
50///
51/// // Notice that the implementation uses the associated type `Output`.
52/// impl<T: Add<Output = T>> Add for Point<T> {
53///     type Output = Self;
54///
55///     fn add(self, other: Self) -> Self::Output {
56///         Self {
57///             x: self.x + other.x,
58///             y: self.y + other.y,
59///         }
60///     }
61/// }
62///
63/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
64///            Point { x: 3, y: 3 });
65/// ```
66#[lang = "add"]
67#[stable(feature = "rust1", since = "1.0.0")]
68#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
69#[rustc_on_unimplemented(
70    on(all(Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",),
71    on(all(Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",),
72    message = "cannot add `{Rhs}` to `{Self}`",
73    label = "no implementation for `{Self} + {Rhs}`",
74    append_const_msg
75)]
76#[doc(alias = "+")]
77#[const_trait]
78pub trait Add<Rhs = Self> {
79    /// The resulting type after applying the `+` operator.
80    #[stable(feature = "rust1", since = "1.0.0")]
81    type Output;
82
83    /// Performs the `+` operation.
84    ///
85    /// # Example
86    ///
87    /// ```
88    /// assert_eq!(12 + 1, 13);
89    /// ```
90    #[must_use = "this returns the result of the operation, without modifying the original"]
91    #[rustc_diagnostic_item = "add"]
92    #[stable(feature = "rust1", since = "1.0.0")]
93    fn add(self, rhs: Rhs) -> Self::Output;
94}
95
96macro_rules! add_impl {
97    ($($t:ty)*) => ($(
98        #[stable(feature = "rust1", since = "1.0.0")]
99        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
100        impl const Add for $t {
101            type Output = $t;
102
103            #[inline]
104            #[track_caller]
105            #[rustc_inherit_overflow_checks]
106            fn add(self, other: $t) -> $t { self + other }
107        }
108
109        forward_ref_binop! { impl Add, add for $t, $t }
110    )*)
111}
112
113add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
114
115/// The subtraction operator `-`.
116///
117/// Note that `Rhs` is `Self` by default, but this is not mandatory. For
118/// example, [`std::time::SystemTime`] implements `Sub<Duration>`, which permits
119/// operations of the form `SystemTime = SystemTime - Duration`.
120///
121/// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
122///
123/// # Examples
124///
125/// ## `Sub`tractable points
126///
127/// ```
128/// use std::ops::Sub;
129///
130/// #[derive(Debug, Copy, Clone, PartialEq)]
131/// struct Point {
132///     x: i32,
133///     y: i32,
134/// }
135///
136/// impl Sub for Point {
137///     type Output = Self;
138///
139///     fn sub(self, other: Self) -> Self::Output {
140///         Self {
141///             x: self.x - other.x,
142///             y: self.y - other.y,
143///         }
144///     }
145/// }
146///
147/// assert_eq!(Point { x: 3, y: 3 } - Point { x: 2, y: 3 },
148///            Point { x: 1, y: 0 });
149/// ```
150///
151/// ## Implementing `Sub` with generics
152///
153/// Here is an example of the same `Point` struct implementing the `Sub` trait
154/// using generics.
155///
156/// ```
157/// use std::ops::Sub;
158///
159/// #[derive(Debug, PartialEq)]
160/// struct Point<T> {
161///     x: T,
162///     y: T,
163/// }
164///
165/// // Notice that the implementation uses the associated type `Output`.
166/// impl<T: Sub<Output = T>> Sub for Point<T> {
167///     type Output = Self;
168///
169///     fn sub(self, other: Self) -> Self::Output {
170///         Point {
171///             x: self.x - other.x,
172///             y: self.y - other.y,
173///         }
174///     }
175/// }
176///
177/// assert_eq!(Point { x: 2, y: 3 } - Point { x: 1, y: 0 },
178///            Point { x: 1, y: 3 });
179/// ```
180#[lang = "sub"]
181#[stable(feature = "rust1", since = "1.0.0")]
182#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
183#[rustc_on_unimplemented(
184    message = "cannot subtract `{Rhs}` from `{Self}`",
185    label = "no implementation for `{Self} - {Rhs}`",
186    append_const_msg
187)]
188#[doc(alias = "-")]
189#[const_trait]
190pub trait Sub<Rhs = Self> {
191    /// The resulting type after applying the `-` operator.
192    #[stable(feature = "rust1", since = "1.0.0")]
193    type Output;
194
195    /// Performs the `-` operation.
196    ///
197    /// # Example
198    ///
199    /// ```
200    /// assert_eq!(12 - 1, 11);
201    /// ```
202    #[must_use = "this returns the result of the operation, without modifying the original"]
203    #[rustc_diagnostic_item = "sub"]
204    #[stable(feature = "rust1", since = "1.0.0")]
205    fn sub(self, rhs: Rhs) -> Self::Output;
206}
207
208macro_rules! sub_impl {
209    ($($t:ty)*) => ($(
210        #[stable(feature = "rust1", since = "1.0.0")]
211        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
212        impl const Sub for $t {
213            type Output = $t;
214
215            #[inline]
216            #[track_caller]
217            #[rustc_inherit_overflow_checks]
218            fn sub(self, other: $t) -> $t { self - other }
219        }
220
221        forward_ref_binop! { impl Sub, sub for $t, $t }
222    )*)
223}
224
225sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
226
227/// The multiplication operator `*`.
228///
229/// Note that `Rhs` is `Self` by default, but this is not mandatory.
230///
231/// # Examples
232///
233/// ## `Mul`tipliable rational numbers
234///
235/// ```
236/// use std::ops::Mul;
237///
238/// // By the fundamental theorem of arithmetic, rational numbers in lowest
239/// // terms are unique. So, by keeping `Rational`s in reduced form, we can
240/// // derive `Eq` and `PartialEq`.
241/// #[derive(Debug, Eq, PartialEq)]
242/// struct Rational {
243///     numerator: usize,
244///     denominator: usize,
245/// }
246///
247/// impl Rational {
248///     fn new(numerator: usize, denominator: usize) -> Self {
249///         if denominator == 0 {
250///             panic!("Zero is an invalid denominator!");
251///         }
252///
253///         // Reduce to lowest terms by dividing by the greatest common
254///         // divisor.
255///         let gcd = gcd(numerator, denominator);
256///         Self {
257///             numerator: numerator / gcd,
258///             denominator: denominator / gcd,
259///         }
260///     }
261/// }
262///
263/// impl Mul for Rational {
264///     // The multiplication of rational numbers is a closed operation.
265///     type Output = Self;
266///
267///     fn mul(self, rhs: Self) -> Self {
268///         let numerator = self.numerator * rhs.numerator;
269///         let denominator = self.denominator * rhs.denominator;
270///         Self::new(numerator, denominator)
271///     }
272/// }
273///
274/// // Euclid's two-thousand-year-old algorithm for finding the greatest common
275/// // divisor.
276/// fn gcd(x: usize, y: usize) -> usize {
277///     let mut x = x;
278///     let mut y = y;
279///     while y != 0 {
280///         let t = y;
281///         y = x % y;
282///         x = t;
283///     }
284///     x
285/// }
286///
287/// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
288/// assert_eq!(Rational::new(2, 3) * Rational::new(3, 4),
289///            Rational::new(1, 2));
290/// ```
291///
292/// ## Multiplying vectors by scalars as in linear algebra
293///
294/// ```
295/// use std::ops::Mul;
296///
297/// struct Scalar { value: usize }
298///
299/// #[derive(Debug, PartialEq)]
300/// struct Vector { value: Vec<usize> }
301///
302/// impl Mul<Scalar> for Vector {
303///     type Output = Self;
304///
305///     fn mul(self, rhs: Scalar) -> Self::Output {
306///         Self { value: self.value.iter().map(|v| v * rhs.value).collect() }
307///     }
308/// }
309///
310/// let vector = Vector { value: vec![2, 4, 6] };
311/// let scalar = Scalar { value: 3 };
312/// assert_eq!(vector * scalar, Vector { value: vec![6, 12, 18] });
313/// ```
314#[lang = "mul"]
315#[stable(feature = "rust1", since = "1.0.0")]
316#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
317#[diagnostic::on_unimplemented(
318    message = "cannot multiply `{Self}` by `{Rhs}`",
319    label = "no implementation for `{Self} * {Rhs}`"
320)]
321#[doc(alias = "*")]
322#[const_trait]
323pub trait Mul<Rhs = Self> {
324    /// The resulting type after applying the `*` operator.
325    #[stable(feature = "rust1", since = "1.0.0")]
326    type Output;
327
328    /// Performs the `*` operation.
329    ///
330    /// # Example
331    ///
332    /// ```
333    /// assert_eq!(12 * 2, 24);
334    /// ```
335    #[must_use = "this returns the result of the operation, without modifying the original"]
336    #[rustc_diagnostic_item = "mul"]
337    #[stable(feature = "rust1", since = "1.0.0")]
338    fn mul(self, rhs: Rhs) -> Self::Output;
339}
340
341macro_rules! mul_impl {
342    ($($t:ty)*) => ($(
343        #[stable(feature = "rust1", since = "1.0.0")]
344        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
345        impl const Mul for $t {
346            type Output = $t;
347
348            #[inline]
349            #[track_caller]
350            #[rustc_inherit_overflow_checks]
351            fn mul(self, other: $t) -> $t { self * other }
352        }
353
354        forward_ref_binop! { impl Mul, mul for $t, $t }
355    )*)
356}
357
358mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
359
360/// The division operator `/`.
361///
362/// Note that `Rhs` is `Self` by default, but this is not mandatory.
363///
364/// # Examples
365///
366/// ## `Div`idable rational numbers
367///
368/// ```
369/// use std::ops::Div;
370///
371/// // By the fundamental theorem of arithmetic, rational numbers in lowest
372/// // terms are unique. So, by keeping `Rational`s in reduced form, we can
373/// // derive `Eq` and `PartialEq`.
374/// #[derive(Debug, Eq, PartialEq)]
375/// struct Rational {
376///     numerator: usize,
377///     denominator: usize,
378/// }
379///
380/// impl Rational {
381///     fn new(numerator: usize, denominator: usize) -> Self {
382///         if denominator == 0 {
383///             panic!("Zero is an invalid denominator!");
384///         }
385///
386///         // Reduce to lowest terms by dividing by the greatest common
387///         // divisor.
388///         let gcd = gcd(numerator, denominator);
389///         Self {
390///             numerator: numerator / gcd,
391///             denominator: denominator / gcd,
392///         }
393///     }
394/// }
395///
396/// impl Div for Rational {
397///     // The division of rational numbers is a closed operation.
398///     type Output = Self;
399///
400///     fn div(self, rhs: Self) -> Self::Output {
401///         if rhs.numerator == 0 {
402///             panic!("Cannot divide by zero-valued `Rational`!");
403///         }
404///
405///         let numerator = self.numerator * rhs.denominator;
406///         let denominator = self.denominator * rhs.numerator;
407///         Self::new(numerator, denominator)
408///     }
409/// }
410///
411/// // Euclid's two-thousand-year-old algorithm for finding the greatest common
412/// // divisor.
413/// fn gcd(x: usize, y: usize) -> usize {
414///     let mut x = x;
415///     let mut y = y;
416///     while y != 0 {
417///         let t = y;
418///         y = x % y;
419///         x = t;
420///     }
421///     x
422/// }
423///
424/// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
425/// assert_eq!(Rational::new(1, 2) / Rational::new(3, 4),
426///            Rational::new(2, 3));
427/// ```
428///
429/// ## Dividing vectors by scalars as in linear algebra
430///
431/// ```
432/// use std::ops::Div;
433///
434/// struct Scalar { value: f32 }
435///
436/// #[derive(Debug, PartialEq)]
437/// struct Vector { value: Vec<f32> }
438///
439/// impl Div<Scalar> for Vector {
440///     type Output = Self;
441///
442///     fn div(self, rhs: Scalar) -> Self::Output {
443///         Self { value: self.value.iter().map(|v| v / rhs.value).collect() }
444///     }
445/// }
446///
447/// let scalar = Scalar { value: 2f32 };
448/// let vector = Vector { value: vec![2f32, 4f32, 6f32] };
449/// assert_eq!(vector / scalar, Vector { value: vec![1f32, 2f32, 3f32] });
450/// ```
451#[lang = "div"]
452#[stable(feature = "rust1", since = "1.0.0")]
453#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
454#[diagnostic::on_unimplemented(
455    message = "cannot divide `{Self}` by `{Rhs}`",
456    label = "no implementation for `{Self} / {Rhs}`"
457)]
458#[doc(alias = "/")]
459#[const_trait]
460pub trait Div<Rhs = Self> {
461    /// The resulting type after applying the `/` operator.
462    #[stable(feature = "rust1", since = "1.0.0")]
463    type Output;
464
465    /// Performs the `/` operation.
466    ///
467    /// # Example
468    ///
469    /// ```
470    /// assert_eq!(12 / 2, 6);
471    /// ```
472    #[must_use = "this returns the result of the operation, without modifying the original"]
473    #[rustc_diagnostic_item = "div"]
474    #[stable(feature = "rust1", since = "1.0.0")]
475    fn div(self, rhs: Rhs) -> Self::Output;
476}
477
478macro_rules! div_impl_integer {
479    ($(($($t:ty)*) => $panic:expr),*) => ($($(
480        /// This operation rounds towards zero, truncating any
481        /// fractional part of the exact result.
482        ///
483        /// # Panics
484        ///
485        #[doc = $panic]
486        #[stable(feature = "rust1", since = "1.0.0")]
487        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
488        impl const Div for $t {
489            type Output = $t;
490
491            #[inline]
492            #[track_caller]
493            fn div(self, other: $t) -> $t { self / other }
494        }
495
496        forward_ref_binop! { impl Div, div for $t, $t }
497    )*)*)
498}
499
500div_impl_integer! {
501    (usize u8 u16 u32 u64 u128) => "This operation will panic if `other == 0`.",
502    (isize i8 i16 i32 i64 i128) => "This operation will panic if `other == 0` or the division results in overflow."
503}
504
505macro_rules! div_impl_float {
506    ($($t:ty)*) => ($(
507        #[stable(feature = "rust1", since = "1.0.0")]
508        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
509        impl const Div for $t {
510            type Output = $t;
511
512            #[inline]
513            fn div(self, other: $t) -> $t { self / other }
514        }
515
516        forward_ref_binop! { impl Div, div for $t, $t }
517    )*)
518}
519
520div_impl_float! { f16 f32 f64 f128 }
521
522/// The remainder operator `%`.
523///
524/// Note that `Rhs` is `Self` by default, but this is not mandatory.
525///
526/// # Examples
527///
528/// This example implements `Rem` on a `SplitSlice` object. After `Rem` is
529/// implemented, one can use the `%` operator to find out what the remaining
530/// elements of the slice would be after splitting it into equal slices of a
531/// given length.
532///
533/// ```
534/// use std::ops::Rem;
535///
536/// #[derive(PartialEq, Debug)]
537/// struct SplitSlice<'a, T> {
538///     slice: &'a [T],
539/// }
540///
541/// impl<'a, T> Rem<usize> for SplitSlice<'a, T> {
542///     type Output = Self;
543///
544///     fn rem(self, modulus: usize) -> Self::Output {
545///         let len = self.slice.len();
546///         let rem = len % modulus;
547///         let start = len - rem;
548///         Self {slice: &self.slice[start..]}
549///     }
550/// }
551///
552/// // If we were to divide &[0, 1, 2, 3, 4, 5, 6, 7] into slices of size 3,
553/// // the remainder would be &[6, 7].
554/// assert_eq!(SplitSlice { slice: &[0, 1, 2, 3, 4, 5, 6, 7] } % 3,
555///            SplitSlice { slice: &[6, 7] });
556/// ```
557#[lang = "rem"]
558#[stable(feature = "rust1", since = "1.0.0")]
559#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
560#[diagnostic::on_unimplemented(
561    message = "cannot calculate the remainder of `{Self}` divided by `{Rhs}`",
562    label = "no implementation for `{Self} % {Rhs}`"
563)]
564#[doc(alias = "%")]
565#[const_trait]
566pub trait Rem<Rhs = Self> {
567    /// The resulting type after applying the `%` operator.
568    #[stable(feature = "rust1", since = "1.0.0")]
569    type Output;
570
571    /// Performs the `%` operation.
572    ///
573    /// # Example
574    ///
575    /// ```
576    /// assert_eq!(12 % 10, 2);
577    /// ```
578    #[must_use = "this returns the result of the operation, without modifying the original"]
579    #[rustc_diagnostic_item = "rem"]
580    #[stable(feature = "rust1", since = "1.0.0")]
581    fn rem(self, rhs: Rhs) -> Self::Output;
582}
583
584macro_rules! rem_impl_integer {
585    ($(($($t:ty)*) => $panic:expr),*) => ($($(
586        /// This operation satisfies `n % d == n - (n / d) * d`. The
587        /// result has the same sign as the left operand.
588        ///
589        /// # Panics
590        ///
591        #[doc = $panic]
592        #[stable(feature = "rust1", since = "1.0.0")]
593        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
594        impl const Rem for $t {
595            type Output = $t;
596
597            #[inline]
598            #[track_caller]
599            fn rem(self, other: $t) -> $t { self % other }
600        }
601
602        forward_ref_binop! { impl Rem, rem for $t, $t }
603    )*)*)
604}
605
606rem_impl_integer! {
607    (usize u8 u16 u32 u64 u128) => "This operation will panic if `other == 0`.",
608    (isize i8 i16 i32 i64 i128) => "This operation will panic if `other == 0` or if `self / other` results in overflow."
609}
610
611macro_rules! rem_impl_float {
612    ($($t:ty)*) => ($(
613
614        /// The remainder from the division of two floats.
615        ///
616        /// The remainder has the same sign as the dividend and is computed as:
617        /// `x - (x / y).trunc() * y`.
618        ///
619        /// # Examples
620        /// ```
621        /// let x: f32 = 50.50;
622        /// let y: f32 = 8.125;
623        /// let remainder = x - (x / y).trunc() * y;
624        ///
625        /// // The answer to both operations is 1.75
626        /// assert_eq!(x % y, remainder);
627        /// ```
628        #[stable(feature = "rust1", since = "1.0.0")]
629        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
630        impl const Rem for $t {
631            type Output = $t;
632
633            #[inline]
634            fn rem(self, other: $t) -> $t { self % other }
635        }
636
637        forward_ref_binop! { impl Rem, rem for $t, $t }
638    )*)
639}
640
641rem_impl_float! { f16 f32 f64 f128 }
642
643/// The unary negation operator `-`.
644///
645/// # Examples
646///
647/// An implementation of `Neg` for `Sign`, which allows the use of `-` to
648/// negate its value.
649///
650/// ```
651/// use std::ops::Neg;
652///
653/// #[derive(Debug, PartialEq)]
654/// enum Sign {
655///     Negative,
656///     Zero,
657///     Positive,
658/// }
659///
660/// impl Neg for Sign {
661///     type Output = Self;
662///
663///     fn neg(self) -> Self::Output {
664///         match self {
665///             Sign::Negative => Sign::Positive,
666///             Sign::Zero => Sign::Zero,
667///             Sign::Positive => Sign::Negative,
668///         }
669///     }
670/// }
671///
672/// // A negative positive is a negative.
673/// assert_eq!(-Sign::Positive, Sign::Negative);
674/// // A double negative is a positive.
675/// assert_eq!(-Sign::Negative, Sign::Positive);
676/// // Zero is its own negation.
677/// assert_eq!(-Sign::Zero, Sign::Zero);
678/// ```
679#[lang = "neg"]
680#[stable(feature = "rust1", since = "1.0.0")]
681#[doc(alias = "-")]
682pub trait Neg {
683    /// The resulting type after applying the `-` operator.
684    #[stable(feature = "rust1", since = "1.0.0")]
685    type Output;
686
687    /// Performs the unary `-` operation.
688    ///
689    /// # Example
690    ///
691    /// ```
692    /// let x: i32 = 12;
693    /// assert_eq!(-x, -12);
694    /// ```
695    #[must_use = "this returns the result of the operation, without modifying the original"]
696    #[rustc_diagnostic_item = "neg"]
697    #[stable(feature = "rust1", since = "1.0.0")]
698    fn neg(self) -> Self::Output;
699}
700
701macro_rules! neg_impl {
702    ($($t:ty)*) => ($(
703        #[stable(feature = "rust1", since = "1.0.0")]
704        impl Neg for $t {
705            type Output = $t;
706
707            #[inline]
708            #[rustc_inherit_overflow_checks]
709            fn neg(self) -> $t { -self }
710        }
711
712        forward_ref_unop! { impl Neg, neg for $t }
713    )*)
714}
715
716neg_impl! { isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
717
718/// The addition assignment operator `+=`.
719///
720/// # Examples
721///
722/// This example creates a `Point` struct that implements the `AddAssign`
723/// trait, and then demonstrates add-assigning to a mutable `Point`.
724///
725/// ```
726/// use std::ops::AddAssign;
727///
728/// #[derive(Debug, Copy, Clone, PartialEq)]
729/// struct Point {
730///     x: i32,
731///     y: i32,
732/// }
733///
734/// impl AddAssign for Point {
735///     fn add_assign(&mut self, other: Self) {
736///         *self = Self {
737///             x: self.x + other.x,
738///             y: self.y + other.y,
739///         };
740///     }
741/// }
742///
743/// let mut point = Point { x: 1, y: 0 };
744/// point += Point { x: 2, y: 3 };
745/// assert_eq!(point, Point { x: 3, y: 3 });
746/// ```
747#[lang = "add_assign"]
748#[stable(feature = "op_assign_traits", since = "1.8.0")]
749#[diagnostic::on_unimplemented(
750    message = "cannot add-assign `{Rhs}` to `{Self}`",
751    label = "no implementation for `{Self} += {Rhs}`"
752)]
753#[doc(alias = "+")]
754#[doc(alias = "+=")]
755pub trait AddAssign<Rhs = Self> {
756    /// Performs the `+=` operation.
757    ///
758    /// # Example
759    ///
760    /// ```
761    /// let mut x: u32 = 12;
762    /// x += 1;
763    /// assert_eq!(x, 13);
764    /// ```
765    #[stable(feature = "op_assign_traits", since = "1.8.0")]
766    fn add_assign(&mut self, rhs: Rhs);
767}
768
769macro_rules! add_assign_impl {
770    ($($t:ty)+) => ($(
771        #[stable(feature = "op_assign_traits", since = "1.8.0")]
772        impl AddAssign for $t {
773            #[inline]
774            #[track_caller]
775            #[rustc_inherit_overflow_checks]
776            fn add_assign(&mut self, other: $t) { *self += other }
777        }
778
779        forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t }
780    )+)
781}
782
783add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
784
785/// The subtraction assignment operator `-=`.
786///
787/// # Examples
788///
789/// This example creates a `Point` struct that implements the `SubAssign`
790/// trait, and then demonstrates sub-assigning to a mutable `Point`.
791///
792/// ```
793/// use std::ops::SubAssign;
794///
795/// #[derive(Debug, Copy, Clone, PartialEq)]
796/// struct Point {
797///     x: i32,
798///     y: i32,
799/// }
800///
801/// impl SubAssign for Point {
802///     fn sub_assign(&mut self, other: Self) {
803///         *self = Self {
804///             x: self.x - other.x,
805///             y: self.y - other.y,
806///         };
807///     }
808/// }
809///
810/// let mut point = Point { x: 3, y: 3 };
811/// point -= Point { x: 2, y: 3 };
812/// assert_eq!(point, Point {x: 1, y: 0});
813/// ```
814#[lang = "sub_assign"]
815#[stable(feature = "op_assign_traits", since = "1.8.0")]
816#[diagnostic::on_unimplemented(
817    message = "cannot subtract-assign `{Rhs}` from `{Self}`",
818    label = "no implementation for `{Self} -= {Rhs}`"
819)]
820#[doc(alias = "-")]
821#[doc(alias = "-=")]
822pub trait SubAssign<Rhs = Self> {
823    /// Performs the `-=` operation.
824    ///
825    /// # Example
826    ///
827    /// ```
828    /// let mut x: u32 = 12;
829    /// x -= 1;
830    /// assert_eq!(x, 11);
831    /// ```
832    #[stable(feature = "op_assign_traits", since = "1.8.0")]
833    fn sub_assign(&mut self, rhs: Rhs);
834}
835
836macro_rules! sub_assign_impl {
837    ($($t:ty)+) => ($(
838        #[stable(feature = "op_assign_traits", since = "1.8.0")]
839        impl SubAssign for $t {
840            #[inline]
841            #[track_caller]
842            #[rustc_inherit_overflow_checks]
843            fn sub_assign(&mut self, other: $t) { *self -= other }
844        }
845
846        forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t }
847    )+)
848}
849
850sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
851
852/// The multiplication assignment operator `*=`.
853///
854/// # Examples
855///
856/// ```
857/// use std::ops::MulAssign;
858///
859/// #[derive(Debug, PartialEq)]
860/// struct Frequency { hertz: f64 }
861///
862/// impl MulAssign<f64> for Frequency {
863///     fn mul_assign(&mut self, rhs: f64) {
864///         self.hertz *= rhs;
865///     }
866/// }
867///
868/// let mut frequency = Frequency { hertz: 50.0 };
869/// frequency *= 4.0;
870/// assert_eq!(Frequency { hertz: 200.0 }, frequency);
871/// ```
872#[lang = "mul_assign"]
873#[stable(feature = "op_assign_traits", since = "1.8.0")]
874#[diagnostic::on_unimplemented(
875    message = "cannot multiply-assign `{Self}` by `{Rhs}`",
876    label = "no implementation for `{Self} *= {Rhs}`"
877)]
878#[doc(alias = "*")]
879#[doc(alias = "*=")]
880pub trait MulAssign<Rhs = Self> {
881    /// Performs the `*=` operation.
882    ///
883    /// # Example
884    ///
885    /// ```
886    /// let mut x: u32 = 12;
887    /// x *= 2;
888    /// assert_eq!(x, 24);
889    /// ```
890    #[stable(feature = "op_assign_traits", since = "1.8.0")]
891    fn mul_assign(&mut self, rhs: Rhs);
892}
893
894macro_rules! mul_assign_impl {
895    ($($t:ty)+) => ($(
896        #[stable(feature = "op_assign_traits", since = "1.8.0")]
897        impl MulAssign for $t {
898            #[inline]
899            #[track_caller]
900            #[rustc_inherit_overflow_checks]
901            fn mul_assign(&mut self, other: $t) { *self *= other }
902        }
903
904        forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t }
905    )+)
906}
907
908mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
909
910/// The division assignment operator `/=`.
911///
912/// # Examples
913///
914/// ```
915/// use std::ops::DivAssign;
916///
917/// #[derive(Debug, PartialEq)]
918/// struct Frequency { hertz: f64 }
919///
920/// impl DivAssign<f64> for Frequency {
921///     fn div_assign(&mut self, rhs: f64) {
922///         self.hertz /= rhs;
923///     }
924/// }
925///
926/// let mut frequency = Frequency { hertz: 200.0 };
927/// frequency /= 4.0;
928/// assert_eq!(Frequency { hertz: 50.0 }, frequency);
929/// ```
930#[lang = "div_assign"]
931#[stable(feature = "op_assign_traits", since = "1.8.0")]
932#[diagnostic::on_unimplemented(
933    message = "cannot divide-assign `{Self}` by `{Rhs}`",
934    label = "no implementation for `{Self} /= {Rhs}`"
935)]
936#[doc(alias = "/")]
937#[doc(alias = "/=")]
938pub trait DivAssign<Rhs = Self> {
939    /// Performs the `/=` operation.
940    ///
941    /// # Example
942    ///
943    /// ```
944    /// let mut x: u32 = 12;
945    /// x /= 2;
946    /// assert_eq!(x, 6);
947    /// ```
948    #[stable(feature = "op_assign_traits", since = "1.8.0")]
949    fn div_assign(&mut self, rhs: Rhs);
950}
951
952macro_rules! div_assign_impl {
953    ($($t:ty)+) => ($(
954        #[stable(feature = "op_assign_traits", since = "1.8.0")]
955        impl DivAssign for $t {
956            #[inline]
957            #[track_caller]
958            fn div_assign(&mut self, other: $t) { *self /= other }
959        }
960
961        forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t }
962    )+)
963}
964
965div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
966
967/// The remainder assignment operator `%=`.
968///
969/// # Examples
970///
971/// ```
972/// use std::ops::RemAssign;
973///
974/// struct CookieJar { cookies: u32 }
975///
976/// impl RemAssign<u32> for CookieJar {
977///     fn rem_assign(&mut self, piles: u32) {
978///         self.cookies %= piles;
979///     }
980/// }
981///
982/// let mut jar = CookieJar { cookies: 31 };
983/// let piles = 4;
984///
985/// println!("Splitting up {} cookies into {} even piles!", jar.cookies, piles);
986///
987/// jar %= piles;
988///
989/// println!("{} cookies remain in the cookie jar!", jar.cookies);
990/// ```
991#[lang = "rem_assign"]
992#[stable(feature = "op_assign_traits", since = "1.8.0")]
993#[diagnostic::on_unimplemented(
994    message = "cannot calculate and assign the remainder of `{Self}` divided by `{Rhs}`",
995    label = "no implementation for `{Self} %= {Rhs}`"
996)]
997#[doc(alias = "%")]
998#[doc(alias = "%=")]
999pub trait RemAssign<Rhs = Self> {
1000    /// Performs the `%=` operation.
1001    ///
1002    /// # Example
1003    ///
1004    /// ```
1005    /// let mut x: u32 = 12;
1006    /// x %= 10;
1007    /// assert_eq!(x, 2);
1008    /// ```
1009    #[stable(feature = "op_assign_traits", since = "1.8.0")]
1010    fn rem_assign(&mut self, rhs: Rhs);
1011}
1012
1013macro_rules! rem_assign_impl {
1014    ($($t:ty)+) => ($(
1015        #[stable(feature = "op_assign_traits", since = "1.8.0")]
1016        impl RemAssign for $t {
1017            #[inline]
1018            #[track_caller]
1019            fn rem_assign(&mut self, other: $t) { *self %= other }
1020        }
1021
1022        forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t }
1023    )+)
1024}
1025
1026rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }