1
1
use clippy_utils:: { numeric_literal:: NumericLiteral , source:: snippet} ;
2
- use rustc_ast:: LitKind ;
3
2
use rustc_errors:: Applicability ;
4
3
use rustc_hir:: { BinOpKind , Expr , ExprKind , Lit } ;
5
- use rustc_lint:: { LateContext , LateLintPass } ;
4
+ use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
5
+ use rustc_middle:: lint:: in_external_macro;
6
6
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
7
7
8
8
declare_clippy_lint ! {
@@ -27,61 +27,26 @@ declare_lint_pass!(ConfusingXorAndPow => [SUSPICIOUS_XOR]);
27
27
28
28
impl LateLintPass < ' _ > for ConfusingXorAndPow {
29
29
fn check_expr ( & mut self , cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) {
30
- if_chain ! {
31
- if let ExprKind :: Binary ( op, left, right) = & expr. kind;
32
- if op. node == BinOpKind :: BitXor ;
33
- if let ExprKind :: Lit ( litr) = & right. kind;
34
- if let ExprKind :: Lit ( litl) = & left. kind;
35
- if let snip_left = snippet( cx, litl. span, ".." ) ;
36
- if let snip_right = snippet( cx, litr. span, ".." ) ;
37
- if get_numlit( litr, & snip_right)
38
- . zip( get_numlit( litl, & snip_left) )
39
- . map_or( false , |( a, b) | a. is_decimal( ) && b. is_decimal( ) ) ;
40
- if let left_val = unwrap_lit_to_dec( left) . unwrap_or( 0 ) ;
41
- if let right_val = unwrap_lit_to_dec( right) . unwrap_or( 0 ) ;
42
- if let suffix = get_numlit( litr, & snip_right) . unwrap( ) . suffix. unwrap_or( "" ) ;
43
- then {
44
-
45
- if left_val == 2 &&
46
- ( right_val == 8 ||
47
- right_val == 16 ||
48
- right_val == 32 ||
49
- right_val == 64 || right_val == 128 )
50
- {
51
- clippy_utils:: diagnostics:: span_lint_and_sugg(
52
- cx,
53
- SUSPICIOUS_XOR ,
54
- expr. span,
55
- "it appears that you are trying to get the maximum value of an integer, but '^' is not exponentiation operator" ,
56
- "try with" ,
57
- format!( "u{right_val}::MAX" ) ,
58
- Applicability :: MaybeIncorrect ,
59
- ) ;
60
- } else {
61
- // Even then, warn always.
62
- clippy_utils:: diagnostics:: span_lint_and_sugg(
63
- cx,
64
- SUSPICIOUS_XOR ,
65
- expr. span,
66
- "'^' is not the exponentiation operator" ,
67
- "did you mean to write" ,
68
- format!( "{left_val}{suffix}.pow({right_val})" ) ,
69
- Applicability :: MaybeIncorrect ,
70
- ) ;
71
- }
72
-
73
- }
74
- }
75
- }
76
- }
77
-
78
- fn unwrap_lit_to_dec ( expr : & Expr < ' _ > ) -> Option < u128 > {
79
- match & expr. kind {
80
- ExprKind :: Lit ( lit) => match lit. node {
81
- LitKind :: Int ( num, _) => Some ( num) ,
82
- _ => None ,
83
- } ,
84
- _ => None ,
30
+ if !in_external_macro ( cx. sess ( ) , expr. span ) &&
31
+ let ExprKind :: Binary ( op, left, right) = & expr. kind &&
32
+ op. node == BinOpKind :: BitXor &&
33
+ let ExprKind :: Lit ( lit_left) = & left. kind &&
34
+ let ExprKind :: Lit ( lit_right) = & right. kind &&
35
+ let snip_left = snippet ( cx, lit_left. span , ".." ) &&
36
+ let snip_right = snippet ( cx, lit_right. span , ".." ) &&
37
+ let Some ( left_val) = get_numlit ( lit_left, & snip_left) &&
38
+ let Some ( right_val) = get_numlit ( lit_right, & snip_right) &&
39
+ left_val. is_decimal ( ) && right_val. is_decimal ( ) {
40
+ clippy_utils:: diagnostics:: span_lint_and_sugg (
41
+ cx,
42
+ SUSPICIOUS_XOR ,
43
+ expr. span ,
44
+ "'^' is not the exponentiation operator" ,
45
+ "did you mean to write" ,
46
+ format ! ( "{}.pow({})" , left_val. format( ) , right_val. format( ) ) ,
47
+ Applicability :: MaybeIncorrect ,
48
+ ) ;
49
+ }
85
50
}
86
51
}
87
52
0 commit comments