ra_ap_rustc_serialize/int_overflow.rs
1// This would belong to `rustc_data_structures`, but `rustc_serialize` needs it too.
2
3/// Addition, but only overflow checked when `cfg(debug_assertions)` is set
4/// instead of respecting `-Coverflow-checks`.
5///
6/// This exists for performance reasons, as we ship rustc with overflow checks.
7/// While overflow checks are perf neutral in almost all of the compiler, there
8/// are a few particularly hot areas where we don't want overflow checks in our
9/// dist builds. Overflow is still a bug there, so we want overflow check for
10/// builds with debug assertions.
11///
12/// That's a long way to say that this should be used in areas where overflow
13/// is a bug but overflow checking is too slow.
14pub trait DebugStrictAdd {
15 /// See [`DebugStrictAdd`].
16 fn debug_strict_add(self, other: Self) -> Self;
17}
18
19macro_rules! impl_debug_strict_add {
20 ($( $ty:ty )*) => {
21 $(
22 impl DebugStrictAdd for $ty {
23 fn debug_strict_add(self, other: Self) -> Self {
24 if cfg!(debug_assertions) {
25 self + other
26 } else {
27 self.wrapping_add(other)
28 }
29 }
30 }
31 )*
32 };
33}
34
35/// See [`DebugStrictAdd`].
36pub trait DebugStrictSub {
37 /// See [`DebugStrictAdd`].
38 fn debug_strict_sub(self, other: Self) -> Self;
39}
40
41macro_rules! impl_debug_strict_sub {
42 ($( $ty:ty )*) => {
43 $(
44 impl DebugStrictSub for $ty {
45 fn debug_strict_sub(self, other: Self) -> Self {
46 if cfg!(debug_assertions) {
47 self - other
48 } else {
49 self.wrapping_sub(other)
50 }
51 }
52 }
53 )*
54 };
55}
56
57impl_debug_strict_add! {
58 u8 u16 u32 u64 u128 usize
59 i8 i16 i32 i64 i128 isize
60}
61
62impl_debug_strict_sub! {
63 u8 u16 u32 u64 u128 usize
64 i8 i16 i32 i64 i128 isize
65}