@@ -6,6 +6,7 @@ use rustc_hir::Expr;
6
6
use rustc_hir:: ExprKind ;
7
7
use rustc_hir:: PatKind ;
8
8
use rustc_hir:: RangeEnd ;
9
+ use rustc_hir:: UnOp ;
9
10
use rustc_lint:: LintContext ;
10
11
use rustc_lint:: { LateContext , LateLintPass } ;
11
12
use rustc_middle:: lint:: in_external_macro;
@@ -19,6 +20,10 @@ declare_clippy_lint! {
19
20
/// ### Why is this bad?
20
21
/// Using an explicit range is more concise and easier to read.
21
22
///
23
+ /// ### Known issues
24
+ /// This lint intentionally does not handle numbers greater than `i128::MAX` for `u128` literals
25
+ /// in order to support negative numbers.
26
+ ///
22
27
/// ### Example
23
28
/// ```rust
24
29
/// let x = 6;
@@ -36,11 +41,14 @@ declare_clippy_lint! {
36
41
}
37
42
declare_lint_pass ! ( ManualRangePatterns => [ MANUAL_RANGE_PATTERNS ] ) ;
38
43
39
- fn expr_as_u128 ( expr : & Expr < ' _ > ) -> Option < u128 > {
40
- if let ExprKind :: Lit ( lit) = expr. kind
44
+ fn expr_as_i128 ( expr : & Expr < ' _ > ) -> Option < i128 > {
45
+ if let ExprKind :: Unary ( UnOp :: Neg , expr) = expr. kind {
46
+ expr_as_i128 ( expr) . map ( |num| -num)
47
+ } else if let ExprKind :: Lit ( lit) = expr. kind
41
48
&& let LitKind :: Int ( num, _) = lit. node
42
49
{
43
- Some ( num)
50
+ // Intentionally not handling numbers greater than i128::MAX (for u128 literals) for now.
51
+ num. try_into ( ) . ok ( )
44
52
} else {
45
53
None
46
54
}
@@ -56,22 +64,22 @@ impl LateLintPass<'_> for ManualRangePatterns {
56
64
if let PatKind :: Or ( pats) = pat. kind
57
65
&& pats. len ( ) >= 3
58
66
{
59
- let mut min = u128 :: MAX ;
60
- let mut max = 0 ;
67
+ let mut min = i128 :: MAX ;
68
+ let mut max = i128 :: MIN ;
61
69
let mut numbers_found = FxHashSet :: default ( ) ;
62
70
let mut ranges_found = Vec :: new ( ) ;
63
71
64
72
for pat in pats {
65
73
if let PatKind :: Lit ( lit) = pat. kind
66
- && let Some ( num) = expr_as_u128 ( lit)
74
+ && let Some ( num) = expr_as_i128 ( lit)
67
75
{
68
76
numbers_found. insert ( num) ;
69
77
70
78
min = min. min ( num) ;
71
79
max = max. max ( num) ;
72
80
} else if let PatKind :: Range ( Some ( left) , Some ( right) , end) = pat. kind
73
- && let Some ( left) = expr_as_u128 ( left)
74
- && let Some ( right) = expr_as_u128 ( right)
81
+ && let Some ( left) = expr_as_i128 ( left)
82
+ && let Some ( right) = expr_as_i128 ( right)
75
83
&& right >= left
76
84
{
77
85
min = min. min ( left) ;
0 commit comments