mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-12-01 00:49:30 +00:00
[manual_range_patterns
]: lint negative values
This commit is contained in:
parent
26edd5a2ab
commit
5cc0c04826
4 changed files with 33 additions and 10 deletions
|
@ -6,6 +6,7 @@ use rustc_hir::Expr;
|
||||||
use rustc_hir::ExprKind;
|
use rustc_hir::ExprKind;
|
||||||
use rustc_hir::PatKind;
|
use rustc_hir::PatKind;
|
||||||
use rustc_hir::RangeEnd;
|
use rustc_hir::RangeEnd;
|
||||||
|
use rustc_hir::UnOp;
|
||||||
use rustc_lint::LintContext;
|
use rustc_lint::LintContext;
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
|
@ -36,11 +37,13 @@ declare_clippy_lint! {
|
||||||
}
|
}
|
||||||
declare_lint_pass!(ManualRangePatterns => [MANUAL_RANGE_PATTERNS]);
|
declare_lint_pass!(ManualRangePatterns => [MANUAL_RANGE_PATTERNS]);
|
||||||
|
|
||||||
fn expr_as_u128(expr: &Expr<'_>) -> Option<u128> {
|
fn expr_as_i128(expr: &Expr<'_>) -> Option<i128> {
|
||||||
if let ExprKind::Lit(lit) = expr.kind
|
if let ExprKind::Unary(UnOp::Neg, expr) = expr.kind {
|
||||||
|
expr_as_i128(expr).map(|num| -num)
|
||||||
|
} else if let ExprKind::Lit(lit) = expr.kind
|
||||||
&& let LitKind::Int(num, _) = lit.node
|
&& let LitKind::Int(num, _) = lit.node
|
||||||
{
|
{
|
||||||
Some(num)
|
Some(num as i128)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -56,22 +59,22 @@ impl LateLintPass<'_> for ManualRangePatterns {
|
||||||
if let PatKind::Or(pats) = pat.kind
|
if let PatKind::Or(pats) = pat.kind
|
||||||
&& pats.len() >= 3
|
&& pats.len() >= 3
|
||||||
{
|
{
|
||||||
let mut min = u128::MAX;
|
let mut min = i128::MAX;
|
||||||
let mut max = 0;
|
let mut max = i128::MIN;
|
||||||
let mut numbers_found = FxHashSet::default();
|
let mut numbers_found = FxHashSet::default();
|
||||||
let mut ranges_found = Vec::new();
|
let mut ranges_found = Vec::new();
|
||||||
|
|
||||||
for pat in pats {
|
for pat in pats {
|
||||||
if let PatKind::Lit(lit) = pat.kind
|
if let PatKind::Lit(lit) = pat.kind
|
||||||
&& let Some(num) = expr_as_u128(lit)
|
&& let Some(num) = expr_as_i128(lit)
|
||||||
{
|
{
|
||||||
numbers_found.insert(num);
|
numbers_found.insert(num);
|
||||||
|
|
||||||
min = min.min(num);
|
min = min.min(num);
|
||||||
max = max.max(num);
|
max = max.max(num);
|
||||||
} else if let PatKind::Range(Some(left), Some(right), end) = pat.kind
|
} else if let PatKind::Range(Some(left), Some(right), end) = pat.kind
|
||||||
&& let Some(left) = expr_as_u128(left)
|
&& let Some(left) = expr_as_i128(left)
|
||||||
&& let Some(right) = expr_as_u128(right)
|
&& let Some(right) = expr_as_i128(right)
|
||||||
&& right >= left
|
&& right >= left
|
||||||
{
|
{
|
||||||
min = min.min(left);
|
min = min.min(left);
|
||||||
|
|
|
@ -25,6 +25,10 @@ fn main() {
|
||||||
1..=10 => true,
|
1..=10 => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
let _ = matches!(f, -5..=3);
|
||||||
|
let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1); // 2 is missing
|
||||||
|
let _ = matches!(f, -1000001..=1000001);
|
||||||
|
let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_002);
|
||||||
|
|
||||||
macro_rules! mac {
|
macro_rules! mac {
|
||||||
($e:expr) => {
|
($e:expr) => {
|
||||||
|
|
|
@ -25,6 +25,10 @@ fn main() {
|
||||||
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 => true,
|
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1 | 2);
|
||||||
|
let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1); // 2 is missing
|
||||||
|
let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_001);
|
||||||
|
let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_002);
|
||||||
|
|
||||||
macro_rules! mac {
|
macro_rules! mac {
|
||||||
($e:expr) => {
|
($e:expr) => {
|
||||||
|
|
|
@ -37,7 +37,19 @@ LL | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 => true,
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10`
|
||||||
|
|
||||||
error: this OR pattern can be rewritten using a range
|
error: this OR pattern can be rewritten using a range
|
||||||
--> $DIR/manual_range_patterns.rs:31:26
|
--> $DIR/manual_range_patterns.rs:28:25
|
||||||
|
|
|
||||||
|
LL | let _ = matches!(f, -1 | -5 | 3 | -2 | -4 | -3 | 0 | 1 | 2);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-5..=3`
|
||||||
|
|
||||||
|
error: this OR pattern can be rewritten using a range
|
||||||
|
--> $DIR/manual_range_patterns.rs:30:25
|
||||||
|
|
|
||||||
|
LL | let _ = matches!(f, -1_000_000..=1_000_000 | -1_000_001 | 1_000_001);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `-1000001..=1000001`
|
||||||
|
|
||||||
|
error: this OR pattern can be rewritten using a range
|
||||||
|
--> $DIR/manual_range_patterns.rs:35:26
|
||||||
|
|
|
|
||||||
LL | matches!($e, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10)
|
LL | matches!($e, 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10)
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `1..=10`
|
||||||
|
@ -47,5 +59,5 @@ LL | mac!(f);
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: aborting due to 9 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue