1 #![warn(clippy::suspicious_arithmetic_impl)]
2 use std::ops::{
3 Add, AddAssign, BitAnd, BitOr, BitOrAssign, BitXor, Div, DivAssign, Mul, MulAssign, Rem, Shl, Shr, Sub,
4 };
5
6 #[derive(Copy, Clone)]
7 struct Foo(u32);
8
9 impl Add for Foo {
10 type Output = Foo;
11
add(self, other: Self) -> Self12 fn add(self, other: Self) -> Self {
13 Foo(self.0 - other.0)
14 }
15 }
16
17 impl AddAssign for Foo {
add_assign(&mut self, other: Foo)18 fn add_assign(&mut self, other: Foo) {
19 *self = *self - other;
20 }
21 }
22
23 impl BitOrAssign for Foo {
bitor_assign(&mut self, other: Foo)24 fn bitor_assign(&mut self, other: Foo) {
25 let idx = other.0;
26 self.0 |= 1 << idx; // OK: BinOpKind::Shl part of AssignOp as child node
27 }
28 }
29
30 impl MulAssign for Foo {
mul_assign(&mut self, other: Foo)31 fn mul_assign(&mut self, other: Foo) {
32 self.0 /= other.0;
33 }
34 }
35
36 impl DivAssign for Foo {
div_assign(&mut self, other: Foo)37 fn div_assign(&mut self, other: Foo) {
38 self.0 /= other.0; // OK: BinOpKind::Div == DivAssign
39 }
40 }
41
42 impl Mul for Foo {
43 type Output = Foo;
44
mul(self, other: Foo) -> Foo45 fn mul(self, other: Foo) -> Foo {
46 Foo(self.0 * other.0 % 42) // OK: BinOpKind::Rem part of BiExpr as parent node
47 }
48 }
49
50 impl Sub for Foo {
51 type Output = Foo;
52
sub(self, other: Self) -> Self53 fn sub(self, other: Self) -> Self {
54 Foo(self.0 * other.0 - 42) // OK: BinOpKind::Mul part of BiExpr as child node
55 }
56 }
57
58 impl Div for Foo {
59 type Output = Foo;
60
div(self, other: Self) -> Self61 fn div(self, other: Self) -> Self {
62 Foo(do_nothing(self.0 + other.0) / 42) // OK: BinOpKind::Add part of BiExpr as child node
63 }
64 }
65
66 impl Rem for Foo {
67 type Output = Foo;
68
rem(self, other: Self) -> Self69 fn rem(self, other: Self) -> Self {
70 Foo(self.0 / other.0)
71 }
72 }
73
74 impl BitAnd for Foo {
75 type Output = Foo;
76
bitand(self, other: Self) -> Self77 fn bitand(self, other: Self) -> Self {
78 Foo(self.0 | other.0)
79 }
80 }
81
82 impl BitOr for Foo {
83 type Output = Foo;
84
bitor(self, other: Self) -> Self85 fn bitor(self, other: Self) -> Self {
86 Foo(self.0 ^ other.0)
87 }
88 }
89
90 impl BitXor for Foo {
91 type Output = Foo;
92
bitxor(self, other: Self) -> Self93 fn bitxor(self, other: Self) -> Self {
94 Foo(self.0 & other.0)
95 }
96 }
97
98 impl Shl for Foo {
99 type Output = Foo;
100
shl(self, other: Self) -> Self101 fn shl(self, other: Self) -> Self {
102 Foo(self.0 >> other.0)
103 }
104 }
105
106 impl Shr for Foo {
107 type Output = Foo;
108
shr(self, other: Self) -> Self109 fn shr(self, other: Self) -> Self {
110 Foo(self.0 << other.0)
111 }
112 }
113
114 struct Bar(i32);
115
116 impl Add for Bar {
117 type Output = Bar;
118
add(self, other: Self) -> Self119 fn add(self, other: Self) -> Self {
120 Bar(self.0 & !other.0) // OK: Not part of BiExpr as child node
121 }
122 }
123
124 impl Sub for Bar {
125 type Output = Bar;
126
sub(self, other: Self) -> Self127 fn sub(self, other: Self) -> Self {
128 if self.0 <= other.0 {
129 Bar(-(self.0 & other.0)) // OK: Neg part of BiExpr as parent node
130 } else {
131 Bar(0)
132 }
133 }
134 }
135
main()136 fn main() {}
137
do_nothing(x: u32) -> u32138 fn do_nothing(x: u32) -> u32 {
139 x
140 }
141
142 struct MultipleBinops(u32);
143
144 impl Add for MultipleBinops {
145 type Output = MultipleBinops;
146
147 // OK: multiple Binops in `add` impl
add(self, other: Self) -> Self::Output148 fn add(self, other: Self) -> Self::Output {
149 let mut result = self.0 + other.0;
150 if result >= u32::max_value() {
151 result -= u32::max_value();
152 }
153 MultipleBinops(result)
154 }
155 }
156
157 impl Mul for MultipleBinops {
158 type Output = MultipleBinops;
159
160 // OK: multiple Binops in `mul` impl
mul(self, other: Self) -> Self::Output161 fn mul(self, other: Self) -> Self::Output {
162 let mut result: u32 = 0;
163 let size = std::cmp::max(self.0, other.0) as usize;
164 let mut v = vec![0; size + 1];
165 for i in 0..size + 1 {
166 result *= i as u32;
167 }
168 MultipleBinops(result)
169 }
170 }
171