1
1
use rustc:: lint:: { LateContext , LateLintPass , LintArray , LintPass } ;
2
2
use rustc:: hir:: def:: Def ;
3
3
use rustc:: hir:: { BiAnd , BiOr , BlockCheckMode , Expr , Expr_ , Stmt , StmtSemi , UnsafeSource } ;
4
- use utils:: { in_macro, snippet_opt, span_lint, span_lint_and_sugg} ;
4
+ use utils:: { in_macro, snippet_opt, span_lint, span_lint_and_sugg, has_drop } ;
5
5
use std:: ops:: Deref ;
6
6
7
7
/// **What it does:** Checks for statements which have no effect.
@@ -45,7 +45,8 @@ fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool {
45
45
return false ;
46
46
}
47
47
match expr. node {
48
- Expr_ :: ExprLit ( ..) | Expr_ :: ExprClosure ( .., _) | Expr_ :: ExprPath ( ..) => true ,
48
+ Expr_ :: ExprLit ( ..) | Expr_ :: ExprClosure ( .., _) => true ,
49
+ Expr_ :: ExprPath ( ..) => !has_drop ( cx, expr) ,
49
50
Expr_ :: ExprIndex ( ref a, ref b) | Expr_ :: ExprBinary ( _, ref a, ref b) => {
50
51
has_no_effect ( cx, a) && has_no_effect ( cx, b)
51
52
} ,
@@ -59,7 +60,7 @@ fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool {
59
60
Expr_ :: ExprAddrOf ( _, ref inner) |
60
61
Expr_ :: ExprBox ( ref inner) => has_no_effect ( cx, inner) ,
61
62
Expr_ :: ExprStruct ( _, ref fields, ref base) => {
62
- fields. iter ( ) . all ( |field| has_no_effect ( cx, & field. expr ) ) && match * base {
63
+ ! has_drop ( cx , expr ) && fields. iter ( ) . all ( |field| has_no_effect ( cx, & field. expr ) ) && match * base {
63
64
Some ( ref base) => has_no_effect ( cx, base) ,
64
65
None => true ,
65
66
}
@@ -68,7 +69,7 @@ fn has_no_effect(cx: &LateContext, expr: &Expr) -> bool {
68
69
let def = cx. tables . qpath_def ( qpath, callee. hir_id ) ;
69
70
match def {
70
71
Def :: Struct ( ..) | Def :: Variant ( ..) | Def :: StructCtor ( ..) | Def :: VariantCtor ( ..) => {
71
- args. iter ( ) . all ( |arg| has_no_effect ( cx, arg) )
72
+ ! has_drop ( cx , expr ) && args. iter ( ) . all ( |arg| has_no_effect ( cx, arg) )
72
73
} ,
73
74
_ => false ,
74
75
}
@@ -145,18 +146,23 @@ fn reduce_expression<'a>(cx: &LateContext, expr: &'a Expr) -> Option<Vec<&'a Exp
145
146
Expr_ :: ExprTupField ( ref inner, _) |
146
147
Expr_ :: ExprAddrOf ( _, ref inner) |
147
148
Expr_ :: ExprBox ( ref inner) => reduce_expression ( cx, inner) . or_else ( || Some ( vec ! [ inner] ) ) ,
148
- Expr_ :: ExprStruct ( _, ref fields, ref base) => Some (
149
- fields
150
- . iter ( )
151
- . map ( |f| & f. expr )
152
- . chain ( base)
153
- . map ( Deref :: deref)
154
- . collect ( ) ,
155
- ) ,
149
+ Expr_ :: ExprStruct ( _, ref fields, ref base) => {
150
+ if has_drop ( cx, expr) {
151
+ None
152
+ } else {
153
+ Some (
154
+ fields
155
+ . iter ( )
156
+ . map ( |f| & f. expr )
157
+ . chain ( base)
158
+ . map ( Deref :: deref)
159
+ . collect ( ) )
160
+ }
161
+ } ,
156
162
Expr_ :: ExprCall ( ref callee, ref args) => if let Expr_ :: ExprPath ( ref qpath) = callee. node {
157
163
let def = cx. tables . qpath_def ( qpath, callee. hir_id ) ;
158
164
match def {
159
- Def :: Struct ( ..) | Def :: Variant ( ..) | Def :: StructCtor ( ..) | Def :: VariantCtor ( ..) => {
165
+ Def :: Struct ( ..) | Def :: Variant ( ..) | Def :: StructCtor ( ..) | Def :: VariantCtor ( ..) if ! has_drop ( cx , expr ) => {
160
166
Some ( args. iter ( ) . collect ( ) )
161
167
} ,
162
168
_ => None ,
0 commit comments