1
/// The addition operator `+`.
2
///
3
/// Note that `Rhs` is `Self` by default, but this is not mandatory. For
4
/// example, [`std::time::SystemTime`] implements `Add<Duration>`, which permits
5
/// operations of the form `SystemTime = SystemTime + Duration`.
6
///
7
/// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
8
///
9
/// # Examples
10
///
11
/// ## `Add`able points
12
///
13
/// ```
14
/// use std::ops::Add;
15
///
16
/// #[derive(Debug, Copy, Clone, PartialEq)]
17
/// struct Point {
18
///     x: i32,
19
///     y: i32,
20
/// }
21
///
22
/// impl Add for Point {
23
///     type Output = Self;
24
///
25
///     fn add(self, other: Self) -> Self {
26
///         Self {
27
///             x: self.x + other.x,
28
///             y: self.y + other.y,
29
///         }
30
///     }
31
/// }
32
///
33
/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
34
///            Point { x: 3, y: 3 });
35
/// ```
36
///
37
/// ## Implementing `Add` with generics
38
///
39
/// Here is an example of the same `Point` struct implementing the `Add` trait
40
/// using generics.
41
///
42
/// ```
43
/// use std::ops::Add;
44
///
45
/// #[derive(Debug, Copy, Clone, PartialEq)]
46
/// struct Point<T> {
47
///     x: T,
48
///     y: T,
49
/// }
50
///
51
/// // Notice that the implementation uses the associated type `Output`.
52
/// impl<T: Add<Output = T>> Add for Point<T> {
53
///     type Output = Self;
54
///
55
///     fn add(self, other: Self) -> Self::Output {
56
///         Self {
57
///             x: self.x + other.x,
58
///             y: self.y + other.y,
59
///         }
60
///     }
61
/// }
62
///
63
/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
64
///            Point { x: 3, y: 3 });
65
/// ```
66
#[lang = "add"]
67
#[stable(feature = "rust1", since = "1.0.0")]
68
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
69
#[rustc_on_unimplemented(
70
    on(all(Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",),
71
    on(all(Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",),
72
    message = "cannot add `{Rhs}` to `{Self}`",
73
    label = "no implementation for `{Self} + {Rhs}`",
74
    append_const_msg
75
)]
76
#[doc(alias = "+")]
77
#[const_trait]
78
pub trait Add<Rhs = Self> {
79
    /// The resulting type after applying the `+` operator.
80
    #[stable(feature = "rust1", since = "1.0.0")]
81
    type Output;
82

            
83
    /// Performs the `+` operation.
84
    ///
85
    /// # Example
86
    ///
87
    /// ```
88
    /// assert_eq!(12 + 1, 13);
89
    /// ```
90
    #[must_use = "this returns the result of the operation, without modifying the original"]
91
    #[rustc_diagnostic_item = "add"]
92
    #[stable(feature = "rust1", since = "1.0.0")]
93
    fn add(self, rhs: Rhs) -> Self::Output;
94
}
95

            
96
macro_rules! add_impl {
97
    ($($t:ty)*) => ($(
98
        #[stable(feature = "rust1", since = "1.0.0")]
99
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
100
        impl const Add for $t {
101
            type Output = $t;
102

            
103
            #[inline]
104
            #[track_caller]
105
            #[rustc_inherit_overflow_checks]
106
34
            fn add(self, other: $t) -> $t { self + other }
107
        }
108

            
109
        forward_ref_binop! { impl Add, add for $t, $t,
110
        #[stable(feature = "rust1", since = "1.0.0")]
111
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
112
    )*)
113
}
114

            
115
#[cfg(not(feature = "ferrocene_certified"))]
116
add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
117

            
118
#[cfg(feature = "ferrocene_certified")]
119
add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
120

            
121
/// The subtraction operator `-`.
122
///
123
/// Note that `Rhs` is `Self` by default, but this is not mandatory. For
124
/// example, [`std::time::SystemTime`] implements `Sub<Duration>`, which permits
125
/// operations of the form `SystemTime = SystemTime - Duration`.
126
///
127
/// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
128
///
129
/// # Examples
130
///
131
/// ## `Sub`tractable points
132
///
133
/// ```
134
/// use std::ops::Sub;
135
///
136
/// #[derive(Debug, Copy, Clone, PartialEq)]
137
/// struct Point {
138
///     x: i32,
139
///     y: i32,
140
/// }
141
///
142
/// impl Sub for Point {
143
///     type Output = Self;
144
///
145
///     fn sub(self, other: Self) -> Self::Output {
146
///         Self {
147
///             x: self.x - other.x,
148
///             y: self.y - other.y,
149
///         }
150
///     }
151
/// }
152
///
153
/// assert_eq!(Point { x: 3, y: 3 } - Point { x: 2, y: 3 },
154
///            Point { x: 1, y: 0 });
155
/// ```
156
///
157
/// ## Implementing `Sub` with generics
158
///
159
/// Here is an example of the same `Point` struct implementing the `Sub` trait
160
/// using generics.
161
///
162
/// ```
163
/// use std::ops::Sub;
164
///
165
/// #[derive(Debug, PartialEq)]
166
/// struct Point<T> {
167
///     x: T,
168
///     y: T,
169
/// }
170
///
171
/// // Notice that the implementation uses the associated type `Output`.
172
/// impl<T: Sub<Output = T>> Sub for Point<T> {
173
///     type Output = Self;
174
///
175
///     fn sub(self, other: Self) -> Self::Output {
176
///         Point {
177
///             x: self.x - other.x,
178
///             y: self.y - other.y,
179
///         }
180
///     }
181
/// }
182
///
183
/// assert_eq!(Point { x: 2, y: 3 } - Point { x: 1, y: 0 },
184
///            Point { x: 1, y: 3 });
185
/// ```
186
#[lang = "sub"]
187
#[stable(feature = "rust1", since = "1.0.0")]
188
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
189
#[rustc_on_unimplemented(
190
    message = "cannot subtract `{Rhs}` from `{Self}`",
191
    label = "no implementation for `{Self} - {Rhs}`",
192
    append_const_msg
193
)]
194
#[doc(alias = "-")]
195
#[const_trait]
196
pub trait Sub<Rhs = Self> {
197
    /// The resulting type after applying the `-` operator.
198
    #[stable(feature = "rust1", since = "1.0.0")]
199
    type Output;
200

            
201
    /// Performs the `-` operation.
202
    ///
203
    /// # Example
204
    ///
205
    /// ```
206
    /// assert_eq!(12 - 1, 11);
207
    /// ```
208
    #[must_use = "this returns the result of the operation, without modifying the original"]
209
    #[rustc_diagnostic_item = "sub"]
210
    #[stable(feature = "rust1", since = "1.0.0")]
211
    fn sub(self, rhs: Rhs) -> Self::Output;
212
}
213

            
214
macro_rules! sub_impl {
215
    ($($t:ty)*) => ($(
216
        #[stable(feature = "rust1", since = "1.0.0")]
217
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
218
        impl const Sub for $t {
219
            type Output = $t;
220

            
221
            #[inline]
222
            #[track_caller]
223
            #[rustc_inherit_overflow_checks]
224
147762
            fn sub(self, other: $t) -> $t { self - other }
225
        }
226

            
227
        forward_ref_binop! { impl Sub, sub for $t, $t,
228
        #[stable(feature = "rust1", since = "1.0.0")]
229
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
230
    )*)
231
}
232

            
233
#[cfg(not(feature = "ferrocene_certified"))]
234
sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
235

            
236
#[cfg(feature = "ferrocene_certified")]
237
sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
238

            
239
/// The multiplication operator `*`.
240
///
241
/// Note that `Rhs` is `Self` by default, but this is not mandatory.
242
///
243
/// # Examples
244
///
245
/// ## `Mul`tipliable rational numbers
246
///
247
/// ```
248
/// use std::ops::Mul;
249
///
250
/// // By the fundamental theorem of arithmetic, rational numbers in lowest
251
/// // terms are unique. So, by keeping `Rational`s in reduced form, we can
252
/// // derive `Eq` and `PartialEq`.
253
/// #[derive(Debug, Eq, PartialEq)]
254
/// struct Rational {
255
///     numerator: usize,
256
///     denominator: usize,
257
/// }
258
///
259
/// impl Rational {
260
///     fn new(numerator: usize, denominator: usize) -> Self {
261
///         if denominator == 0 {
262
///             panic!("Zero is an invalid denominator!");
263
///         }
264
///
265
///         // Reduce to lowest terms by dividing by the greatest common
266
///         // divisor.
267
///         let gcd = gcd(numerator, denominator);
268
///         Self {
269
///             numerator: numerator / gcd,
270
///             denominator: denominator / gcd,
271
///         }
272
///     }
273
/// }
274
///
275
/// impl Mul for Rational {
276
///     // The multiplication of rational numbers is a closed operation.
277
///     type Output = Self;
278
///
279
///     fn mul(self, rhs: Self) -> Self {
280
///         let numerator = self.numerator * rhs.numerator;
281
///         let denominator = self.denominator * rhs.denominator;
282
///         Self::new(numerator, denominator)
283
///     }
284
/// }
285
///
286
/// // Euclid's two-thousand-year-old algorithm for finding the greatest common
287
/// // divisor.
288
/// fn gcd(x: usize, y: usize) -> usize {
289
///     let mut x = x;
290
///     let mut y = y;
291
///     while y != 0 {
292
///         let t = y;
293
///         y = x % y;
294
///         x = t;
295
///     }
296
///     x
297
/// }
298
///
299
/// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
300
/// assert_eq!(Rational::new(2, 3) * Rational::new(3, 4),
301
///            Rational::new(1, 2));
302
/// ```
303
///
304
/// ## Multiplying vectors by scalars as in linear algebra
305
///
306
/// ```
307
/// use std::ops::Mul;
308
///
309
/// struct Scalar { value: usize }
310
///
311
/// #[derive(Debug, PartialEq)]
312
/// struct Vector { value: Vec<usize> }
313
///
314
/// impl Mul<Scalar> for Vector {
315
///     type Output = Self;
316
///
317
///     fn mul(self, rhs: Scalar) -> Self::Output {
318
///         Self { value: self.value.iter().map(|v| v * rhs.value).collect() }
319
///     }
320
/// }
321
///
322
/// let vector = Vector { value: vec![2, 4, 6] };
323
/// let scalar = Scalar { value: 3 };
324
/// assert_eq!(vector * scalar, Vector { value: vec![6, 12, 18] });
325
/// ```
326
#[lang = "mul"]
327
#[stable(feature = "rust1", since = "1.0.0")]
328
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
329
#[diagnostic::on_unimplemented(
330
    message = "cannot multiply `{Self}` by `{Rhs}`",
331
    label = "no implementation for `{Self} * {Rhs}`"
332
)]
333
#[doc(alias = "*")]
334
#[const_trait]
335
pub trait Mul<Rhs = Self> {
336
    /// The resulting type after applying the `*` operator.
337
    #[stable(feature = "rust1", since = "1.0.0")]
338
    type Output;
339

            
340
    /// Performs the `*` operation.
341
    ///
342
    /// # Example
343
    ///
344
    /// ```
345
    /// assert_eq!(12 * 2, 24);
346
    /// ```
347
    #[must_use = "this returns the result of the operation, without modifying the original"]
348
    #[rustc_diagnostic_item = "mul"]
349
    #[stable(feature = "rust1", since = "1.0.0")]
350
    fn mul(self, rhs: Rhs) -> Self::Output;
351
}
352

            
353
macro_rules! mul_impl {
354
    ($($t:ty)*) => ($(
355
        #[stable(feature = "rust1", since = "1.0.0")]
356
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
357
        impl const Mul for $t {
358
            type Output = $t;
359

            
360
            #[inline]
361
            #[track_caller]
362
            #[rustc_inherit_overflow_checks]
363
73
            fn mul(self, other: $t) -> $t { self * other }
364
        }
365

            
366
        forward_ref_binop! { impl Mul, mul for $t, $t,
367
        #[stable(feature = "rust1", since = "1.0.0")]
368
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
369
    )*)
370
}
371

            
372
#[cfg(not(feature = "ferrocene_certified"))]
373
mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
374

            
375
#[cfg(feature = "ferrocene_certified")]
376
mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
377

            
378
/// The division operator `/`.
379
///
380
/// Note that `Rhs` is `Self` by default, but this is not mandatory.
381
///
382
/// # Examples
383
///
384
/// ## `Div`idable rational numbers
385
///
386
/// ```
387
/// use std::ops::Div;
388
///
389
/// // By the fundamental theorem of arithmetic, rational numbers in lowest
390
/// // terms are unique. So, by keeping `Rational`s in reduced form, we can
391
/// // derive `Eq` and `PartialEq`.
392
/// #[derive(Debug, Eq, PartialEq)]
393
/// struct Rational {
394
///     numerator: usize,
395
///     denominator: usize,
396
/// }
397
///
398
/// impl Rational {
399
///     fn new(numerator: usize, denominator: usize) -> Self {
400
///         if denominator == 0 {
401
///             panic!("Zero is an invalid denominator!");
402
///         }
403
///
404
///         // Reduce to lowest terms by dividing by the greatest common
405
///         // divisor.
406
///         let gcd = gcd(numerator, denominator);
407
///         Self {
408
///             numerator: numerator / gcd,
409
///             denominator: denominator / gcd,
410
///         }
411
///     }
412
/// }
413
///
414
/// impl Div for Rational {
415
///     // The division of rational numbers is a closed operation.
416
///     type Output = Self;
417
///
418
///     fn div(self, rhs: Self) -> Self::Output {
419
///         if rhs.numerator == 0 {
420
///             panic!("Cannot divide by zero-valued `Rational`!");
421
///         }
422
///
423
///         let numerator = self.numerator * rhs.denominator;
424
///         let denominator = self.denominator * rhs.numerator;
425
///         Self::new(numerator, denominator)
426
///     }
427
/// }
428
///
429
/// // Euclid's two-thousand-year-old algorithm for finding the greatest common
430
/// // divisor.
431
/// fn gcd(x: usize, y: usize) -> usize {
432
///     let mut x = x;
433
///     let mut y = y;
434
///     while y != 0 {
435
///         let t = y;
436
///         y = x % y;
437
///         x = t;
438
///     }
439
///     x
440
/// }
441
///
442
/// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
443
/// assert_eq!(Rational::new(1, 2) / Rational::new(3, 4),
444
///            Rational::new(2, 3));
445
/// ```
446
///
447
/// ## Dividing vectors by scalars as in linear algebra
448
///
449
/// ```
450
/// use std::ops::Div;
451
///
452
/// struct Scalar { value: f32 }
453
///
454
/// #[derive(Debug, PartialEq)]
455
/// struct Vector { value: Vec<f32> }
456
///
457
/// impl Div<Scalar> for Vector {
458
///     type Output = Self;
459
///
460
///     fn div(self, rhs: Scalar) -> Self::Output {
461
///         Self { value: self.value.iter().map(|v| v / rhs.value).collect() }
462
///     }
463
/// }
464
///
465
/// let scalar = Scalar { value: 2f32 };
466
/// let vector = Vector { value: vec![2f32, 4f32, 6f32] };
467
/// assert_eq!(vector / scalar, Vector { value: vec![1f32, 2f32, 3f32] });
468
/// ```
469
#[lang = "div"]
470
#[stable(feature = "rust1", since = "1.0.0")]
471
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
472
#[diagnostic::on_unimplemented(
473
    message = "cannot divide `{Self}` by `{Rhs}`",
474
    label = "no implementation for `{Self} / {Rhs}`"
475
)]
476
#[doc(alias = "/")]
477
#[const_trait]
478
pub trait Div<Rhs = Self> {
479
    /// The resulting type after applying the `/` operator.
480
    #[stable(feature = "rust1", since = "1.0.0")]
481
    type Output;
482

            
483
    /// Performs the `/` operation.
484
    ///
485
    /// # Example
486
    ///
487
    /// ```
488
    /// assert_eq!(12 / 2, 6);
489
    /// ```
490
    #[must_use = "this returns the result of the operation, without modifying the original"]
491
    #[rustc_diagnostic_item = "div"]
492
    #[stable(feature = "rust1", since = "1.0.0")]
493
    fn div(self, rhs: Rhs) -> Self::Output;
494
}
495

            
496
macro_rules! div_impl_integer {
497
    ($(($($t:ty)*) => $panic:expr),*) => ($($(
498
        /// This operation rounds towards zero, truncating any
499
        /// fractional part of the exact result.
500
        ///
501
        /// # Panics
502
        ///
503
        #[doc = $panic]
504
        #[stable(feature = "rust1", since = "1.0.0")]
505
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
506
        impl const Div for $t {
507
            type Output = $t;
508

            
509
            #[inline]
510
            #[track_caller]
511
            fn div(self, other: $t) -> $t { self / other }
512
        }
513

            
514
        forward_ref_binop! { impl Div, div for $t, $t,
515
        #[stable(feature = "rust1", since = "1.0.0")]
516
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
517
    )*)*)
518
}
519

            
520
div_impl_integer! {
521
    (usize u8 u16 u32 u64 u128) => "This operation will panic if `other == 0`.",
522
    (isize i8 i16 i32 i64 i128) => "This operation will panic if `other == 0` or the division results in overflow."
523
}
524

            
525
macro_rules! div_impl_float {
526
    ($($t:ty)*) => ($(
527
        #[stable(feature = "rust1", since = "1.0.0")]
528
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
529
        impl const Div for $t {
530
            type Output = $t;
531

            
532
            #[inline]
533
135
            fn div(self, other: $t) -> $t { self / other }
534
        }
535

            
536
        forward_ref_binop! { impl Div, div for $t, $t,
537
        #[stable(feature = "rust1", since = "1.0.0")]
538
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
539
    )*)
540
}
541

            
542
#[cfg(not(feature = "ferrocene_certified"))]
543
div_impl_float! { f16 f32 f64 f128 }
544

            
545
#[cfg(feature = "ferrocene_certified")]
546
div_impl_float! { f32 f64 }
547

            
548
/// The remainder operator `%`.
549
///
550
/// Note that `Rhs` is `Self` by default, but this is not mandatory.
551
///
552
/// # Examples
553
///
554
/// This example implements `Rem` on a `SplitSlice` object. After `Rem` is
555
/// implemented, one can use the `%` operator to find out what the remaining
556
/// elements of the slice would be after splitting it into equal slices of a
557
/// given length.
558
///
559
/// ```
560
/// use std::ops::Rem;
561
///
562
/// #[derive(PartialEq, Debug)]
563
/// struct SplitSlice<'a, T> {
564
///     slice: &'a [T],
565
/// }
566
///
567
/// impl<'a, T> Rem<usize> for SplitSlice<'a, T> {
568
///     type Output = Self;
569
///
570
///     fn rem(self, modulus: usize) -> Self::Output {
571
///         let len = self.slice.len();
572
///         let rem = len % modulus;
573
///         let start = len - rem;
574
///         Self {slice: &self.slice[start..]}
575
///     }
576
/// }
577
///
578
/// // If we were to divide &[0, 1, 2, 3, 4, 5, 6, 7] into slices of size 3,
579
/// // the remainder would be &[6, 7].
580
/// assert_eq!(SplitSlice { slice: &[0, 1, 2, 3, 4, 5, 6, 7] } % 3,
581
///            SplitSlice { slice: &[6, 7] });
582
/// ```
583
#[lang = "rem"]
584
#[stable(feature = "rust1", since = "1.0.0")]
585
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
586
#[diagnostic::on_unimplemented(
587
    message = "cannot calculate the remainder of `{Self}` divided by `{Rhs}`",
588
    label = "no implementation for `{Self} % {Rhs}`"
589
)]
590
#[doc(alias = "%")]
591
#[const_trait]
592
pub trait Rem<Rhs = Self> {
593
    /// The resulting type after applying the `%` operator.
594
    #[stable(feature = "rust1", since = "1.0.0")]
595
    type Output;
596

            
597
    /// Performs the `%` operation.
598
    ///
599
    /// # Example
600
    ///
601
    /// ```
602
    /// assert_eq!(12 % 10, 2);
603
    /// ```
604
    #[must_use = "this returns the result of the operation, without modifying the original"]
605
    #[rustc_diagnostic_item = "rem"]
606
    #[stable(feature = "rust1", since = "1.0.0")]
607
    fn rem(self, rhs: Rhs) -> Self::Output;
608
}
609

            
610
macro_rules! rem_impl_integer {
611
    ($(($($t:ty)*) => $panic:expr),*) => ($($(
612
        /// This operation satisfies `n % d == n - (n / d) * d`. The
613
        /// result has the same sign as the left operand.
614
        ///
615
        /// # Panics
616
        ///
617
        #[doc = $panic]
618
        #[stable(feature = "rust1", since = "1.0.0")]
619
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
620
        impl const Rem for $t {
621
            type Output = $t;
622

            
623
            #[inline]
624
            #[track_caller]
625
12000006
            fn rem(self, other: $t) -> $t { self % other }
626
        }
627

            
628
        forward_ref_binop! { impl Rem, rem for $t, $t,
629
        #[stable(feature = "rust1", since = "1.0.0")]
630
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
631
    )*)*)
632
}
633

            
634
rem_impl_integer! {
635
    (usize u8 u16 u32 u64 u128) => "This operation will panic if `other == 0`.",
636
    (isize i8 i16 i32 i64 i128) => "This operation will panic if `other == 0` or if `self / other` results in overflow."
637
}
638

            
639
macro_rules! rem_impl_float {
640
    ($($t:ty)*) => ($(
641

            
642
        /// The remainder from the division of two floats.
643
        ///
644
        /// The remainder has the same sign as the dividend and is computed as:
645
        /// `x - (x / y).trunc() * y`.
646
        ///
647
        /// # Examples
648
        /// ```
649
        /// let x: f32 = 50.50;
650
        /// let y: f32 = 8.125;
651
        /// let remainder = x - (x / y).trunc() * y;
652
        ///
653
        /// // The answer to both operations is 1.75
654
        /// assert_eq!(x % y, remainder);
655
        /// ```
656
        #[stable(feature = "rust1", since = "1.0.0")]
657
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
658
        impl const Rem for $t {
659
            type Output = $t;
660

            
661
            #[inline]
662
            fn rem(self, other: $t) -> $t { self % other }
663
        }
664

            
665
        forward_ref_binop! { impl Rem, rem for $t, $t,
666
        #[stable(feature = "rust1", since = "1.0.0")]
667
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
668
    )*)
669
}
670

            
671
#[cfg(not(feature = "ferrocene_certified"))]
672
rem_impl_float! { f16 f32 f64 f128 }
673

            
674
#[cfg(feature = "ferrocene_certified")]
675
rem_impl_float! { f32 f64 }
676

            
677
/// The unary negation operator `-`.
678
///
679
/// # Examples
680
///
681
/// An implementation of `Neg` for `Sign`, which allows the use of `-` to
682
/// negate its value.
683
///
684
/// ```
685
/// use std::ops::Neg;
686
///
687
/// #[derive(Debug, PartialEq)]
688
/// enum Sign {
689
///     Negative,
690
///     Zero,
691
///     Positive,
692
/// }
693
///
694
/// impl Neg for Sign {
695
///     type Output = Self;
696
///
697
///     fn neg(self) -> Self::Output {
698
///         match self {
699
///             Sign::Negative => Sign::Positive,
700
///             Sign::Zero => Sign::Zero,
701
///             Sign::Positive => Sign::Negative,
702
///         }
703
///     }
704
/// }
705
///
706
/// // A negative positive is a negative.
707
/// assert_eq!(-Sign::Positive, Sign::Negative);
708
/// // A double negative is a positive.
709
/// assert_eq!(-Sign::Negative, Sign::Positive);
710
/// // Zero is its own negation.
711
/// assert_eq!(-Sign::Zero, Sign::Zero);
712
/// ```
713
#[lang = "neg"]
714
#[stable(feature = "rust1", since = "1.0.0")]
715
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
716
#[doc(alias = "-")]
717
#[const_trait]
718
pub trait Neg {
719
    /// The resulting type after applying the `-` operator.
720
    #[stable(feature = "rust1", since = "1.0.0")]
721
    type Output;
722

            
723
    /// Performs the unary `-` operation.
724
    ///
725
    /// # Example
726
    ///
727
    /// ```
728
    /// let x: i32 = 12;
729
    /// assert_eq!(-x, -12);
730
    /// ```
731
    #[must_use = "this returns the result of the operation, without modifying the original"]
732
    #[rustc_diagnostic_item = "neg"]
733
    #[stable(feature = "rust1", since = "1.0.0")]
734
    fn neg(self) -> Self::Output;
735
}
736

            
737
macro_rules! neg_impl {
738
    ($($t:ty)*) => ($(
739
        #[stable(feature = "rust1", since = "1.0.0")]
740
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
741
        impl const Neg for $t {
742
            type Output = $t;
743

            
744
            #[inline]
745
            #[rustc_inherit_overflow_checks]
746
100
            fn neg(self) -> $t { -self }
747
        }
748

            
749
        forward_ref_unop! { impl Neg, neg for $t,
750
        #[stable(feature = "rust1", since = "1.0.0")]
751
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
752
    )*)
753
}
754

            
755
#[cfg(not(feature = "ferrocene_certified"))]
756
neg_impl! { isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
757

            
758
#[cfg(feature = "ferrocene_certified")]
759
neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 }
760

            
761
/// The addition assignment operator `+=`.
762
///
763
/// # Examples
764
///
765
/// This example creates a `Point` struct that implements the `AddAssign`
766
/// trait, and then demonstrates add-assigning to a mutable `Point`.
767
///
768
/// ```
769
/// use std::ops::AddAssign;
770
///
771
/// #[derive(Debug, Copy, Clone, PartialEq)]
772
/// struct Point {
773
///     x: i32,
774
///     y: i32,
775
/// }
776
///
777
/// impl AddAssign for Point {
778
///     fn add_assign(&mut self, other: Self) {
779
///         *self = Self {
780
///             x: self.x + other.x,
781
///             y: self.y + other.y,
782
///         };
783
///     }
784
/// }
785
///
786
/// let mut point = Point { x: 1, y: 0 };
787
/// point += Point { x: 2, y: 3 };
788
/// assert_eq!(point, Point { x: 3, y: 3 });
789
/// ```
790
#[lang = "add_assign"]
791
#[stable(feature = "op_assign_traits", since = "1.8.0")]
792
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
793
#[diagnostic::on_unimplemented(
794
    message = "cannot add-assign `{Rhs}` to `{Self}`",
795
    label = "no implementation for `{Self} += {Rhs}`"
796
)]
797
#[doc(alias = "+")]
798
#[doc(alias = "+=")]
799
#[const_trait]
800
pub trait AddAssign<Rhs = Self> {
801
    /// Performs the `+=` operation.
802
    ///
803
    /// # Example
804
    ///
805
    /// ```
806
    /// let mut x: u32 = 12;
807
    /// x += 1;
808
    /// assert_eq!(x, 13);
809
    /// ```
810
    #[stable(feature = "op_assign_traits", since = "1.8.0")]
811
    fn add_assign(&mut self, rhs: Rhs);
812
}
813

            
814
macro_rules! add_assign_impl {
815
    ($($t:ty)+) => ($(
816
        #[stable(feature = "op_assign_traits", since = "1.8.0")]
817
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
818
        impl const AddAssign for $t {
819
            #[inline]
820
            #[track_caller]
821
            #[rustc_inherit_overflow_checks]
822
37718
            fn add_assign(&mut self, other: $t) { *self += other }
823
        }
824

            
825
        forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t,
826
        #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]
827
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
828
    )+)
829
}
830

            
831
#[cfg(not(feature = "ferrocene_certified"))]
832
add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
833

            
834
#[cfg(feature = "ferrocene_certified")]
835
add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
836

            
837
/// The subtraction assignment operator `-=`.
838
///
839
/// # Examples
840
///
841
/// This example creates a `Point` struct that implements the `SubAssign`
842
/// trait, and then demonstrates sub-assigning to a mutable `Point`.
843
///
844
/// ```
845
/// use std::ops::SubAssign;
846
///
847
/// #[derive(Debug, Copy, Clone, PartialEq)]
848
/// struct Point {
849
///     x: i32,
850
///     y: i32,
851
/// }
852
///
853
/// impl SubAssign for Point {
854
///     fn sub_assign(&mut self, other: Self) {
855
///         *self = Self {
856
///             x: self.x - other.x,
857
///             y: self.y - other.y,
858
///         };
859
///     }
860
/// }
861
///
862
/// let mut point = Point { x: 3, y: 3 };
863
/// point -= Point { x: 2, y: 3 };
864
/// assert_eq!(point, Point {x: 1, y: 0});
865
/// ```
866
#[lang = "sub_assign"]
867
#[stable(feature = "op_assign_traits", since = "1.8.0")]
868
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
869
#[diagnostic::on_unimplemented(
870
    message = "cannot subtract-assign `{Rhs}` from `{Self}`",
871
    label = "no implementation for `{Self} -= {Rhs}`"
872
)]
873
#[doc(alias = "-")]
874
#[doc(alias = "-=")]
875
#[const_trait]
876
pub trait SubAssign<Rhs = Self> {
877
    /// Performs the `-=` operation.
878
    ///
879
    /// # Example
880
    ///
881
    /// ```
882
    /// let mut x: u32 = 12;
883
    /// x -= 1;
884
    /// assert_eq!(x, 11);
885
    /// ```
886
    #[stable(feature = "op_assign_traits", since = "1.8.0")]
887
    fn sub_assign(&mut self, rhs: Rhs);
888
}
889

            
890
macro_rules! sub_assign_impl {
891
    ($($t:ty)+) => ($(
892
        #[stable(feature = "op_assign_traits", since = "1.8.0")]
893
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
894
        impl const SubAssign for $t {
895
            #[inline]
896
            #[track_caller]
897
            #[rustc_inherit_overflow_checks]
898
2
            fn sub_assign(&mut self, other: $t) { *self -= other }
899
        }
900

            
901
        forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t,
902
        #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]
903
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
904
    )+)
905
}
906

            
907
#[cfg(not(feature = "ferrocene_certified"))]
908
sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
909

            
910
#[cfg(feature = "ferrocene_certified")]
911
sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
912

            
913
/// The multiplication assignment operator `*=`.
914
///
915
/// # Examples
916
///
917
/// ```
918
/// use std::ops::MulAssign;
919
///
920
/// #[derive(Debug, PartialEq)]
921
/// struct Frequency { hertz: f64 }
922
///
923
/// impl MulAssign<f64> for Frequency {
924
///     fn mul_assign(&mut self, rhs: f64) {
925
///         self.hertz *= rhs;
926
///     }
927
/// }
928
///
929
/// let mut frequency = Frequency { hertz: 50.0 };
930
/// frequency *= 4.0;
931
/// assert_eq!(Frequency { hertz: 200.0 }, frequency);
932
/// ```
933
#[lang = "mul_assign"]
934
#[stable(feature = "op_assign_traits", since = "1.8.0")]
935
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
936
#[diagnostic::on_unimplemented(
937
    message = "cannot multiply-assign `{Self}` by `{Rhs}`",
938
    label = "no implementation for `{Self} *= {Rhs}`"
939
)]
940
#[doc(alias = "*")]
941
#[doc(alias = "*=")]
942
#[const_trait]
943
pub trait MulAssign<Rhs = Self> {
944
    /// Performs the `*=` operation.
945
    ///
946
    /// # Example
947
    ///
948
    /// ```
949
    /// let mut x: u32 = 12;
950
    /// x *= 2;
951
    /// assert_eq!(x, 24);
952
    /// ```
953
    #[stable(feature = "op_assign_traits", since = "1.8.0")]
954
    fn mul_assign(&mut self, rhs: Rhs);
955
}
956

            
957
macro_rules! mul_assign_impl {
958
    ($($t:ty)+) => ($(
959
        #[stable(feature = "op_assign_traits", since = "1.8.0")]
960
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
961
        impl const MulAssign for $t {
962
            #[inline]
963
            #[track_caller]
964
            #[rustc_inherit_overflow_checks]
965
1026
            fn mul_assign(&mut self, other: $t) { *self *= other }
966
        }
967

            
968
        forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t,
969
        #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]
970
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
971
    )+)
972
}
973

            
974
#[cfg(not(feature = "ferrocene_certified"))]
975
mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
976

            
977
#[cfg(feature = "ferrocene_certified")]
978
mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
979

            
980
/// The division assignment operator `/=`.
981
///
982
/// # Examples
983
///
984
/// ```
985
/// use std::ops::DivAssign;
986
///
987
/// #[derive(Debug, PartialEq)]
988
/// struct Frequency { hertz: f64 }
989
///
990
/// impl DivAssign<f64> for Frequency {
991
///     fn div_assign(&mut self, rhs: f64) {
992
///         self.hertz /= rhs;
993
///     }
994
/// }
995
///
996
/// let mut frequency = Frequency { hertz: 200.0 };
997
/// frequency /= 4.0;
998
/// assert_eq!(Frequency { hertz: 50.0 }, frequency);
999
/// ```
#[lang = "div_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
#[diagnostic::on_unimplemented(
    message = "cannot divide-assign `{Self}` by `{Rhs}`",
    label = "no implementation for `{Self} /= {Rhs}`"
)]
#[doc(alias = "/")]
#[doc(alias = "/=")]
#[const_trait]
pub trait DivAssign<Rhs = Self> {
    /// Performs the `/=` operation.
    ///
    /// # Example
    ///
    /// ```
    /// let mut x: u32 = 12;
    /// x /= 2;
    /// assert_eq!(x, 6);
    /// ```
    #[stable(feature = "op_assign_traits", since = "1.8.0")]
    fn div_assign(&mut self, rhs: Rhs);
}
macro_rules! div_assign_impl {
    ($($t:ty)+) => ($(
        #[stable(feature = "op_assign_traits", since = "1.8.0")]
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
        impl const DivAssign for $t {
            #[inline]
            #[track_caller]
            fn div_assign(&mut self, other: $t) { *self /= other }
        }
        forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t,
        #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
    )+)
}
#[cfg(not(feature = "ferrocene_certified"))]
div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
#[cfg(feature = "ferrocene_certified")]
div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
/// The remainder assignment operator `%=`.
///
/// # Examples
///
/// ```
/// use std::ops::RemAssign;
///
/// struct CookieJar { cookies: u32 }
///
/// impl RemAssign<u32> for CookieJar {
///     fn rem_assign(&mut self, piles: u32) {
///         self.cookies %= piles;
///     }
/// }
///
/// let mut jar = CookieJar { cookies: 31 };
/// let piles = 4;
///
/// println!("Splitting up {} cookies into {} even piles!", jar.cookies, piles);
///
/// jar %= piles;
///
/// println!("{} cookies remain in the cookie jar!", jar.cookies);
/// ```
#[lang = "rem_assign"]
#[stable(feature = "op_assign_traits", since = "1.8.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
#[diagnostic::on_unimplemented(
    message = "cannot calculate and assign the remainder of `{Self}` divided by `{Rhs}`",
    label = "no implementation for `{Self} %= {Rhs}`"
)]
#[doc(alias = "%")]
#[doc(alias = "%=")]
#[const_trait]
pub trait RemAssign<Rhs = Self> {
    /// Performs the `%=` operation.
    ///
    /// # Example
    ///
    /// ```
    /// let mut x: u32 = 12;
    /// x %= 10;
    /// assert_eq!(x, 2);
    /// ```
    #[stable(feature = "op_assign_traits", since = "1.8.0")]
    fn rem_assign(&mut self, rhs: Rhs);
}
macro_rules! rem_assign_impl {
    ($($t:ty)+) => ($(
        #[stable(feature = "op_assign_traits", since = "1.8.0")]
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
        impl const RemAssign for $t {
            #[inline]
            #[track_caller]
8
            fn rem_assign(&mut self, other: $t) { *self %= other }
        }
        forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t,
        #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]
        #[rustc_const_unstable(feature = "const_ops", issue = "143802")] }
    )+)
}
#[cfg(not(feature = "ferrocene_certified"))]
rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128 }
#[cfg(feature = "ferrocene_certified")]
rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }