@@ -87,6 +87,10 @@ impl<'tcx> LateLintPass<'tcx> for NoEffect {
8787
8888fn check_no_effect ( cx : & LateContext < ' _ > , stmt : & Stmt < ' _ > ) -> bool {
8989 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+ }
9094 if has_no_effect ( cx, expr) {
9195 span_lint_hir_and_then (
9296 cx,
@@ -153,6 +157,61 @@ fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
153157 false
154158}
155159
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+
156215fn has_no_effect ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) -> bool {
157216 if expr. span . from_expansion ( ) {
158217 return false ;
0 commit comments