1
+ use clippy_config:: Conf ;
1
2
use clippy_utils:: diagnostics:: span_lint_and_sugg;
3
+ use clippy_utils:: msrvs:: { self , Msrv } ;
2
4
use clippy_utils:: sugg:: Sugg ;
3
- use clippy_utils:: { SpanlessEq , is_integer_literal} ;
5
+ use clippy_utils:: { SpanlessEq , is_in_const_context , is_integer_literal} ;
4
6
use rustc_errors:: Applicability ;
5
7
use rustc_hir:: { BinOpKind , Expr , ExprKind } ;
6
8
use rustc_lint:: { LateContext , LateLintPass } ;
7
9
use rustc_middle:: ty;
8
- use rustc_session:: declare_lint_pass ;
10
+ use rustc_session:: impl_lint_pass ;
9
11
10
12
declare_clippy_lint ! {
11
13
/// ### What it does
@@ -31,7 +33,36 @@ declare_clippy_lint! {
31
33
"manually reimplementing `is_power_of_two`"
32
34
}
33
35
34
- declare_lint_pass ! ( ManualIsPowerOfTwo => [ MANUAL_IS_POWER_OF_TWO ] ) ;
36
+ pub struct ManualIsPowerOfTwo {
37
+ msrv : Msrv ,
38
+ }
39
+
40
+ impl_lint_pass ! ( ManualIsPowerOfTwo => [ MANUAL_IS_POWER_OF_TWO ] ) ;
41
+
42
+ impl ManualIsPowerOfTwo {
43
+ pub fn new ( conf : & ' static Conf ) -> Self {
44
+ Self { msrv : conf. msrv }
45
+ }
46
+
47
+ fn build_sugg ( & self , cx : & LateContext < ' _ > , expr : & Expr < ' _ > , receiver : & Expr < ' _ > ) {
48
+ if is_in_const_context ( cx) && !self . msrv . meets ( cx, msrvs:: CONST_IS_POWER_OF_TWO ) {
49
+ return ;
50
+ }
51
+
52
+ let mut applicability = Applicability :: MachineApplicable ;
53
+ let snippet = Sugg :: hir_with_applicability ( cx, receiver, "_" , & mut applicability) ;
54
+
55
+ span_lint_and_sugg (
56
+ cx,
57
+ MANUAL_IS_POWER_OF_TWO ,
58
+ expr. span ,
59
+ "manually reimplementing `is_power_of_two`" ,
60
+ "consider using `.is_power_of_two()`" ,
61
+ format ! ( "{}.is_power_of_two()" , snippet. maybe_paren( ) ) ,
62
+ applicability,
63
+ ) ;
64
+ }
65
+ }
35
66
36
67
impl < ' tcx > LateLintPass < ' tcx > for ManualIsPowerOfTwo {
37
68
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & Expr < ' tcx > ) {
@@ -41,39 +72,24 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsPowerOfTwo {
41
72
if let Some ( a) = count_ones_receiver ( cx, lhs)
42
73
&& is_integer_literal ( rhs, 1 )
43
74
{
44
- build_sugg ( cx, expr, a) ;
75
+ self . build_sugg ( cx, expr, a) ;
45
76
} else if let Some ( a) = count_ones_receiver ( cx, rhs)
46
77
&& is_integer_literal ( lhs, 1 )
47
78
{
48
- build_sugg ( cx, expr, a) ;
79
+ self . build_sugg ( cx, expr, a) ;
49
80
} else if is_integer_literal ( rhs, 0 )
50
81
&& let Some ( a) = is_and_minus_one ( cx, lhs)
51
82
{
52
- build_sugg ( cx, expr, a) ;
83
+ self . build_sugg ( cx, expr, a) ;
53
84
} else if is_integer_literal ( lhs, 0 )
54
85
&& let Some ( a) = is_and_minus_one ( cx, rhs)
55
86
{
56
- build_sugg ( cx, expr, a) ;
87
+ self . build_sugg ( cx, expr, a) ;
57
88
}
58
89
}
59
90
}
60
91
}
61
92
62
- fn build_sugg ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , receiver : & Expr < ' _ > ) {
63
- let mut applicability = Applicability :: MachineApplicable ;
64
- let snippet = Sugg :: hir_with_applicability ( cx, receiver, "_" , & mut applicability) ;
65
-
66
- span_lint_and_sugg (
67
- cx,
68
- MANUAL_IS_POWER_OF_TWO ,
69
- expr. span ,
70
- "manually reimplementing `is_power_of_two`" ,
71
- "consider using `.is_power_of_two()`" ,
72
- format ! ( "{}.is_power_of_two()" , snippet. maybe_paren( ) ) ,
73
- applicability,
74
- ) ;
75
- }
76
-
77
93
/// Return the unsigned integer receiver of `.count_ones()`
78
94
fn count_ones_receiver < ' tcx > ( cx : & LateContext < ' tcx > , expr : & Expr < ' tcx > ) -> Option < & ' tcx Expr < ' tcx > > {
79
95
if let ExprKind :: MethodCall ( method_name, receiver, [ ] , _) = expr. kind
0 commit comments