@@ -641,6 +641,15 @@ impl<'tcx> Constructor<'tcx> {
641
641
IntRange :: should_treat_range_exhaustively ( tcx, ty)
642
642
}
643
643
644
+ fn is_integral_range ( & self ) -> bool {
645
+ let ty = match self {
646
+ ConstantValue ( value, _) => value. ty ,
647
+ ConstantRange ( _, _, ty, _, _) => ty,
648
+ _ => return false ,
649
+ } ;
650
+ IntRange :: is_integral ( ty)
651
+ }
652
+
644
653
fn variant_index_for_adt < ' a > (
645
654
& self ,
646
655
cx : & MatchCheckCtxt < ' a , ' tcx > ,
@@ -1471,6 +1480,12 @@ impl<'tcx> IntRange<'tcx> {
1471
1480
}
1472
1481
}
1473
1482
1483
+ fn is_subrange ( & self , other : & Self ) -> bool {
1484
+ let ( lo, hi) = ( * self . range . start ( ) , * self . range . end ( ) ) ;
1485
+ let ( other_lo, other_hi) = ( * other. range . start ( ) , * other. range . end ( ) ) ;
1486
+ other_lo <= lo && hi <= other_hi
1487
+ }
1488
+
1474
1489
fn suspicious_intersection ( & self , other : & Self ) -> bool {
1475
1490
// `false` in the following cases:
1476
1491
// 1 ---- // 1 ---------- // 1 ---- // 1 ----
@@ -2300,13 +2315,25 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
2300
2315
IntRange :: from_pat ( cx. tcx , cx. param_env , pat) ,
2301
2316
) {
2302
2317
( Some ( ctor) , Some ( pat) ) => ctor. intersection ( & pat) . map ( |_| {
2318
+ // Constructor splitting should ensure that all intersections we encounter
2319
+ // are actually inclusions.
2303
2320
let ( pat_lo, pat_hi) = pat. range . into_inner ( ) ;
2304
2321
let ( ctor_lo, ctor_hi) = ctor. range . into_inner ( ) ;
2305
2322
assert ! ( pat_lo <= ctor_lo && ctor_hi <= pat_hi) ;
2306
2323
PatStack :: default ( )
2307
2324
} ) ,
2308
2325
_ => None ,
2309
2326
}
2327
+ } else if constructor. is_integral_range ( ) {
2328
+ // If we have an integer range that should not be matched exhaustively, fallback to
2329
+ // checking for inclusion.
2330
+ match (
2331
+ IntRange :: from_ctor ( cx. tcx , cx. param_env , constructor) ,
2332
+ IntRange :: from_pat ( cx. tcx , cx. param_env , pat) ,
2333
+ ) {
2334
+ ( Some ( ctor) , Some ( pat) ) if ctor. is_subrange ( & pat) => Some ( PatStack :: default ( ) ) ,
2335
+ _ => None ,
2336
+ }
2310
2337
} else {
2311
2338
// Fallback for non-ranges and ranges that involve
2312
2339
// floating-point numbers, which are not conveniently handled
0 commit comments