|
1 |
| -use crate::consts::{constant, Constant}; |
| 1 | +use crate::consts::{constant, miri_to_const, Constant}; |
2 | 2 | use crate::utils::paths;
|
3 | 3 | use crate::utils::sugg::Sugg;
|
4 | 4 | use crate::utils::{
|
@@ -444,7 +444,7 @@ fn check_match_bool(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>], e
|
444 | 444 |
|
445 | 445 | fn check_overlapping_arms<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ex: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) {
|
446 | 446 | 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)); |
448 | 448 | let type_ranges = type_ranges(&ranges);
|
449 | 449 | if !type_ranges.is_empty() {
|
450 | 450 | if let Some((start, end)) = overlapping(&type_ranges) {
|
@@ -705,25 +705,52 @@ fn check_wild_in_or_pats(cx: &LateContext<'_, '_>, arms: &[Arm<'_>]) {
|
705 | 705 | }
|
706 | 706 |
|
707 | 707 | /// 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>> { |
709 | 713 | arms.iter()
|
710 | 714 | .flat_map(|arm| {
|
711 | 715 | if let Arm {
|
712 | 716 | ref pat, guard: None, ..
|
713 | 717 | } = *arm
|
714 | 718 | {
|
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, |
727 | 754 | }
|
728 | 755 | }
|
729 | 756 |
|
|
0 commit comments