@@ -6,6 +6,7 @@ use rustc_hir::Expr;
66use rustc_hir:: ExprKind ;
77use rustc_hir:: PatKind ;
88use rustc_hir:: RangeEnd ;
9+ use rustc_hir:: UnOp ;
910use rustc_lint:: LintContext ;
1011use rustc_lint:: { LateContext , LateLintPass } ;
1112use rustc_middle:: lint:: in_external_macro;
@@ -19,6 +20,10 @@ declare_clippy_lint! {
1920 /// ### Why is this bad?
2021 /// Using an explicit range is more concise and easier to read.
2122 ///
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+ ///
2227 /// ### Example
2328 /// ```rust
2429 /// let x = 6;
@@ -36,11 +41,14 @@ declare_clippy_lint! {
3641}
3742declare_lint_pass ! ( ManualRangePatterns => [ MANUAL_RANGE_PATTERNS ] ) ;
3843
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
4148 && let LitKind :: Int ( num, _) = lit. node
4249 {
43- Some ( num)
50+ // Intentionally not handling numbers greater than i128::MAX (for u128 literals) for now.
51+ num. try_into ( ) . ok ( )
4452 } else {
4553 None
4654 }
@@ -56,22 +64,22 @@ impl LateLintPass<'_> for ManualRangePatterns {
5664 if let PatKind :: Or ( pats) = pat. kind
5765 && pats. len ( ) >= 3
5866 {
59- let mut min = u128 :: MAX ;
60- let mut max = 0 ;
67+ let mut min = i128 :: MAX ;
68+ let mut max = i128 :: MIN ;
6169 let mut numbers_found = FxHashSet :: default ( ) ;
6270 let mut ranges_found = Vec :: new ( ) ;
6371
6472 for pat in pats {
6573 if let PatKind :: Lit ( lit) = pat. kind
66- && let Some ( num) = expr_as_u128 ( lit)
74+ && let Some ( num) = expr_as_i128 ( lit)
6775 {
6876 numbers_found. insert ( num) ;
6977
7078 min = min. min ( num) ;
7179 max = max. max ( num) ;
7280 } 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)
7583 && right >= left
7684 {
7785 min = min. min ( left) ;
0 commit comments