@@ -21,11 +21,13 @@ use super::{PatternFoldable, PatternFolder, compare_const_vals};
21
21
use rustc:: hir:: def_id:: DefId ;
22
22
use rustc:: hir:: RangeEnd ;
23
23
use rustc:: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
24
+ use rustc:: ty:: layout:: { Integer , IntegerExt } ;
24
25
25
26
use rustc:: mir:: Field ;
26
27
use rustc:: mir:: interpret:: ConstValue ;
27
28
use rustc:: util:: common:: ErrorReported ;
28
29
30
+ use syntax:: attr:: { SignedInt , UnsignedInt } ;
29
31
use syntax_pos:: { Span , DUMMY_SP } ;
30
32
31
33
use arena:: TypedArena ;
@@ -469,21 +471,19 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
469
471
ConstantRange ( endpoint( '\u{E000}' ) , endpoint( '\u{10FFFF}' ) , RangeEnd :: Included ) ,
470
472
]
471
473
}
472
- ty:: TyInt ( _ ) if exhaustive_integer_patterns => {
474
+ ty:: TyInt ( ity ) if exhaustive_integer_patterns => {
473
475
// FIXME(49937): refactor these bit manipulations into interpret.
474
- let bits = cx. tcx . layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( pcx. ty ) )
475
- . unwrap ( ) . size . bits ( ) as u128 ;
476
+ let bits = Integer :: from_attr ( cx. tcx , SignedInt ( ity) ) . size ( ) . bits ( ) as u128 ;
476
477
let min = 1u128 << ( bits - 1 ) ;
477
478
let max = ( 1u128 << ( bits - 1 ) ) - 1 ;
478
479
value_constructors = true ;
479
480
vec ! [ ConstantRange ( ty:: Const :: from_bits( cx. tcx, min as u128 , pcx. ty) ,
480
481
ty:: Const :: from_bits( cx. tcx, max as u128 , pcx. ty) ,
481
482
RangeEnd :: Included ) ]
482
483
}
483
- ty:: TyUint ( _ ) if exhaustive_integer_patterns => {
484
+ ty:: TyUint ( uty ) if exhaustive_integer_patterns => {
484
485
// FIXME(49937): refactor these bit manipulations into interpret.
485
- let bits = cx. tcx . layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( pcx. ty ) )
486
- . unwrap ( ) . size . bits ( ) as u128 ;
486
+ let bits = Integer :: from_attr ( cx. tcx , UnsignedInt ( uty) ) . size ( ) . bits ( ) as u128 ;
487
487
let max = !0u128 >> ( 128 - bits) ;
488
488
value_constructors = true ;
489
489
vec ! [ ConstantRange ( ty:: Const :: from_bits( cx. tcx, 0 , pcx. ty) ,
@@ -627,7 +627,8 @@ impl<'tcx> IntRange<'tcx> {
627
627
if let Some ( hi) = hi. assert_bits ( ty) {
628
628
// Perform a shift if the underlying types are signed,
629
629
// which makes the interval arithmetic simpler.
630
- let ( lo, hi) = Self :: encode ( tcx, ty, ( lo, hi) ) ;
630
+ let bias = IntRange :: signed_bias ( tcx, ty) ;
631
+ let ( lo, hi) = ( lo ^ bias, hi ^ bias) ;
631
632
// Make sure the interval is well-formed.
632
633
return if lo > hi || lo == hi && * end == RangeEnd :: Excluded {
633
634
None
@@ -642,8 +643,9 @@ impl<'tcx> IntRange<'tcx> {
642
643
ConstantValue ( val) => {
643
644
let ty = val. ty ;
644
645
if let Some ( val) = val. assert_bits ( ty) {
645
- let ( lo, hi) = Self :: encode ( tcx, ty, ( val, val) ) ;
646
- Some ( IntRange { range : lo..=hi, ty } )
646
+ let bias = IntRange :: signed_bias ( tcx, ty) ;
647
+ let val = val ^ bias;
648
+ Some ( IntRange { range : val..=val, ty } )
647
649
} else {
648
650
None
649
651
}
@@ -654,46 +656,16 @@ impl<'tcx> IntRange<'tcx> {
654
656
}
655
657
}
656
658
657
- fn encode ( tcx : TyCtxt < ' _ , ' tcx , ' tcx > ,
658
- ty : Ty < ' tcx > ,
659
- ( lo, hi) : ( u128 , u128 ) )
660
- -> ( u128 , u128 ) {
659
+ fn signed_bias ( tcx : TyCtxt < ' _ , ' tcx , ' tcx > , ty : Ty < ' tcx > ) -> u128 {
661
660
match ty. sty {
662
- ty:: TyInt ( _) => {
663
- // FIXME(49937): refactor these bit manipulations into interpret.
664
- let bits = tcx. layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( ty) )
665
- . unwrap ( ) . size . bits ( ) as u128 ;
666
- let min = 1u128 << ( bits - 1 ) ;
667
- let mask = !0u128 >> ( 128 - bits) ;
668
- let offset = |x : u128 | x. wrapping_sub ( min) & mask;
669
- ( offset ( lo) , offset ( hi) )
661
+ ty:: TyInt ( ity) => {
662
+ let bits = Integer :: from_attr ( tcx, SignedInt ( ity) ) . size ( ) . bits ( ) as u128 ;
663
+ 1u128 << ( bits - 1 )
670
664
}
671
- _ => ( lo , hi )
665
+ _ => 0
672
666
}
673
667
}
674
668
675
- fn decode ( tcx : TyCtxt < ' _ , ' tcx , ' tcx > ,
676
- ty : Ty < ' tcx > ,
677
- range : RangeInclusive < u128 > )
678
- -> Constructor < ' tcx > {
679
- let ( lo, hi) = range. into_inner ( ) ;
680
- let ( lo, hi) = match ty. sty {
681
- ty:: TyInt ( _) => {
682
- // FIXME(49937): refactor these bit manipulations into interpret.
683
- let bits = tcx. layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( ty) )
684
- . unwrap ( ) . size . bits ( ) as u128 ;
685
- let min = 1u128 << ( bits - 1 ) ;
686
- let mask = !0u128 >> ( 128 - bits) ;
687
- let offset = |x : u128 | x. wrapping_add ( min) & mask;
688
- ( offset ( lo) , offset ( hi) )
689
- }
690
- _ => ( lo, hi)
691
- } ;
692
- ConstantRange ( ty:: Const :: from_bits ( tcx, lo, ty) ,
693
- ty:: Const :: from_bits ( tcx, hi, ty) ,
694
- RangeEnd :: Included )
695
- }
696
-
697
669
fn into_inner ( self ) -> ( u128 , u128 ) {
698
670
self . range . into_inner ( )
699
671
}
@@ -733,7 +705,11 @@ fn ranges_subtract_pattern<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
733
705
}
734
706
// Convert the remaining ranges from pairs to inclusive `ConstantRange`s.
735
707
remaining_ranges. into_iter ( ) . map ( |r| {
736
- IntRange :: decode ( cx. tcx , ty, r)
708
+ let ( lo, hi) = r. into_inner ( ) ;
709
+ let bias = IntRange :: signed_bias ( cx. tcx , ty) ;
710
+ ConstantRange ( ty:: Const :: from_bits ( cx. tcx , lo ^ bias, ty) ,
711
+ ty:: Const :: from_bits ( cx. tcx , hi ^ bias, ty) ,
712
+ RangeEnd :: Included )
737
713
} ) . collect ( )
738
714
} else {
739
715
ranges
0 commit comments