@@ -33,7 +33,6 @@ use rustc_span::source_map::{Span, Spanned};
3333use rustc_span:: sym;
3434use std:: cmp:: Ordering ;
3535use std:: collections:: hash_map:: Entry ;
36- use std:: ops:: Bound ;
3736
3837declare_clippy_lint ! {
3938 /// ### What it does
@@ -1596,27 +1595,27 @@ fn opt_parent_let<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<&'a Local<'
15961595 None
15971596}
15981597
1599- /// Gets all arms that are unbounded `PatRange`s .
1598+ /// Gets the ranges for each range pattern arm. Applies `ty` bounds for open ranges .
16001599fn all_ranges < ' tcx > ( cx : & LateContext < ' tcx > , arms : & ' tcx [ Arm < ' _ > ] , ty : Ty < ' tcx > ) -> Vec < SpannedRange < FullInt > > {
16011600 arms. iter ( )
16021601 . filter_map ( |arm| {
16031602 if let Arm { pat, guard : None , .. } = * arm {
16041603 if let PatKind :: Range ( ref lhs, ref rhs, range_end) = pat. kind {
1605- let lhs = match lhs {
1604+ let lhs_const = match lhs {
16061605 Some ( lhs) => constant ( cx, cx. typeck_results ( ) , lhs) ?. 0 ,
16071606 None => miri_to_const ( ty. numeric_min_val ( cx. tcx ) ?) ?,
16081607 } ;
1609- let rhs = match rhs {
1608+ let rhs_const = match rhs {
16101609 Some ( rhs) => constant ( cx, cx. typeck_results ( ) , rhs) ?. 0 ,
16111610 None => miri_to_const ( ty. numeric_max_val ( cx. tcx ) ?) ?,
16121611 } ;
16131612
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) ?;
16161615
16171616 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) ,
16201619 } ;
16211620 return Some ( SpannedRange {
16221621 span : pat. span ,
@@ -1628,7 +1627,7 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>)
16281627 let value = constant_full_int ( cx, cx. typeck_results ( ) , value) ?;
16291628 return Some ( SpannedRange {
16301629 span : pat. span ,
1631- node : ( value, Bound :: Included ( value) ) ,
1630+ node : ( value, EndBound :: Included ( value) ) ,
16321631 } ) ;
16331632 }
16341633 }
@@ -1637,10 +1636,16 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>)
16371636 . collect ( )
16381637}
16391638
1639+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
1640+ pub enum EndBound < T > {
1641+ Included ( T ) ,
1642+ Excluded ( T ) ,
1643+ }
1644+
16401645#[ derive( Debug , Eq , PartialEq ) ]
1641- pub struct SpannedRange < T > {
1646+ struct SpannedRange < T > {
16421647 pub span : Span ,
1643- pub node : ( T , Bound < T > ) ,
1648+ pub node : ( T , EndBound < T > ) ,
16441649}
16451650
16461651// Checks if arm has the form `None => None`
@@ -1689,87 +1694,62 @@ where
16891694 ref_count > 1
16901695}
16911696
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 > ) >
16931698where
16941699 T : Copy + Ord ,
16951700{
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 ,
17001706 }
17011707
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 > ) ;
17101710
1711- impl < ' a , T : Copy + Ord > PartialOrd for Kind < ' a , T > {
1711+ impl < ' a , T : Copy + Ord > PartialOrd for RangeBound < ' a , T > {
17121712 fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
17131713 Some ( self . cmp ( other) )
17141714 }
17151715 }
17161716
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) )
17441721 }
17451722 }
17461723
17471724 let mut values = Vec :: with_capacity ( 2 * ranges. len ( ) ) ;
17481725
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+ } ) ;
17521732 }
17531733
17541734 values. sort ( ) ;
17551735
17561736 let mut started = vec ! [ ] ;
17571737
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 => {
17621742 let mut overlap = None ;
17631743
1764- while let Some ( sr ) = started. pop ( ) {
1765- if sr == er {
1744+ while let Some ( last_started ) = started. pop ( ) {
1745+ if last_started == range {
17661746 break ;
17671747 }
1768- overlap = Some ( sr ) ;
1748+ overlap = Some ( last_started ) ;
17691749 }
17701750
1771- if let Some ( sr ) = overlap {
1772- return Some ( ( er , sr ) ) ;
1751+ if let Some ( first_overlapping ) = overlap {
1752+ return Some ( ( range , first_overlapping ) ) ;
17731753 }
17741754 } ,
17751755 }
@@ -2227,29 +2207,29 @@ fn test_overlapping() {
22272207 } ;
22282208
22292209 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 ) ) ] ) ) ;
22312211 assert_eq ! (
22322212 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 ) ) ] )
22342214 ) ;
22352215 assert_eq ! (
22362216 None ,
22372217 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 ) )
22412221 ] , )
22422222 ) ;
22432223 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 ) ) ] )
22462226 ) ;
22472227 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 ) ) ) ) ,
22492229 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 ) )
22532233 ] , )
22542234 ) ;
22552235}
0 commit comments