@@ -590,7 +590,10 @@ enum Constructor<'tcx> {
590
590
Variant ( DefId ) ,
591
591
/// Literal values.
592
592
ConstantValue ( & ' tcx ty:: Const < ' tcx > , Span ) ,
593
- /// Ranges of literal values (`2..=5` and `2..5`).
593
+ /// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
594
+ IntRange ( IntRange < ' tcx > ) ,
595
+ // TODO: non-integer
596
+ /// Ranges of literal values (`2.0..=5.2`).
594
597
ConstantRange ( u128 , u128 , Ty < ' tcx > , RangeEnd , Span ) ,
595
598
/// Array patterns of length `n`.
596
599
FixedLenSlice ( u64 ) ,
@@ -612,6 +615,7 @@ impl<'tcx> std::cmp::PartialEq for Constructor<'tcx> {
612
615
Constructor :: ConstantRange ( a_start, a_end, a_ty, a_range_end, _) ,
613
616
Constructor :: ConstantRange ( b_start, b_end, b_ty, b_range_end, _) ,
614
617
) => a_start == b_start && a_end == b_end && a_ty == b_ty && a_range_end == b_range_end,
618
+ ( Constructor :: IntRange ( a) , Constructor :: IntRange ( b) ) => a == b,
615
619
( Constructor :: FixedLenSlice ( a) , Constructor :: FixedLenSlice ( b) ) => a == b,
616
620
(
617
621
Constructor :: VarLenSlice ( a_prefix, a_suffix) ,
@@ -634,6 +638,7 @@ impl<'tcx> Constructor<'tcx> {
634
638
let ty = match self {
635
639
ConstantValue ( value, _) => value. ty ,
636
640
ConstantRange ( _, _, ty, _, _) => ty,
641
+ IntRange ( _) => return true ,
637
642
_ => return false ,
638
643
} ;
639
644
IntRange :: is_integral ( ty)
@@ -743,7 +748,7 @@ impl<'tcx> Constructor<'tcx> {
743
748
744
749
remaining_ctors
745
750
}
746
- ConstantRange ( ..) | ConstantValue ( ..) => {
751
+ IntRange ( .. ) | ConstantRange ( ..) | ConstantValue ( ..) => {
747
752
if let Some ( self_range) = IntRange :: from_ctor ( tcx, param_env, self ) {
748
753
let mut remaining_ranges = vec ! [ self_range. clone( ) ] ;
749
754
let other_ranges = other_ctors
@@ -767,7 +772,7 @@ impl<'tcx> Constructor<'tcx> {
767
772
}
768
773
769
774
// Convert the ranges back into constructors
770
- remaining_ranges. into_iter ( ) . map ( |range| range . into_ctor ( tcx ) ) . collect ( )
775
+ remaining_ranges. into_iter ( ) . map ( IntRange ) . collect ( )
771
776
} else {
772
777
if other_ctors. iter ( ) . any ( |c| {
773
778
c == self
@@ -855,7 +860,7 @@ impl<'tcx> Constructor<'tcx> {
855
860
}
856
861
_ => bug ! ( "bad slice pattern {:?} {:?}" , self , ty) ,
857
862
} ,
858
- ConstantValue ( ..) | ConstantRange ( ..) | NonExhaustive => vec ! [ ] ,
863
+ ConstantValue ( ..) | ConstantRange ( ..) | IntRange ( .. ) | NonExhaustive => vec ! [ ] ,
859
864
}
860
865
}
861
866
@@ -880,7 +885,7 @@ impl<'tcx> Constructor<'tcx> {
880
885
} ,
881
886
FixedLenSlice ( length) => * length,
882
887
VarLenSlice ( prefix, suffix) => prefix + suffix,
883
- ConstantValue ( ..) | ConstantRange ( ..) | NonExhaustive => 0 ,
888
+ ConstantValue ( ..) | ConstantRange ( ..) | IntRange ( .. ) | NonExhaustive => 0 ,
884
889
}
885
890
}
886
891
@@ -949,6 +954,10 @@ impl<'tcx> Constructor<'tcx> {
949
954
hi : ty:: Const :: from_bits ( cx. tcx , hi, ty:: ParamEnv :: empty ( ) . and ( ty) ) ,
950
955
end,
951
956
} ) ,
957
+ IntRange ( range) => {
958
+ // TODO: do it more directly
959
+ return range. clone ( ) . into_ctor ( cx. tcx ) . apply ( cx, ty, None . into_iter ( ) ) ;
960
+ }
952
961
NonExhaustive => PatKind :: Wild ,
953
962
} ;
954
963
@@ -1145,7 +1154,14 @@ fn all_constructors<'a, 'tcx>(
1145
1154
pcx : PatCtxt < ' tcx > ,
1146
1155
) -> Vec < Constructor < ' tcx > > {
1147
1156
debug ! ( "all_constructors({:?})" , pcx. ty) ;
1148
- let make_range = |start, end| ConstantRange ( start, end, pcx. ty , RangeEnd :: Included , pcx. span ) ;
1157
+ let make_range = |start, end| {
1158
+ IntRange (
1159
+ // `unwrap()` is ok because we know the type is an integer and the range is
1160
+ // well-formed.
1161
+ IntRange :: from_range ( cx. tcx , start, end, pcx. ty , & RangeEnd :: Included , pcx. span )
1162
+ . unwrap ( ) ,
1163
+ )
1164
+ } ;
1149
1165
match pcx. ty . kind {
1150
1166
ty:: Bool => [ true , false ]
1151
1167
. iter ( )
@@ -1356,6 +1372,7 @@ impl<'tcx> IntRange<'tcx> {
1356
1372
match ctor {
1357
1373
ConstantRange ( lo, hi, ty, end, span) => Self :: from_range ( tcx, * lo, * hi, ty, end, * span) ,
1358
1374
ConstantValue ( val, span) => Self :: from_const ( tcx, param_env, val, * span) ,
1375
+ IntRange ( range) => Some ( range. clone ( ) ) ,
1359
1376
_ => None ,
1360
1377
}
1361
1378
}
@@ -1381,6 +1398,7 @@ impl<'tcx> IntRange<'tcx> {
1381
1398
}
1382
1399
1383
1400
/// Converts an `IntRange` to a `ConstantValue` or inclusive `ConstantRange`.
1401
+ /// TODO: Deprecated
1384
1402
fn into_ctor ( self , tcx : TyCtxt < ' tcx > ) -> Constructor < ' tcx > {
1385
1403
let bias = IntRange :: signed_bias ( tcx, self . ty ) ;
1386
1404
let ( lo, hi) = self . range . into_inner ( ) ;
@@ -1889,7 +1907,9 @@ fn split_grouped_constructors<'p, 'tcx>(
1889
1907
1890
1908
for ctor in ctors. into_iter ( ) {
1891
1909
match ctor {
1892
- ConstantRange ( ..) if IntRange :: should_treat_range_exhaustively ( tcx, ty) => {
1910
+ IntRange ( ..) | ConstantRange ( ..)
1911
+ if IntRange :: should_treat_range_exhaustively ( tcx, ty) =>
1912
+ {
1893
1913
// We only care about finding all the subranges within the range of the constructor
1894
1914
// range. Anything else is irrelevant, because it is guaranteed to result in
1895
1915
// `NotUseful`, which is the default case anyway, and can be ignored.
@@ -1968,7 +1988,7 @@ fn split_grouped_constructors<'p, 'tcx>(
1968
1988
}
1969
1989
( Border :: AfterMax , _) => None ,
1970
1990
} )
1971
- . map ( |range| range . into_ctor ( tcx ) ) ,
1991
+ . map ( IntRange ) ,
1972
1992
) ;
1973
1993
}
1974
1994
VarLenSlice ( self_prefix, self_suffix) => {
0 commit comments