@@ -814,17 +814,21 @@ impl<'tcx> PatRange<'tcx> {
814
814
//
815
815
// Also, for performance, it's important to only do the second `try_to_bits` if necessary.
816
816
let lo_is_min = match self . lo {
817
+ PatRangeBoundary :: NegInfinity => true ,
817
818
PatRangeBoundary :: Finite ( value) => {
818
819
let lo = value. try_to_bits ( size) . unwrap ( ) ^ bias;
819
820
lo <= min
820
821
}
822
+ PatRangeBoundary :: PosInfinity => false ,
821
823
} ;
822
824
if lo_is_min {
823
825
let hi_is_max = match self . hi {
826
+ PatRangeBoundary :: NegInfinity => false ,
824
827
PatRangeBoundary :: Finite ( value) => {
825
828
let hi = value. try_to_bits ( size) . unwrap ( ) ^ bias;
826
829
hi > max || hi == max && self . end == RangeEnd :: Included
827
830
}
831
+ PatRangeBoundary :: PosInfinity => true ,
828
832
} ;
829
833
if hi_is_max {
830
834
return Some ( true ) ;
@@ -883,11 +887,13 @@ impl<'tcx> PatRange<'tcx> {
883
887
884
888
impl < ' tcx > fmt:: Display for PatRange < ' tcx > {
885
889
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
886
- let PatRangeBoundary :: Finite ( value) = & self . lo ;
887
- write ! ( f, "{value}" ) ?;
890
+ if let PatRangeBoundary :: Finite ( value) = & self . lo {
891
+ write ! ( f, "{value}" ) ?;
892
+ }
888
893
write ! ( f, "{}" , self . end) ?;
889
- let PatRangeBoundary :: Finite ( value) = & self . hi ;
890
- write ! ( f, "{value}" ) ?;
894
+ if let PatRangeBoundary :: Finite ( value) = & self . hi {
895
+ write ! ( f, "{value}" ) ?;
896
+ }
891
897
Ok ( ( ) )
892
898
}
893
899
}
@@ -897,38 +903,49 @@ impl<'tcx> fmt::Display for PatRange<'tcx> {
897
903
#[ derive( Copy , Clone , Debug , PartialEq , HashStable , TypeVisitable ) ]
898
904
pub enum PatRangeBoundary < ' tcx > {
899
905
Finite ( mir:: Const < ' tcx > ) ,
906
+ NegInfinity ,
907
+ PosInfinity ,
900
908
}
901
909
902
910
impl < ' tcx > PatRangeBoundary < ' tcx > {
903
911
#[ inline]
904
- pub fn lower_bound ( ty : Ty < ' tcx > , tcx : TyCtxt < ' tcx > ) -> Self {
905
- // Unwrap is ok because the type is known to be numeric.
906
- let c = ty. numeric_min_val ( tcx) . unwrap ( ) ;
907
- let value = mir:: Const :: from_ty_const ( c, tcx) ;
908
- Self :: Finite ( value)
912
+ pub fn is_finite ( self ) -> bool {
913
+ matches ! ( self , Self :: Finite ( ..) )
909
914
}
910
915
#[ inline]
911
- pub fn upper_bound ( ty : Ty < ' tcx > , tcx : TyCtxt < ' tcx > ) -> Self {
912
- // Unwrap is ok because the type is known to be numeric.
913
- let c = ty . numeric_max_val ( tcx ) . unwrap ( ) ;
914
- let value = mir :: Const :: from_ty_const ( c , tcx ) ;
915
- Self :: Finite ( value )
916
+ pub fn as_finite ( self ) -> Option < mir :: Const < ' tcx > > {
917
+ match self {
918
+ Self :: Finite ( value ) => Some ( value ) ,
919
+ Self :: NegInfinity | Self :: PosInfinity => None ,
920
+ }
916
921
}
917
-
918
922
#[ inline]
919
- pub fn to_const ( self , _ty : Ty < ' tcx > , _tcx : TyCtxt < ' tcx > ) -> mir:: Const < ' tcx > {
923
+ pub fn to_const ( self , ty : Ty < ' tcx > , tcx : TyCtxt < ' tcx > ) -> mir:: Const < ' tcx > {
920
924
match self {
921
925
Self :: Finite ( value) => value,
926
+ Self :: NegInfinity => {
927
+ // Unwrap is ok because the type is known to be numeric.
928
+ let c = ty. numeric_min_val ( tcx) . unwrap ( ) ;
929
+ mir:: Const :: from_ty_const ( c, tcx)
930
+ }
931
+ Self :: PosInfinity => {
932
+ // Unwrap is ok because the type is known to be numeric.
933
+ let c = ty. numeric_max_val ( tcx) . unwrap ( ) ;
934
+ mir:: Const :: from_ty_const ( c, tcx)
935
+ }
922
936
}
923
937
}
924
- pub fn eval_bits (
925
- self ,
926
- _ty : Ty < ' tcx > ,
927
- tcx : TyCtxt < ' tcx > ,
928
- param_env : ty:: ParamEnv < ' tcx > ,
929
- ) -> u128 {
938
+ pub fn eval_bits ( self , ty : Ty < ' tcx > , tcx : TyCtxt < ' tcx > , param_env : ty:: ParamEnv < ' tcx > ) -> u128 {
930
939
match self {
931
940
Self :: Finite ( value) => value. eval_bits ( tcx, param_env) ,
941
+ Self :: NegInfinity => {
942
+ // Unwrap is ok because the type is known to be numeric.
943
+ ty. numeric_min_and_max_as_bits ( tcx) . unwrap ( ) . 0
944
+ }
945
+ Self :: PosInfinity => {
946
+ // Unwrap is ok because the type is known to be numeric.
947
+ ty. numeric_min_and_max_as_bits ( tcx) . unwrap ( ) . 1
948
+ }
932
949
}
933
950
}
934
951
@@ -942,6 +959,9 @@ impl<'tcx> PatRangeBoundary<'tcx> {
942
959
) -> Option < Ordering > {
943
960
use PatRangeBoundary :: * ;
944
961
match ( self , other) {
962
+ ( PosInfinity , PosInfinity ) => return Some ( Ordering :: Equal ) ,
963
+ ( NegInfinity , NegInfinity ) => return Some ( Ordering :: Equal ) ,
964
+
945
965
// This code is hot when compiling matches with many ranges. So we
946
966
// special-case extraction of evaluated scalars for speed, for types where
947
967
// raw data comparisons are appropriate. E.g. `unicode-normalization` has
0 commit comments