@@ -87,6 +87,10 @@ impl<'tcx> LateLintPass<'tcx> for NoEffect {
87
87
88
88
fn check_no_effect ( cx : & LateContext < ' _ > , stmt : & Stmt < ' _ > ) -> bool {
89
89
if let StmtKind :: Semi ( expr) = stmt. kind {
90
+ // assume nontrivial oprand of `Binary` Expr can skip `check_unnecessary_operation`
91
+ if has_nontrivial_oprand ( expr) {
92
+ return true ;
93
+ }
90
94
if has_no_effect ( cx, expr) {
91
95
span_lint_hir_and_then (
92
96
cx,
@@ -153,6 +157,61 @@ fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
153
157
false
154
158
}
155
159
160
+ fn has_nontrivial_oprand ( expr : & Expr < ' _ > ) -> bool {
161
+ if expr. span . from_expansion ( ) {
162
+ return false ;
163
+ }
164
+ return match peel_blocks ( expr) . kind {
165
+ ExprKind :: Binary ( _, lhs, rhs) => !check_nontrivial_operand ( lhs, rhs) ,
166
+ _ => false ,
167
+ } ;
168
+ }
169
+
170
+ fn check_nontrivial_operand ( lhs : & Expr < ' _ > , rhs : & Expr < ' _ > ) -> bool {
171
+ // It's seem that impossable to check whether operator is overrided through context of this lint,
172
+ // so, this function assume user-defined binary operator is overrided with an side-effect.
173
+ // The definition of user-defined structure here is `tuple`, `array`, `struct`,
174
+ // it looks like a little bit simple, but useful.
175
+ // Althrough this will weaken the ability of this lint,
176
+ // less miss lint-fix happen.
177
+
178
+ // a closure to check whether expr belongs to user-defined structure
179
+ let closure = |expr : & Expr < ' _ > | -> bool {
180
+ match & expr. kind {
181
+ // check whether expr is a user-defined sturcture
182
+ ExprKind :: Tup ( ..) | ExprKind :: Array ( ..) | ExprKind :: Struct ( ..) => true ,
183
+ // resolve expr's path
184
+ ExprKind :: Path ( rustc_hir:: QPath :: Resolved (
185
+ _,
186
+ rustc_hir:: Path {
187
+ span : _,
188
+ res,
189
+ segments : _,
190
+ } ,
191
+ ) ) => {
192
+ match res {
193
+ Res :: Def ( defkind, _) => match defkind {
194
+ // user-defined
195
+ DefKind :: Struct | DefKind :: Ctor ( _, _) => true ,
196
+ _ => false ,
197
+ } ,
198
+ _ => false ,
199
+ } ;
200
+ false
201
+ } ,
202
+ _ => false ,
203
+ }
204
+ } ;
205
+
206
+ let lhs_ud = closure ( lhs) ;
207
+ let rhs_ud = closure ( rhs) ;
208
+ // one of lhs or rhs is user-defined structure
209
+ if lhs_ud || rhs_ud {
210
+ return false ;
211
+ }
212
+ true
213
+ }
214
+
156
215
fn has_no_effect ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) -> bool {
157
216
if expr. span . from_expansion ( ) {
158
217
return false ;
0 commit comments