@@ -630,6 +630,17 @@ impl<'tcx> Constructor<'tcx> {
630
630
}
631
631
}
632
632
633
+ // Whether to evaluate a constructor using exhaustive integer matching. This is true if the
634
+ // constructor is a range or constant with an integer type.
635
+ fn is_range_and_should_match_exhaustively ( & self , tcx : TyCtxt < ' tcx > ) -> bool {
636
+ let ty = match self {
637
+ ConstantValue ( value, _) => value. ty ,
638
+ ConstantRange ( _, _, ty, _, _) => ty,
639
+ _ => return false ,
640
+ } ;
641
+ IntRange :: should_treat_range_exhaustively ( tcx, ty)
642
+ }
643
+
633
644
fn variant_index_for_adt < ' a > (
634
645
& self ,
635
646
cx : & MatchCheckCtxt < ' a , ' tcx > ,
@@ -1280,6 +1291,13 @@ impl<'tcx> IntRange<'tcx> {
1280
1291
}
1281
1292
}
1282
1293
1294
+ fn should_treat_range_exhaustively ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> bool {
1295
+ // Don't treat `usize`/`isize` exhaustively unless the `precise_pointer_size_matching`
1296
+ // feature is enabled.
1297
+ IntRange :: is_integral ( ty)
1298
+ && ( !ty. is_ptr_sized_integral ( ) || tcx. features ( ) . precise_pointer_size_matching )
1299
+ }
1300
+
1283
1301
#[ inline]
1284
1302
fn integral_size_and_signed_bias ( tcx : TyCtxt < ' tcx > , ty : Ty < ' _ > ) -> Option < ( Size , u128 ) > {
1285
1303
match ty. kind {
@@ -1857,21 +1875,6 @@ fn slice_pat_covered_by_const<'tcx>(
1857
1875
Ok ( true )
1858
1876
}
1859
1877
1860
- // Whether to evaluate a constructor using exhaustive integer matching. This is true if the
1861
- // constructor is a range or constant with an integer type.
1862
- fn should_treat_range_exhaustively ( tcx : TyCtxt < ' tcx > , ctor : & Constructor < ' tcx > ) -> bool {
1863
- let ty = match ctor {
1864
- ConstantValue ( value, _) => value. ty ,
1865
- ConstantRange ( _, _, ty, _, _) => ty,
1866
- _ => return false ,
1867
- } ;
1868
- if let ty:: Char | ty:: Int ( _) | ty:: Uint ( _) = ty. kind {
1869
- !ty. is_ptr_sized_integral ( ) || tcx. features ( ) . precise_pointer_size_matching
1870
- } else {
1871
- false
1872
- }
1873
- }
1874
-
1875
1878
/// For exhaustive integer matching, some constructors are grouped within other constructors
1876
1879
/// (namely integer typed values are grouped within ranges). However, when specialising these
1877
1880
/// constructors, we want to be specialising for the underlying constructors (the integers), not
@@ -1923,7 +1926,7 @@ fn split_grouped_constructors<'p, 'tcx>(
1923
1926
1924
1927
for ctor in ctors. into_iter ( ) {
1925
1928
match ctor {
1926
- ConstantRange ( ..) if should_treat_range_exhaustively ( tcx, & ctor ) => {
1929
+ ConstantRange ( ..) if ctor . is_range_and_should_match_exhaustively ( tcx) => {
1927
1930
// We only care about finding all the subranges within the range of the constructor
1928
1931
// range. Anything else is irrelevant, because it is guaranteed to result in
1929
1932
// `NotUseful`, which is the default case anyway, and can be ignored.
@@ -2342,7 +2345,7 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
2342
2345
// If the constructor is a:
2343
2346
// - Single value: add a row if the pattern contains the constructor.
2344
2347
// - Range: add a row if the constructor intersects the pattern.
2345
- if should_treat_range_exhaustively ( cx. tcx , constructor ) {
2348
+ if constructor . is_range_and_should_match_exhaustively ( cx. tcx ) {
2346
2349
match (
2347
2350
IntRange :: from_ctor ( cx. tcx , cx. param_env , constructor) ,
2348
2351
IntRange :: from_pat ( cx. tcx , cx. param_env , pat) ,
0 commit comments