@@ -33,7 +33,6 @@ use rustc_span::source_map::{Span, Spanned};
33
33
use rustc_span:: sym;
34
34
use std:: cmp:: Ordering ;
35
35
use std:: collections:: hash_map:: Entry ;
36
- use std:: ops:: Bound ;
37
36
38
37
declare_clippy_lint ! {
39
38
/// ### What it does
@@ -1596,27 +1595,27 @@ fn opt_parent_let<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<&'a Local<'
1596
1595
None
1597
1596
}
1598
1597
1599
- /// Gets all arms that are unbounded `PatRange`s .
1598
+ /// Gets the ranges for each range pattern arm. Applies `ty` bounds for open ranges .
1600
1599
fn all_ranges < ' tcx > ( cx : & LateContext < ' tcx > , arms : & ' tcx [ Arm < ' _ > ] , ty : Ty < ' tcx > ) -> Vec < SpannedRange < FullInt > > {
1601
1600
arms. iter ( )
1602
1601
. filter_map ( |arm| {
1603
1602
if let Arm { pat, guard : None , .. } = * arm {
1604
1603
if let PatKind :: Range ( ref lhs, ref rhs, range_end) = pat. kind {
1605
- let lhs = match lhs {
1604
+ let lhs_const = match lhs {
1606
1605
Some ( lhs) => constant ( cx, cx. typeck_results ( ) , lhs) ?. 0 ,
1607
1606
None => miri_to_const ( ty. numeric_min_val ( cx. tcx ) ?) ?,
1608
1607
} ;
1609
- let rhs = match rhs {
1608
+ let rhs_const = match rhs {
1610
1609
Some ( rhs) => constant ( cx, cx. typeck_results ( ) , rhs) ?. 0 ,
1611
1610
None => miri_to_const ( ty. numeric_max_val ( cx. tcx ) ?) ?,
1612
1611
} ;
1613
1612
1614
- let lhs_val = lhs . int_value ( cx, ty) ?;
1615
- let rhs_val = rhs . int_value ( cx, ty) ?;
1613
+ let lhs_val = lhs_const . int_value ( cx, ty) ?;
1614
+ let rhs_val = rhs_const . int_value ( cx, ty) ?;
1616
1615
1617
1616
let rhs_bound = match range_end {
1618
- RangeEnd :: Included => Bound :: Included ( rhs_val) ,
1619
- RangeEnd :: Excluded => Bound :: Excluded ( rhs_val) ,
1617
+ RangeEnd :: Included => EndBound :: Included ( rhs_val) ,
1618
+ RangeEnd :: Excluded => EndBound :: Excluded ( rhs_val) ,
1620
1619
} ;
1621
1620
return Some ( SpannedRange {
1622
1621
span : pat. span ,
@@ -1628,7 +1627,7 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>)
1628
1627
let value = constant_full_int ( cx, cx. typeck_results ( ) , value) ?;
1629
1628
return Some ( SpannedRange {
1630
1629
span : pat. span ,
1631
- node : ( value, Bound :: Included ( value) ) ,
1630
+ node : ( value, EndBound :: Included ( value) ) ,
1632
1631
} ) ;
1633
1632
}
1634
1633
}
@@ -1637,10 +1636,16 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>)
1637
1636
. collect ( )
1638
1637
}
1639
1638
1639
+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
1640
+ pub enum EndBound < T > {
1641
+ Included ( T ) ,
1642
+ Excluded ( T ) ,
1643
+ }
1644
+
1640
1645
#[ derive( Debug , Eq , PartialEq ) ]
1641
- pub struct SpannedRange < T > {
1646
+ struct SpannedRange < T > {
1642
1647
pub span : Span ,
1643
- pub node : ( T , Bound < T > ) ,
1648
+ pub node : ( T , EndBound < T > ) ,
1644
1649
}
1645
1650
1646
1651
// Checks if arm has the form `None => None`
@@ -1689,87 +1694,62 @@ where
1689
1694
ref_count > 1
1690
1695
}
1691
1696
1692
- pub fn overlapping < T > ( ranges : & [ SpannedRange < T > ] ) -> Option < ( & SpannedRange < T > , & SpannedRange < T > ) >
1697
+ fn overlapping < T > ( ranges : & [ SpannedRange < T > ] ) -> Option < ( & SpannedRange < T > , & SpannedRange < T > ) >
1693
1698
where
1694
1699
T : Copy + Ord ,
1695
1700
{
1696
- #[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
1697
- enum Kind < ' a , T > {
1698
- Start ( T , & ' a SpannedRange < T > ) ,
1699
- End ( Bound < T > , & ' a SpannedRange < T > ) ,
1701
+ #[ derive( Copy , Clone , Debug , Eq , Ord , PartialEq , PartialOrd ) ]
1702
+ enum BoundKind {
1703
+ EndExcluded ,
1704
+ Start ,
1705
+ EndIncluded ,
1700
1706
}
1701
1707
1702
- impl < ' a , T : Copy > Kind < ' a , T > {
1703
- fn value ( self ) -> Bound < T > {
1704
- match self {
1705
- Kind :: Start ( t, _) => Bound :: Included ( t) ,
1706
- Kind :: End ( t, _) => t,
1707
- }
1708
- }
1709
- }
1708
+ #[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
1709
+ struct RangeBound < ' a , T > ( T , BoundKind , & ' a SpannedRange < T > ) ;
1710
1710
1711
- impl < ' a , T : Copy + Ord > PartialOrd for Kind < ' a , T > {
1711
+ impl < ' a , T : Copy + Ord > PartialOrd for RangeBound < ' a , T > {
1712
1712
fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
1713
1713
Some ( self . cmp ( other) )
1714
1714
}
1715
1715
}
1716
1716
1717
- impl < ' a , T : Copy + Ord > Ord for Kind < ' a , T > {
1718
- fn cmp ( & self , other : & Self ) -> Ordering {
1719
- match ( self . value ( ) , other. value ( ) ) {
1720
- ( Bound :: Included ( a) , Bound :: Included ( b) ) | ( Bound :: Excluded ( a) , Bound :: Excluded ( b) ) => {
1721
- let value_cmp = a. cmp ( & b) ;
1722
- // In the case of ties, starts come before ends
1723
- if value_cmp == Ordering :: Equal {
1724
- match ( self , other) {
1725
- ( Kind :: Start ( ..) , Kind :: End ( ..) ) => Ordering :: Less ,
1726
- ( Kind :: End ( ..) , Kind :: Start ( ..) ) => Ordering :: Greater ,
1727
- _ => Ordering :: Equal ,
1728
- }
1729
- } else {
1730
- value_cmp
1731
- }
1732
- } ,
1733
- // Range patterns cannot be unbounded (yet)
1734
- ( Bound :: Unbounded , _) | ( _, Bound :: Unbounded ) => unimplemented ! ( ) ,
1735
- ( Bound :: Included ( a) , Bound :: Excluded ( b) ) => match a. cmp ( & b) {
1736
- Ordering :: Equal => Ordering :: Greater ,
1737
- other => other,
1738
- } ,
1739
- ( Bound :: Excluded ( a) , Bound :: Included ( b) ) => match a. cmp ( & b) {
1740
- Ordering :: Equal => Ordering :: Less ,
1741
- other => other,
1742
- } ,
1743
- }
1717
+ impl < ' a , T : Copy + Ord > Ord for RangeBound < ' a , T > {
1718
+ fn cmp ( & self , RangeBound ( other_value, other_kind, _) : & Self ) -> Ordering {
1719
+ let RangeBound ( self_value, self_kind, _) = * self ;
1720
+ ( self_value, self_kind) . cmp ( & ( * other_value, * other_kind) )
1744
1721
}
1745
1722
}
1746
1723
1747
1724
let mut values = Vec :: with_capacity ( 2 * ranges. len ( ) ) ;
1748
1725
1749
- for r in ranges {
1750
- values. push ( Kind :: Start ( r. node . 0 , r) ) ;
1751
- values. push ( Kind :: End ( r. node . 1 , r) ) ;
1726
+ for r @ SpannedRange { node : ( start, end) , .. } in ranges {
1727
+ values. push ( RangeBound ( * start, BoundKind :: Start , r) ) ;
1728
+ values. push ( match end {
1729
+ EndBound :: Excluded ( val) => RangeBound ( * val, BoundKind :: EndExcluded , r) ,
1730
+ EndBound :: Included ( val) => RangeBound ( * val, BoundKind :: EndIncluded , r) ,
1731
+ } ) ;
1752
1732
}
1753
1733
1754
1734
values. sort ( ) ;
1755
1735
1756
1736
let mut started = vec ! [ ] ;
1757
1737
1758
- for value in values {
1759
- match value {
1760
- Kind :: Start ( _ , r ) => started. push ( r ) ,
1761
- Kind :: End ( _ , er ) => {
1738
+ for RangeBound ( _ , kind , range ) in values {
1739
+ match kind {
1740
+ BoundKind :: Start => started. push ( range ) ,
1741
+ BoundKind :: EndExcluded | BoundKind :: EndIncluded => {
1762
1742
let mut overlap = None ;
1763
1743
1764
- while let Some ( sr ) = started. pop ( ) {
1765
- if sr == er {
1744
+ while let Some ( last_started ) = started. pop ( ) {
1745
+ if last_started == range {
1766
1746
break ;
1767
1747
}
1768
- overlap = Some ( sr ) ;
1748
+ overlap = Some ( last_started ) ;
1769
1749
}
1770
1750
1771
- if let Some ( sr ) = overlap {
1772
- return Some ( ( er , sr ) ) ;
1751
+ if let Some ( first_overlapping ) = overlap {
1752
+ return Some ( ( range , first_overlapping ) ) ;
1773
1753
}
1774
1754
} ,
1775
1755
}
@@ -2227,29 +2207,29 @@ fn test_overlapping() {
2227
2207
} ;
2228
2208
2229
2209
assert_eq ! ( None , overlapping:: <u8 >( & [ ] ) ) ;
2230
- assert_eq ! ( None , overlapping( & [ sp( 1 , Bound :: Included ( 4 ) ) ] ) ) ;
2210
+ assert_eq ! ( None , overlapping( & [ sp( 1 , EndBound :: Included ( 4 ) ) ] ) ) ;
2231
2211
assert_eq ! (
2232
2212
None ,
2233
- overlapping( & [ sp( 1 , Bound :: Included ( 4 ) ) , sp( 5 , Bound :: Included ( 6 ) ) ] )
2213
+ overlapping( & [ sp( 1 , EndBound :: Included ( 4 ) ) , sp( 5 , EndBound :: Included ( 6 ) ) ] )
2234
2214
) ;
2235
2215
assert_eq ! (
2236
2216
None ,
2237
2217
overlapping( & [
2238
- sp( 1 , Bound :: Included ( 4 ) ) ,
2239
- sp( 5 , Bound :: Included ( 6 ) ) ,
2240
- sp( 10 , Bound :: Included ( 11 ) )
2218
+ sp( 1 , EndBound :: Included ( 4 ) ) ,
2219
+ sp( 5 , EndBound :: Included ( 6 ) ) ,
2220
+ sp( 10 , EndBound :: Included ( 11 ) )
2241
2221
] , )
2242
2222
) ;
2243
2223
assert_eq ! (
2244
- Some ( ( & sp( 1 , Bound :: Included ( 4 ) ) , & sp( 3 , Bound :: Included ( 6 ) ) ) ) ,
2245
- overlapping( & [ sp( 1 , Bound :: Included ( 4 ) ) , sp( 3 , Bound :: Included ( 6 ) ) ] )
2224
+ Some ( ( & sp( 1 , EndBound :: Included ( 4 ) ) , & sp( 3 , EndBound :: Included ( 6 ) ) ) ) ,
2225
+ overlapping( & [ sp( 1 , EndBound :: Included ( 4 ) ) , sp( 3 , EndBound :: Included ( 6 ) ) ] )
2246
2226
) ;
2247
2227
assert_eq ! (
2248
- Some ( ( & sp( 5 , Bound :: Included ( 6 ) ) , & sp( 6 , Bound :: Included ( 11 ) ) ) ) ,
2228
+ Some ( ( & sp( 5 , EndBound :: Included ( 6 ) ) , & sp( 6 , EndBound :: Included ( 11 ) ) ) ) ,
2249
2229
overlapping( & [
2250
- sp( 1 , Bound :: Included ( 4 ) ) ,
2251
- sp( 5 , Bound :: Included ( 6 ) ) ,
2252
- sp( 6 , Bound :: Included ( 11 ) )
2230
+ sp( 1 , EndBound :: Included ( 4 ) ) ,
2231
+ sp( 5 , EndBound :: Included ( 6 ) ) ,
2232
+ sp( 6 , EndBound :: Included ( 11 ) )
2253
2233
] , )
2254
2234
) ;
2255
2235
}
0 commit comments