@@ -16,8 +16,9 @@ const HARD_CODED_ALLOWED: &[&str] = &[
16
16
"f32" ,
17
17
"f64" ,
18
18
"std::num::Saturating" ,
19
- "std::string::String" ,
20
19
"std::num::Wrapping" ,
20
+ "std::string::String" ,
21
+ "&str" ,
21
22
] ;
22
23
23
24
#[ derive( Debug ) ]
@@ -77,6 +78,11 @@ impl ArithmeticSideEffects {
77
78
)
78
79
}
79
80
81
+ // For example, 8i32 or &i64::MAX.
82
+ fn is_integral < ' expr , ' tcx > ( cx : & LateContext < ' tcx > , expr : & ' expr hir:: Expr < ' tcx > ) -> bool {
83
+ cx. typeck_results ( ) . expr_ty ( expr) . peel_refs ( ) . is_integral ( )
84
+ }
85
+
80
86
// Common entry-point to avoid code duplication.
81
87
fn issue_lint ( & mut self , cx : & LateContext < ' _ > , expr : & hir:: Expr < ' _ > ) {
82
88
let msg = "arithmetic operation that can potentially result in unexpected side-effects" ;
@@ -88,24 +94,13 @@ impl ArithmeticSideEffects {
88
94
/// * Is `expr` is a literal integer reference like `&199`, returns the literal integer without
89
95
/// references.
90
96
/// * If `expr` is anything else, returns `None`.
91
- fn literal_integer < ' expr , ' tcx > (
92
- cx : & LateContext < ' tcx > ,
93
- expr : & ' expr hir:: Expr < ' tcx > ,
94
- ) -> Option < & ' expr hir:: Expr < ' tcx > > {
95
- let expr_refs = cx. typeck_results ( ) . expr_ty ( expr) . peel_refs ( ) ;
96
-
97
- if !expr_refs. is_integral ( ) {
98
- return None ;
99
- }
100
-
97
+ fn literal_integer < ' expr , ' tcx > ( expr : & ' expr hir:: Expr < ' tcx > ) -> Option < & ' expr hir:: Expr < ' tcx > > {
101
98
if matches ! ( expr. kind, hir:: ExprKind :: Lit ( _) ) {
102
99
return Some ( expr) ;
103
100
}
104
-
105
101
if let hir:: ExprKind :: AddrOf ( .., inn) = expr. kind && let hir:: ExprKind :: Lit ( _) = inn. kind {
106
102
return Some ( inn)
107
103
}
108
-
109
104
None
110
105
}
111
106
@@ -134,14 +129,18 @@ impl ArithmeticSideEffects {
134
129
) {
135
130
return ;
136
131
} ;
137
- if self . is_allowed_ty ( cx, lhs) || self . is_allowed_ty ( cx, rhs) {
132
+ if self . is_allowed_ty ( cx, lhs) && self . is_allowed_ty ( cx, rhs) {
138
133
return ;
139
134
}
140
- let has_valid_op = match ( Self :: literal_integer ( cx, lhs) , Self :: literal_integer ( cx, rhs) ) {
141
- ( None , None ) => false ,
142
- ( None , Some ( local_expr) ) => Self :: has_valid_op ( op, local_expr) ,
143
- ( Some ( local_expr) , None ) => Self :: has_valid_op ( op, local_expr) ,
144
- ( Some ( _) , Some ( _) ) => true ,
135
+ let has_valid_op = if Self :: is_integral ( cx, lhs) && Self :: is_integral ( cx, rhs) {
136
+ match ( Self :: literal_integer ( lhs) , Self :: literal_integer ( rhs) ) {
137
+ ( None , None ) => false ,
138
+ ( None , Some ( local_expr) ) => Self :: has_valid_op ( op, local_expr) ,
139
+ ( Some ( local_expr) , None ) => Self :: has_valid_op ( op, local_expr) ,
140
+ ( Some ( _) , Some ( _) ) => true ,
141
+ }
142
+ } else {
143
+ false
145
144
} ;
146
145
if !has_valid_op {
147
146
self . issue_lint ( cx, expr) ;
0 commit comments