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