@@ -457,13 +457,52 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
457
457
. map ( |v| Variant ( v. did ) )
458
458
. collect ( )
459
459
}
460
- ty:: TyUint ( ast:: UintTy :: Usize ) => {
460
+ ty:: TyChar => {
461
+ let ( min, max) = ( 0u128 , char:: MAX as u128 ) ;
461
462
return ( vec ! [
462
- ConstantRange ( ty:: Const :: from_usize ( cx. tcx, 0 ) ,
463
- ty:: Const :: from_usize ( cx. tcx, 100 ) ,
464
- RangeEnd :: Excluded ) ,
463
+ ConstantRange ( ty:: Const :: from_bits ( cx. tcx, min , cx . tcx . types . char ) ,
464
+ ty:: Const :: from_bits ( cx. tcx, max , cx . tcx . types . char ) ,
465
+ RangeEnd :: Included ) ,
465
466
] , true )
466
467
}
468
+ ty:: TyInt ( int_ty) => {
469
+ use syntax:: ast:: IntTy :: * ;
470
+ let ( min, max, ty) = match int_ty {
471
+ Isize => ( isize:: MIN as i128 , isize:: MAX as i128 , cx. tcx . types . isize ) ,
472
+ I8 => ( i8:: MIN as i128 , i8:: MAX as i128 , cx. tcx . types . i8 ) ,
473
+ I16 => ( i16:: MIN as i128 , i16:: MAX as i128 , cx. tcx . types . i16 ) ,
474
+ I32 => ( i32:: MIN as i128 , i32:: MAX as i128 , cx. tcx . types . i32 ) ,
475
+ I64 => ( i64:: MIN as i128 , i64:: MAX as i128 , cx. tcx . types . i64 ) ,
476
+ I128 => ( i128:: MIN as i128 , i128:: MAX as i128 , cx. tcx . types . i128 ) ,
477
+ } ;
478
+ return ( vec ! [
479
+ ConstantRange (
480
+ ty:: Const :: from_bits( cx. tcx, unsafe {
481
+ transmute:: <i128 , u128 >( min)
482
+ } , ty) ,
483
+ ty:: Const :: from_bits( cx. tcx, unsafe {
484
+ transmute:: <i128 , u128 >( max)
485
+ } , ty) ,
486
+ RangeEnd :: Included
487
+ ) ,
488
+ ] , true ) ;
489
+ }
490
+ ty:: TyUint ( uint_ty) => {
491
+ use syntax:: ast:: UintTy :: * ;
492
+ let ( min, ( max, ty) ) = ( 0u128 , match uint_ty {
493
+ Usize => ( usize:: MAX as u128 , cx. tcx . types . usize ) ,
494
+ U8 => ( u8:: MAX as u128 , cx. tcx . types . u8 ) ,
495
+ U16 => ( u16:: MAX as u128 , cx. tcx . types . u16 ) ,
496
+ U32 => ( u32:: MAX as u128 , cx. tcx . types . u32 ) ,
497
+ U64 => ( u64:: MAX as u128 , cx. tcx . types . u64 ) ,
498
+ U128 => ( u128:: MAX as u128 , cx. tcx . types . u128 ) ,
499
+ } ) ;
500
+ return ( vec ! [
501
+ ConstantRange ( ty:: Const :: from_bits( cx. tcx, min, ty) ,
502
+ ty:: Const :: from_bits( cx. tcx, max, ty) ,
503
+ RangeEnd :: Included ) ,
504
+ ] , true ) ;
505
+ }
467
506
_ => {
468
507
if cx. is_uninhabited ( pcx. ty ) {
469
508
vec ! [ ]
@@ -666,26 +705,27 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
666
705
let ( all_ctors, _ranged) = all_constructors ( cx, pcx) ;
667
706
debug ! ( "all_ctors = {:#?}" , all_ctors) ;
668
707
669
- fn to_inc_range_pair < ' tcx > ( tcx : TyCtxt < ' _ , ' _ , ' _ > , ctor : & Constructor < ' tcx > ) -> Option < ( u64 , u64 ) > {
708
+ fn to_inc_range_pair < ' tcx > ( _tcx : TyCtxt < ' _ , ' _ , ' _ > , ctor : & Constructor < ' tcx > ) -> Option < ( u128 , u128 , Ty < ' tcx > ) > {
670
709
match ctor {
671
710
Single | Variant ( _) | Slice ( _) => {
672
711
None
673
712
}
674
713
ConstantValue ( const_) => {
675
- if let Some ( val) = const_. assert_usize ( tcx ) {
676
- return Some ( ( val, val) ) ;
714
+ if let Some ( val) = const_. assert_bits ( const_ . ty ) {
715
+ return Some ( ( val, val, const_ . ty ) ) ;
677
716
}
678
717
None
679
718
}
680
719
ConstantRange ( lo, hi, end) => {
681
- if let Some ( lo) = lo. assert_usize ( tcx) {
682
- if let Some ( hi) = hi. assert_usize ( tcx) {
720
+ let ty = lo. ty ;
721
+ if let Some ( lo) = lo. assert_bits ( lo. ty ) {
722
+ if let Some ( hi) = hi. assert_bits ( hi. ty ) {
683
723
if lo > hi || lo == hi && end == & RangeEnd :: Excluded {
684
724
return None ;
685
725
} else if end == & RangeEnd :: Included {
686
- return Some ( ( lo, hi) ) ;
726
+ return Some ( ( lo, hi, ty ) ) ;
687
727
} else {
688
- return Some ( ( lo, hi - 1 ) ) ;
728
+ return Some ( ( lo, hi - 1 , ty ) ) ;
689
729
}
690
730
}
691
731
}
@@ -700,12 +740,14 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
700
740
ranges : Vec < Constructor < ' tcx > > ,
701
741
ctor : & Constructor < ' tcx > )
702
742
-> ( Vec < Constructor < ' tcx > > , bool ) {
703
- if let Some ( ( lo1, hi1) ) = to_inc_range_pair ( cx. tcx , ctor) {
743
+ if let Some ( ( lo1, hi1, ty ) ) = to_inc_range_pair ( cx. tcx , ctor) {
704
744
let mut ctor_was_useful = false ;
705
745
// values only consists of ranges
706
746
let mut new_ranges = vec ! [ ] ;
707
747
let mut ranges: Vec < _ > =
708
- ranges. into_iter ( ) . filter_map ( |r| to_inc_range_pair ( cx. tcx , & r) ) . collect ( ) ;
748
+ ranges. into_iter ( ) . filter_map ( |r| {
749
+ to_inc_range_pair ( cx. tcx , & r) . map ( |( lo, hi, _) | ( lo, hi) )
750
+ } ) . collect ( ) ;
709
751
while let Some ( ( lo2, hi2) ) = ranges. pop ( ) {
710
752
// eprintln!("{:?} {:?}", (lo2, hi2), (lo1, hi1));
711
753
if lo1 <= lo2 && hi1 >= hi2 {
@@ -745,9 +787,9 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
745
787
}
746
788
// transform ranges to proper format
747
789
( new_ranges. into_iter ( ) . map ( |( lo, hi) | {
748
- ConstantRange ( ty:: Const :: from_usize ( cx. tcx , lo) ,
749
- ty:: Const :: from_usize ( cx. tcx , hi) ,
750
- RangeEnd :: Included )
790
+ ConstantRange ( ty:: Const :: from_bits ( cx. tcx , lo, ty ) ,
791
+ ty:: Const :: from_bits ( cx. tcx , hi, ty ) ,
792
+ RangeEnd :: Included )
751
793
} ) . collect ( ) , ctor_was_useful)
752
794
} else {
753
795
( ranges, false )
0 commit comments