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 }