clippy_utilities/
arithmetic.rs1use crate::conversion::NumericCast;
4use std::any::type_name;
5
6macro_rules! impl_overflow_arithmetic {
8 ($target: ty) => {
9 #[allow(clippy::use_self)]
10 impl OverflowArithmetic for $target {
11 #[inline]
12 fn overflow_add(self, other: Self) -> Self {
13 let (res, overflow) = self.overflowing_add(other);
14 assert!(
15 !overflow,
16 "number = {}({}) add number = {}({}) overflowed",
17 self,
18 type_name::<Self>(),
19 other,
20 type_name::<Self>()
21 );
22 res
23 }
24
25 #[inline]
26 fn overflow_sub(self, other: Self) -> Self {
27 let (res, overflow) = self.overflowing_sub(other);
28 assert!(
29 !overflow,
30 "number = {}({}) substract number = {}({}) overflowed",
31 self,
32 type_name::<Self>(),
33 other,
34 type_name::<Self>()
35 );
36 res
37 }
38
39 #[inline]
40 fn overflow_mul(self, other: Self) -> Self {
41 let (res, overflow) = self.overflowing_mul(other);
42 assert!(
43 !overflow,
44 "number = {}({}) multiply number = {}({}) overflowed",
45 self,
46 type_name::<Self>(),
47 other,
48 type_name::<Self>()
49 );
50 res
51 }
52
53 #[inline]
54 fn overflow_div(self, other: Self) -> Self {
55 let (res, overflow) = self.overflowing_div(other);
56 assert!(
57 !overflow,
58 "number = {}({}) divide number = {}({}) overflowed",
59 self,
60 type_name::<Self>(),
61 other,
62 type_name::<Self>()
63 );
64 res
65 }
66
67 #[inline]
68 fn overflow_shl(self, other: Self) -> Self {
69 let (res, overflow) = self.overflowing_shl(other.numeric_cast());
70 assert!(
71 !overflow,
72 "number = {}({}) left shift number = {}({}) overflowed",
73 self,
74 type_name::<Self>(),
75 other,
76 type_name::<Self>()
77 );
78 res
79 }
80
81 #[inline]
82 fn overflow_shr(self, other: Self) -> Self {
83 let (res, overflow) = self.overflowing_shr(other.numeric_cast());
84 assert!(
85 !overflow,
86 "number = {}({}) right shift number = {}({}) overflowed",
87 self,
88 type_name::<Self>(),
89 other,
90 type_name::<Self>()
91 );
92 res
93 }
94
95 #[inline]
96 fn overflow_neg(self) -> Self {
97 let (res, overflow) = self.overflowing_neg();
98 assert!(
99 !overflow,
100 "number = {}({}) negate overflowed",
101 self,
102 type_name::<Self>(),
103 );
104 res
105 }
106
107 #[inline]
108 fn overflow_rem(self, other: Self) -> Self {
109 let (res, overflow) = self.overflowing_rem(other.numeric_cast());
110 assert!(
111 !overflow,
112 "number = {}({}) remainder number = {}({}) overflowed",
113 self,
114 type_name::<Self>(),
115 other,
116 type_name::<Self>()
117 );
118 res
119 }
120 }
121 };
122}
123
124impl_overflow_arithmetic!(u8);
125impl_overflow_arithmetic!(u16);
126impl_overflow_arithmetic!(u32);
127impl_overflow_arithmetic!(u64);
128impl_overflow_arithmetic!(u128);
129impl_overflow_arithmetic!(i8);
130impl_overflow_arithmetic!(i16);
131impl_overflow_arithmetic!(i32);
132impl_overflow_arithmetic!(i64);
133impl_overflow_arithmetic!(i128);
134impl_overflow_arithmetic!(usize);
135impl_overflow_arithmetic!(isize);
136
137pub trait OverflowArithmetic {
139 #[must_use]
141 fn overflow_add(self, other: Self) -> Self;
142
143 #[must_use]
145 fn overflow_sub(self, other: Self) -> Self;
146
147 #[must_use]
149 fn overflow_mul(self, other: Self) -> Self;
150
151 #[must_use]
153 fn overflow_div(self, other: Self) -> Self;
154
155 #[must_use]
157 fn overflow_shl(self, other: Self) -> Self;
158
159 #[must_use]
161 fn overflow_shr(self, other: Self) -> Self;
162
163 #[must_use]
165 fn overflow_neg(self) -> Self;
166
167 #[must_use]
169 fn overflow_rem(self, other: Self) -> Self;
170}