Skip to main content

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