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