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