@@ -16,8 +16,9 @@ const HARD_CODED_ALLOWED: &[&str] = &[
1616 "f32" ,
1717 "f64" ,
1818 "std::num::Saturating" ,
19- "std::string::String" ,
2019 "std::num::Wrapping" ,
20+ "std::string::String" ,
21+ "&str" ,
2122] ;
2223
2324#[ derive( Debug ) ]
@@ -77,6 +78,11 @@ impl ArithmeticSideEffects {
7778 )
7879 }
7980
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+
8086 // Common entry-point to avoid code duplication.
8187 fn issue_lint ( & mut self , cx : & LateContext < ' _ > , expr : & hir:: Expr < ' _ > ) {
8288 let msg = "arithmetic operation that can potentially result in unexpected side-effects" ;
@@ -88,24 +94,13 @@ impl ArithmeticSideEffects {
8894 /// * Is `expr` is a literal integer reference like `&199`, returns the literal integer without
8995 /// references.
9096 /// * 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 > > {
10198 if matches ! ( expr. kind, hir:: ExprKind :: Lit ( _) ) {
10299 return Some ( expr) ;
103100 }
104-
105101 if let hir:: ExprKind :: AddrOf ( .., inn) = expr. kind && let hir:: ExprKind :: Lit ( _) = inn. kind {
106102 return Some ( inn)
107103 }
108-
109104 None
110105 }
111106
@@ -134,14 +129,18 @@ impl ArithmeticSideEffects {
134129 ) {
135130 return ;
136131 } ;
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) {
138133 return ;
139134 }
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
145144 } ;
146145 if !has_valid_op {
147146 self . issue_lint ( cx, expr) ;
0 commit comments