Skip to content

Commit 10cf141

Browse files
committed
Apply review comments
1 parent 8daa278 commit 10cf141

File tree

5 files changed

+95
-37
lines changed

5 files changed

+95
-37
lines changed

clippy_lints/src/matches.rs

+42-15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::consts::{constant, Constant};
1+
use crate::consts::{constant, miri_to_const, Constant};
22
use crate::utils::paths;
33
use crate::utils::sugg::Sugg;
44
use crate::utils::{
@@ -444,7 +444,7 @@ fn check_match_bool(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], e
444444

445445
fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) {
446446
if arms.len() >= 2 && cx.tables.expr_ty(ex).is_integral() {
447-
let ranges = all_ranges(cx, arms);
447+
let ranges = all_ranges(cx, arms, cx.tables.expr_ty(ex));
448448
let type_ranges = type_ranges(&ranges);
449449
if !type_ranges.is_empty() {
450450
if let Some((start, end)) = overlapping(&type_ranges) {
@@ -705,25 +705,52 @@ fn check_wild_in_or_pats(cx: &LateContext<'_, '_>, arms: &[Arm<'_>]) {
705705
}
706706

707707
/// Gets all arms that are unbounded `PatRange`s.
708-
fn all_ranges<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arms: &'tcx [Arm<'_>]) -> Vec<SpannedRange<Constant>> {
708+
fn all_ranges<'a, 'tcx>(
709+
cx: &LateContext<'a, 'tcx>,
710+
arms: &'tcx [Arm<'_>],
711+
ty: Ty<'tcx>,
712+
) -> Vec<SpannedRange<Constant>> {
709713
arms.iter()
710714
.flat_map(|arm| {
711715
if let Arm {
712716
ref pat, guard: None, ..
713717
} = *arm
714718
{
715-
if let PatKind::Range(ref lhs, ref rhs, ref range_end) = pat.kind {
716-
if let (Some(l), Some(r)) = (lhs, rhs) {
717-
let lhs = constant(cx, cx.tables, l)?.0;
718-
let rhs = constant(cx, cx.tables, r)?.0;
719-
let rhs = match *range_end {
720-
RangeEnd::Included => Bound::Included(rhs),
721-
RangeEnd::Excluded => Bound::Excluded(rhs),
722-
};
723-
return Some(SpannedRange {
724-
span: pat.span,
725-
node: (lhs, rhs),
726-
});
719+
if let PatKind::Range(ref lhs, ref rhs, range_end) = pat.kind {
720+
match (lhs, rhs) {
721+
(Some(lhs), Some(rhs)) => {
722+
let lhs = constant(cx, cx.tables, lhs)?.0;
723+
let rhs = constant(cx, cx.tables, rhs)?.0;
724+
let rhs = match range_end {
725+
RangeEnd::Included => Bound::Included(rhs),
726+
RangeEnd::Excluded => Bound::Excluded(rhs),
727+
};
728+
return Some(SpannedRange {
729+
span: pat.span,
730+
node: (lhs, rhs),
731+
});
732+
},
733+
(None, Some(rhs)) => {
734+
let lhs = miri_to_const(ty.numeric_min_val(cx.tcx)?)?;
735+
let rhs = constant(cx, cx.tables, rhs)?.0;
736+
let rhs = match range_end {
737+
RangeEnd::Included => Bound::Included(rhs),
738+
RangeEnd::Excluded => Bound::Excluded(rhs),
739+
};
740+
return Some(SpannedRange {
741+
span: pat.span,
742+
node: (lhs, rhs),
743+
});
744+
},
745+
(Some(lhs), None) => {
746+
let lhs = constant(cx, cx.tables, lhs)?.0;
747+
let rhs = miri_to_const(ty.numeric_max_val(cx.tcx)?)?;
748+
return Some(SpannedRange {
749+
span: pat.span,
750+
node: (lhs, Bound::Excluded(rhs)),
751+
});
752+
},
753+
_ => return None,
727754
}
728755
}
729756

clippy_lints/src/utils/author.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_hir::intravisit::{NestedVisitorMap, Visitor};
1212
use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, Pat, PatKind, QPath, Stmt, StmtKind, TyKind};
1313
use rustc_session::declare_tool_lint;
1414
use syntax::ast::{Attribute, LitFloatType, LitKind};
15+
use syntax::walk_list;
1516

1617
declare_clippy_lint! {
1718
/// **What it does:** Generates clippy code that detects the offending pattern
@@ -617,13 +618,9 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
617618
start_pat, end_pat, end_kind, current
618619
);
619620
self.current = start_pat;
620-
if let Some(expr) = start {
621-
self.visit_expr(expr);
622-
}
621+
walk_list!(self, visit_expr, start);
623622
self.current = end_pat;
624-
if let Some(expr) = end {
625-
self.visit_expr(expr);
626-
}
623+
walk_list!(self, visit_expr, end);
627624
},
628625
PatKind::Slice(ref start, ref middle, ref end) => {
629626
let start_pat = self.next("start");

clippy_lints/src/utils/hir_utils.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,8 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> {
194194
(&PatKind::Tuple(ref l, ls), &PatKind::Tuple(ref r, rs)) => {
195195
ls == rs && over(l, r, |l, r| self.eq_pat(l, r))
196196
},
197-
(&PatKind::Range(ref ls, ref le, ref li), &PatKind::Range(ref rs, ref re, ref ri)) => {
198-
if let (Some(ls), Some(rs), Some(le), Some(re)) = (ls, rs, le, re) {
199-
return self.eq_expr(ls, rs) && self.eq_expr(le, re) && (*li == *ri);
200-
}
201-
false
197+
(&PatKind::Range(ref ls, ref le, li), &PatKind::Range(ref rs, ref re, ri)) => {
198+
both(ls, rs, |a, b| self.eq_expr(a, b)) && both(le, re, |a, b| self.eq_expr(a, b)) && (li == ri)
202199
},
203200
(&PatKind::Ref(ref le, ref lm), &PatKind::Ref(ref re, ref rm)) => lm == rm && self.eq_pat(le, re),
204201
(&PatKind::Slice(ref ls, ref li, ref le), &PatKind::Slice(ref rs, ref ri, ref re)) => {

tests/ui/match_overlapping_arm.rs

+13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(exclusive_range_pattern)]
2+
#![feature(half_open_range_patterns)]
23
#![warn(clippy::match_overlapping_arm)]
34
#![allow(clippy::redundant_pattern_matching)]
45

@@ -56,6 +57,18 @@ fn overlapping() {
5657
_ => (),
5758
}
5859

60+
match 42 {
61+
0.. => println!("0 .. 42"),
62+
3.. => println!("3 .. 42"),
63+
_ => (),
64+
}
65+
66+
match 42 {
67+
..=23 => println!("0 ... 23"),
68+
..26 => println!("0 .. 26"),
69+
_ => (),
70+
}
71+
5972
if let None = Some(42) {
6073
// nothing
6174
} else if let None = Some(42) {

tests/ui/match_overlapping_arm.stderr

+35-11
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,87 @@
11
error: some ranges overlap
2-
--> $DIR/match_overlapping_arm.rs:11:9
2+
--> $DIR/match_overlapping_arm.rs:12:9
33
|
44
LL | 0..=10 => println!("0 ... 10"),
55
| ^^^^^^
66
|
77
= note: `-D clippy::match-overlapping-arm` implied by `-D warnings`
88
note: overlaps with this
9-
--> $DIR/match_overlapping_arm.rs:12:9
9+
--> $DIR/match_overlapping_arm.rs:13:9
1010
|
1111
LL | 0..=11 => println!("0 ... 11"),
1212
| ^^^^^^
1313

1414
error: some ranges overlap
15-
--> $DIR/match_overlapping_arm.rs:17:9
15+
--> $DIR/match_overlapping_arm.rs:18:9
1616
|
1717
LL | 0..=5 => println!("0 ... 5"),
1818
| ^^^^^
1919
|
2020
note: overlaps with this
21-
--> $DIR/match_overlapping_arm.rs:19:9
21+
--> $DIR/match_overlapping_arm.rs:20:9
2222
|
2323
LL | FOO..=11 => println!("0 ... 11"),
2424
| ^^^^^^^^
2525

2626
error: some ranges overlap
27-
--> $DIR/match_overlapping_arm.rs:25:9
27+
--> $DIR/match_overlapping_arm.rs:26:9
2828
|
2929
LL | 0..=5 => println!("0 ... 5"),
3030
| ^^^^^
3131
|
3232
note: overlaps with this
33-
--> $DIR/match_overlapping_arm.rs:24:9
33+
--> $DIR/match_overlapping_arm.rs:25:9
3434
|
3535
LL | 2 => println!("2"),
3636
| ^
3737

3838
error: some ranges overlap
39-
--> $DIR/match_overlapping_arm.rs:31:9
39+
--> $DIR/match_overlapping_arm.rs:32:9
4040
|
4141
LL | 0..=2 => println!("0 ... 2"),
4242
| ^^^^^
4343
|
4444
note: overlaps with this
45-
--> $DIR/match_overlapping_arm.rs:30:9
45+
--> $DIR/match_overlapping_arm.rs:31:9
4646
|
4747
LL | 2 => println!("2"),
4848
| ^
4949

5050
error: some ranges overlap
51-
--> $DIR/match_overlapping_arm.rs:54:9
51+
--> $DIR/match_overlapping_arm.rs:55:9
5252
|
5353
LL | 0..11 => println!("0 .. 11"),
5454
| ^^^^^
5555
|
5656
note: overlaps with this
57-
--> $DIR/match_overlapping_arm.rs:55:9
57+
--> $DIR/match_overlapping_arm.rs:56:9
5858
|
5959
LL | 0..=11 => println!("0 ... 11"),
6060
| ^^^^^^
6161

62-
error: aborting due to 5 previous errors
62+
error: some ranges overlap
63+
--> $DIR/match_overlapping_arm.rs:61:9
64+
|
65+
LL | 0.. => println!("0 .. 42"),
66+
| ^^^
67+
|
68+
note: overlaps with this
69+
--> $DIR/match_overlapping_arm.rs:62:9
70+
|
71+
LL | 3.. => println!("3 .. 42"),
72+
| ^^^
73+
74+
error: some ranges overlap
75+
--> $DIR/match_overlapping_arm.rs:67:9
76+
|
77+
LL | ..=23 => println!("0 ... 23"),
78+
| ^^^^^
79+
|
80+
note: overlaps with this
81+
--> $DIR/match_overlapping_arm.rs:68:9
82+
|
83+
LL | ..26 => println!("0 .. 26"),
84+
| ^^^^
85+
86+
error: aborting due to 7 previous errors
6387

0 commit comments

Comments
 (0)