@@ -834,44 +834,69 @@ struct IntRange<'tcx> {
834
834
}
835
835
836
836
impl < ' tcx > IntRange < ' tcx > {
837
+ #[ inline]
838
+ fn is_integral ( ty : Ty < ' _ > ) -> bool {
839
+ match ty. kind {
840
+ ty:: Char | ty:: Int ( _) | ty:: Uint ( _) => true ,
841
+ _ => false ,
842
+ }
843
+ }
844
+
845
+ #[ inline]
846
+ fn from_const (
847
+ tcx : TyCtxt < ' tcx > ,
848
+ param_env : ty:: ParamEnv < ' tcx > ,
849
+ value : & Const < ' tcx > ,
850
+ ) -> Option < IntRange < ' tcx > > {
851
+ if Self :: is_integral ( value. ty ) {
852
+ let ty = value. ty ;
853
+ if let Some ( val) = value. try_eval_bits ( tcx, param_env, ty) {
854
+ let bias = IntRange :: signed_bias ( tcx, ty) ;
855
+ let val = val ^ bias;
856
+ Some ( IntRange { range : val..=val, ty } )
857
+ } else {
858
+ None
859
+ }
860
+ } else {
861
+ None
862
+ }
863
+ }
864
+
865
+ #[ inline]
866
+ fn from_range (
867
+ tcx : TyCtxt < ' tcx > ,
868
+ lo : u128 ,
869
+ hi : u128 ,
870
+ ty : Ty < ' tcx > ,
871
+ end : & RangeEnd ,
872
+ ) -> Option < IntRange < ' tcx > > {
873
+ if Self :: is_integral ( ty) {
874
+ // Perform a shift if the underlying types are signed,
875
+ // which makes the interval arithmetic simpler.
876
+ let bias = IntRange :: signed_bias ( tcx, ty) ;
877
+ let ( lo, hi) = ( lo ^ bias, hi ^ bias) ;
878
+ // Make sure the interval is well-formed.
879
+ if lo > hi || lo == hi && * end == RangeEnd :: Excluded {
880
+ None
881
+ } else {
882
+ let offset = ( * end == RangeEnd :: Excluded ) as u128 ;
883
+ Some ( IntRange { range : lo..=( hi - offset) , ty } )
884
+ }
885
+ } else {
886
+ None
887
+ }
888
+ }
889
+
837
890
fn from_ctor (
838
891
tcx : TyCtxt < ' tcx > ,
839
892
param_env : ty:: ParamEnv < ' tcx > ,
840
893
ctor : & Constructor < ' tcx > ,
841
894
) -> Option < IntRange < ' tcx > > {
842
895
// Floating-point ranges are permitted and we don't want
843
896
// to consider them when constructing integer ranges.
844
- fn is_integral ( ty : Ty < ' _ > ) -> bool {
845
- match ty. kind {
846
- ty:: Char | ty:: Int ( _) | ty:: Uint ( _) => true ,
847
- _ => false ,
848
- }
849
- }
850
-
851
897
match ctor {
852
- ConstantRange ( lo, hi, ty, end) if is_integral ( ty) => {
853
- // Perform a shift if the underlying types are signed,
854
- // which makes the interval arithmetic simpler.
855
- let bias = IntRange :: signed_bias ( tcx, ty) ;
856
- let ( lo, hi) = ( lo ^ bias, hi ^ bias) ;
857
- // Make sure the interval is well-formed.
858
- if lo > hi || lo == hi && * end == RangeEnd :: Excluded {
859
- None
860
- } else {
861
- let offset = ( * end == RangeEnd :: Excluded ) as u128 ;
862
- Some ( IntRange { range : lo..=( hi - offset) , ty } )
863
- }
864
- }
865
- ConstantValue ( val) if is_integral ( val. ty ) => {
866
- let ty = val. ty ;
867
- if let Some ( val) = val. try_eval_bits ( tcx, param_env, ty) {
868
- let bias = IntRange :: signed_bias ( tcx, ty) ;
869
- let val = val ^ bias;
870
- Some ( IntRange { range : val..=val, ty } )
871
- } else {
872
- None
873
- }
874
- }
898
+ ConstantRange ( lo, hi, ty, end) => Self :: from_range ( tcx, * lo, * hi, ty, end) ,
899
+ ConstantValue ( val) => Self :: from_const ( tcx, param_env, val) ,
875
900
_ => None ,
876
901
}
877
902
}
@@ -881,22 +906,26 @@ impl<'tcx> IntRange<'tcx> {
881
906
param_env : ty:: ParamEnv < ' tcx > ,
882
907
mut pat : & Pat < ' tcx > ,
883
908
) -> Option < IntRange < ' tcx > > {
884
- let range = loop {
909
+ loop {
885
910
match pat. kind {
886
- box PatKind :: Constant { value } => break ConstantValue ( value) ,
887
- box PatKind :: Range ( PatRange { lo, hi, end } ) => break ConstantRange (
888
- lo. eval_bits ( tcx, param_env, lo. ty ) ,
889
- hi. eval_bits ( tcx, param_env, hi. ty ) ,
890
- lo. ty ,
891
- end,
892
- ) ,
911
+ box PatKind :: Constant { value } => {
912
+ return Self :: from_const ( tcx, param_env, value) ;
913
+ }
914
+ box PatKind :: Range ( PatRange { lo, hi, end } ) => {
915
+ return Self :: from_range (
916
+ tcx,
917
+ lo. eval_bits ( tcx, param_env, lo. ty ) ,
918
+ hi. eval_bits ( tcx, param_env, hi. ty ) ,
919
+ & lo. ty ,
920
+ & end,
921
+ ) ;
922
+ }
893
923
box PatKind :: AscribeUserType { ref subpattern, .. } => {
894
924
pat = subpattern;
895
925
} ,
896
926
_ => return None ,
897
927
}
898
- } ;
899
- Self :: from_ctor ( tcx, param_env, & range)
928
+ }
900
929
}
901
930
902
931
// The return value of `signed_bias` should be XORed with an endpoint to encode/decode it.
0 commit comments