1+ use clippy_config:: Conf ;
12use clippy_utils:: diagnostics:: span_lint_and_sugg;
3+ use clippy_utils:: msrvs:: { self , Msrv } ;
24use clippy_utils:: sugg:: Sugg ;
3- use clippy_utils:: { SpanlessEq , is_integer_literal} ;
5+ use clippy_utils:: { SpanlessEq , is_in_const_context , is_integer_literal} ;
46use rustc_errors:: Applicability ;
57use rustc_hir:: { BinOpKind , Expr , ExprKind } ;
68use rustc_lint:: { LateContext , LateLintPass } ;
79use rustc_middle:: ty;
8- use rustc_session:: declare_lint_pass ;
10+ use rustc_session:: impl_lint_pass ;
911
1012declare_clippy_lint ! {
1113 /// ### What it does
@@ -31,7 +33,36 @@ declare_clippy_lint! {
3133 "manually reimplementing `is_power_of_two`"
3234}
3335
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+ }
3566
3667impl < ' tcx > LateLintPass < ' tcx > for ManualIsPowerOfTwo {
3768 fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & Expr < ' tcx > ) {
@@ -41,39 +72,24 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsPowerOfTwo {
4172 if let Some ( a) = count_ones_receiver ( cx, lhs)
4273 && is_integer_literal ( rhs, 1 )
4374 {
44- build_sugg ( cx, expr, a) ;
75+ self . build_sugg ( cx, expr, a) ;
4576 } else if let Some ( a) = count_ones_receiver ( cx, rhs)
4677 && is_integer_literal ( lhs, 1 )
4778 {
48- build_sugg ( cx, expr, a) ;
79+ self . build_sugg ( cx, expr, a) ;
4980 } else if is_integer_literal ( rhs, 0 )
5081 && let Some ( a) = is_and_minus_one ( cx, lhs)
5182 {
52- build_sugg ( cx, expr, a) ;
83+ self . build_sugg ( cx, expr, a) ;
5384 } else if is_integer_literal ( lhs, 0 )
5485 && let Some ( a) = is_and_minus_one ( cx, rhs)
5586 {
56- build_sugg ( cx, expr, a) ;
87+ self . build_sugg ( cx, expr, a) ;
5788 }
5889 }
5990 }
6091}
6192
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-
7793/// Return the unsigned integer receiver of `.count_ones()`
7894fn count_ones_receiver < ' tcx > ( cx : & LateContext < ' tcx > , expr : & Expr < ' tcx > ) -> Option < & ' tcx Expr < ' tcx > > {
7995 if let ExprKind :: MethodCall ( method_name, receiver, [ ] , _) = expr. kind
0 commit comments