9
9
10
10
11
11
use crate :: utils:: span_lint;
12
- use crate :: rustc:: hir;
12
+ use crate :: rustc:: hir:: { self , Item , ItemKind } ;
13
13
use crate :: rustc:: lint:: { LateContext , LateLintPass , LintArray , LintPass } ;
14
14
use crate :: rustc:: { declare_tool_lint, lint_array} ;
15
15
use crate :: syntax:: source_map:: Span ;
@@ -51,7 +51,8 @@ declare_clippy_lint! {
51
51
52
52
#[ derive( Copy , Clone , Default ) ]
53
53
pub struct Arithmetic {
54
- span : Option < Span > ,
54
+ expr_span : Option < Span > ,
55
+ item_span : Option < Span > ,
55
56
}
56
57
57
58
impl LintPass for Arithmetic {
@@ -62,9 +63,15 @@ impl LintPass for Arithmetic {
62
63
63
64
impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for Arithmetic {
64
65
fn check_expr ( & mut self , cx : & LateContext < ' a , ' tcx > , expr : & ' tcx hir:: Expr ) {
65
- if self . span . is_some ( ) {
66
+ if self . expr_span . is_some ( ) {
66
67
return ;
67
68
}
69
+
70
+ if let Some ( span) = self . item_span {
71
+ if span. contains ( expr. span ) {
72
+ return ;
73
+ }
74
+ }
68
75
match expr. node {
69
76
hir:: ExprKind :: Binary ( ref op, ref l, ref r) => {
70
77
match op. node {
@@ -86,29 +93,47 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic {
86
93
let ( l_ty, r_ty) = ( cx. tables . expr_ty ( l) , cx. tables . expr_ty ( r) ) ;
87
94
if l_ty. is_integral ( ) && r_ty. is_integral ( ) {
88
95
span_lint ( cx, INTEGER_ARITHMETIC , expr. span , "integer arithmetic detected" ) ;
89
- self . span = Some ( expr. span ) ;
96
+ self . expr_span = Some ( expr. span ) ;
90
97
} else if l_ty. is_floating_point ( ) && r_ty. is_floating_point ( ) {
91
98
span_lint ( cx, FLOAT_ARITHMETIC , expr. span , "floating-point arithmetic detected" ) ;
92
- self . span = Some ( expr. span ) ;
99
+ self . expr_span = Some ( expr. span ) ;
93
100
}
94
101
} ,
95
102
hir:: ExprKind :: Unary ( hir:: UnOp :: UnNeg , ref arg) => {
96
103
let ty = cx. tables . expr_ty ( arg) ;
97
104
if ty. is_integral ( ) {
98
105
span_lint ( cx, INTEGER_ARITHMETIC , expr. span , "integer arithmetic detected" ) ;
99
- self . span = Some ( expr. span ) ;
106
+ self . expr_span = Some ( expr. span ) ;
100
107
} else if ty. is_floating_point ( ) {
101
108
span_lint ( cx, FLOAT_ARITHMETIC , expr. span , "floating-point arithmetic detected" ) ;
102
- self . span = Some ( expr. span ) ;
109
+ self . expr_span = Some ( expr. span ) ;
103
110
}
104
111
} ,
105
112
_ => ( ) ,
106
113
}
107
114
}
108
115
109
116
fn check_expr_post ( & mut self , _: & LateContext < ' a , ' tcx > , expr : & ' tcx hir:: Expr ) {
110
- if Some ( expr. span ) == self . span {
111
- self . span = None ;
117
+ if Some ( expr. span ) == self . expr_span {
118
+ self . expr_span = None ;
119
+ }
120
+ }
121
+
122
+ fn check_item ( & mut self , _: & LateContext < ' _ , ' _ > , item : & Item ) {
123
+ match item. node {
124
+ ItemKind :: Enum ( ..)
125
+ | ItemKind :: Const ( ..)
126
+ | ItemKind :: Static ( ..) => self . item_span = Some ( item. span ) ,
127
+ _ => ( ) ,
128
+ }
129
+ }
130
+
131
+ fn check_item_post ( & mut self , _: & LateContext < ' _ , ' _ > , item : & Item ) {
132
+ match item. node {
133
+ ItemKind :: Enum ( ..)
134
+ | ItemKind :: Const ( ..)
135
+ | ItemKind :: Static ( ..) => self . item_span = None ,
136
+ _ => ( ) ,
112
137
}
113
138
}
114
139
}
0 commit comments