@@ -6,6 +6,7 @@ use rustc_const_eval::EvalHint::ExprTypeChecked;
66use rustc_const_eval:: ConstContext ;
77use rustc_const_math:: ConstInt ;
88use std:: cmp:: Ordering ;
9+ use std:: collections:: Bound ;
910use syntax:: ast:: LitKind ;
1011use syntax:: codemap:: Span ;
1112use utils:: paths;
@@ -361,18 +362,22 @@ fn all_ranges(cx: &LateContext, arms: &[Arm]) -> Vec<SpannedRange<ConstVal>> {
361362 }
362363 . filter_map ( |pat| {
363364 if_let_chain ! { [
364- let PatKind :: Range ( ref lhs, ref rhs, _ ) = pat. node,
365+ let PatKind :: Range ( ref lhs, ref rhs, ref range_end ) = pat. node,
365366 let Ok ( lhs) = constcx. eval( lhs, ExprTypeChecked ) ,
366367 let Ok ( rhs) = constcx. eval( rhs, ExprTypeChecked )
367368 ] , {
369+ let rhs = match * range_end {
370+ RangeEnd :: Included => Bound :: Included ( rhs) ,
371+ RangeEnd :: Excluded => Bound :: Excluded ( rhs) ,
372+ } ;
368373 return Some ( SpannedRange { span: pat. span, node: ( lhs, rhs) } ) ;
369374 } }
370375
371376 if_let_chain ! { [
372377 let PatKind :: Lit ( ref value) = pat. node,
373378 let Ok ( value) = constcx. eval( value, ExprTypeChecked )
374379 ] , {
375- return Some ( SpannedRange { span: pat. span, node: ( value. clone( ) , value) } ) ;
380+ return Some ( SpannedRange { span: pat. span, node: ( value. clone( ) , Bound :: Included ( value) ) } ) ;
376381 } }
377382
378383 None
@@ -384,7 +389,7 @@ fn all_ranges(cx: &LateContext, arms: &[Arm]) -> Vec<SpannedRange<ConstVal>> {
384389#[ derive( Debug , Eq , PartialEq ) ]
385390pub struct SpannedRange < T > {
386391 pub span : Span ,
387- pub node : ( T , T ) ,
392+ pub node : ( T , Bound < T > ) ,
388393}
389394
390395type TypedRanges = Vec < SpannedRange < ConstInt > > ;
@@ -393,13 +398,26 @@ type TypedRanges = Vec<SpannedRange<ConstInt>>;
393398/// `Uint` and `Int` probably don't make sense.
394399fn type_ranges ( ranges : & [ SpannedRange < ConstVal > ] ) -> TypedRanges {
395400 ranges. iter ( )
396- . filter_map ( |range| if let ( ConstVal :: Integral ( start) , ConstVal :: Integral ( end) ) = range. node {
397- Some ( SpannedRange {
398- span : range. span ,
399- node : ( start, end) ,
400- } )
401- } else {
402- None
401+ . filter_map ( |range| match range. node {
402+ ( ConstVal :: Integral ( start) , Bound :: Included ( ConstVal :: Integral ( end) ) ) => {
403+ Some ( SpannedRange {
404+ span : range. span ,
405+ node : ( start, Bound :: Included ( end) ) ,
406+ } )
407+ } ,
408+ ( ConstVal :: Integral ( start) , Bound :: Excluded ( ConstVal :: Integral ( end) ) ) => {
409+ Some ( SpannedRange {
410+ span : range. span ,
411+ node : ( start, Bound :: Excluded ( end) ) ,
412+ } )
413+ } ,
414+ ( ConstVal :: Integral ( start) , Bound :: Unbounded ) => {
415+ Some ( SpannedRange {
416+ span : range. span ,
417+ node : ( start, Bound :: Unbounded ) ,
418+ } )
419+ } ,
420+ _ => None ,
403421 } )
404422 . collect ( )
405423}
@@ -443,7 +461,7 @@ pub fn overlapping<T>(ranges: &[SpannedRange<T>]) -> Option<(&SpannedRange<T>, &
443461 #[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
444462 enum Kind < ' a , T : ' a > {
445463 Start ( T , & ' a SpannedRange < T > ) ,
446- End ( T , & ' a SpannedRange < T > ) ,
464+ End ( Bound < T > , & ' a SpannedRange < T > ) ,
447465 }
448466
449467 impl < ' a , T : Copy > Kind < ' a , T > {
@@ -454,9 +472,9 @@ pub fn overlapping<T>(ranges: &[SpannedRange<T>]) -> Option<(&SpannedRange<T>, &
454472 }
455473 }
456474
457- fn value ( self ) -> T {
475+ fn value ( self ) -> Bound < T > {
458476 match self {
459- Kind :: Start ( t, _) |
477+ Kind :: Start ( t, _) => Bound :: Included ( t ) ,
460478 Kind :: End ( t, _) => t,
461479 }
462480 }
@@ -470,7 +488,25 @@ pub fn overlapping<T>(ranges: &[SpannedRange<T>]) -> Option<(&SpannedRange<T>, &
470488
471489 impl < ' a , T : Copy + Ord > Ord for Kind < ' a , T > {
472490 fn cmp ( & self , other : & Self ) -> Ordering {
473- self . value ( ) . cmp ( & other. value ( ) )
491+ match ( self . value ( ) , other. value ( ) ) {
492+ ( Bound :: Included ( a) , Bound :: Included ( b) ) |
493+ ( Bound :: Excluded ( a) , Bound :: Excluded ( b) ) => a. cmp ( & b) ,
494+ // Range patterns cannot be unbounded (yet)
495+ ( Bound :: Unbounded , _) |
496+ ( _, Bound :: Unbounded ) => unimplemented ! ( ) ,
497+ ( Bound :: Included ( a) , Bound :: Excluded ( b) ) => {
498+ match a. cmp ( & b) {
499+ Ordering :: Equal => Ordering :: Greater ,
500+ other => other,
501+ }
502+ } ,
503+ ( Bound :: Excluded ( a) , Bound :: Included ( b) ) => {
504+ match a. cmp ( & b) {
505+ Ordering :: Equal => Ordering :: Less ,
506+ other => other,
507+ }
508+ } ,
509+ }
474510 }
475511 }
476512
@@ -490,7 +526,7 @@ pub fn overlapping<T>(ranges: &[SpannedRange<T>]) -> Option<(&SpannedRange<T>, &
490526 return Some ( ( ra, rb) ) ;
491527 }
492528 } ,
493- ( & Kind :: End ( a, _) , & Kind :: Start ( b, _) ) if a != b => ( ) ,
529+ ( & Kind :: End ( a, _) , & Kind :: Start ( b, _) ) if a != Bound :: Included ( b ) => ( ) ,
494530 _ => return Some ( ( a. range ( ) , b. range ( ) ) ) ,
495531 }
496532 }
0 commit comments