1
- #![ allow(
2
- // False positive
3
- clippy:: match_same_arms
4
- ) ]
5
-
6
1
use super :: ARITHMETIC_SIDE_EFFECTS ;
7
2
use clippy_utils:: { consts:: constant_simple, diagnostics:: span_lint} ;
8
3
use rustc_ast as ast;
@@ -14,12 +9,12 @@ use rustc_session::impl_lint_pass;
14
9
use rustc_span:: source_map:: { Span , Spanned } ;
15
10
16
11
const HARD_CODED_ALLOWED : & [ & str ] = & [
12
+ "&str" ,
17
13
"f32" ,
18
14
"f64" ,
19
15
"std::num::Saturating" ,
20
16
"std::num::Wrapping" ,
21
17
"std::string::String" ,
22
- "&str" ,
23
18
] ;
24
19
25
20
#[ derive( Debug ) ]
@@ -79,16 +74,13 @@ impl ArithmeticSideEffects {
79
74
self . expr_span = Some ( expr. span ) ;
80
75
}
81
76
82
- /// * If `expr` is a literal integer like `1` or `i32::MAX`, returns itself.
83
- /// * Is `expr` is a literal integer reference like `&199`, returns the literal integer without
84
- /// references.
85
- /// * If `expr` is anything else, returns `None`.
86
- fn literal_integer < ' expr , ' tcx > ( expr : & ' expr hir:: Expr < ' tcx > ) -> Option < & ' expr hir:: Expr < ' tcx > > {
77
+ /// If `expr` does not match any variant of [LiteralIntegerTy], returns `None`.
78
+ fn literal_integer < ' expr , ' tcx > ( expr : & ' expr hir:: Expr < ' tcx > ) -> Option < LiteralIntegerTy < ' expr , ' tcx > > {
87
79
if matches ! ( expr. kind, hir:: ExprKind :: Lit ( _) ) {
88
- return Some ( expr) ;
80
+ return Some ( LiteralIntegerTy :: Value ( expr) ) ;
89
81
}
90
82
if let hir:: ExprKind :: AddrOf ( .., inn) = expr. kind && let hir:: ExprKind :: Lit ( _) = inn. kind {
91
- return Some ( inn)
83
+ return Some ( LiteralIntegerTy :: Ref ( inn) ) ;
92
84
}
93
85
None
94
86
}
@@ -127,9 +119,10 @@ impl ArithmeticSideEffects {
127
119
let has_valid_op = if Self :: is_integral ( lhs_ty) && Self :: is_integral ( rhs_ty) {
128
120
match ( Self :: literal_integer ( lhs) , Self :: literal_integer ( rhs) ) {
129
121
( None , None ) => false ,
130
- ( None , Some ( local_expr) ) => Self :: has_valid_op ( op, local_expr) ,
131
- ( Some ( local_expr) , None ) => Self :: has_valid_op ( op, local_expr) ,
132
- ( Some ( _) , Some ( _) ) => true ,
122
+ ( None , Some ( lit_int_ty) ) => Self :: has_valid_op ( op, lit_int_ty. into ( ) ) ,
123
+ ( Some ( lit_int_ty) , None ) => Self :: has_valid_op ( op, lit_int_ty. into ( ) ) ,
124
+ ( Some ( LiteralIntegerTy :: Value ( _) ) , Some ( LiteralIntegerTy :: Value ( _) ) ) => true ,
125
+ ( Some ( _) , Some ( _) ) => false ,
133
126
}
134
127
} else {
135
128
false
@@ -186,3 +179,23 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
186
179
}
187
180
}
188
181
}
182
+
183
+ /// Tells if an expression is a integer passed by value or by reference.
184
+ ///
185
+ /// If [LiteralIntegerTy::Ref], then the contained value will be `hir::ExprKind::Lit` rather
186
+ /// than `hirExprKind::Addr`.
187
+ enum LiteralIntegerTy < ' expr , ' tcx > {
188
+ /// For example, `&199`
189
+ Ref ( & ' expr hir:: Expr < ' tcx > ) ,
190
+ /// For example, `1` or `i32::MAX`
191
+ Value ( & ' expr hir:: Expr < ' tcx > ) ,
192
+ }
193
+
194
+ impl < ' expr , ' tcx > From < LiteralIntegerTy < ' expr , ' tcx > > for & ' expr hir:: Expr < ' tcx > {
195
+ fn from ( from : LiteralIntegerTy < ' expr , ' tcx > ) -> Self {
196
+ match from {
197
+ LiteralIntegerTy :: Ref ( elem) => elem,
198
+ LiteralIntegerTy :: Value ( elem) => elem,
199
+ }
200
+ }
201
+ }
0 commit comments