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