@@ -649,12 +649,7 @@ impl<'tcx> Constructor<'tcx> {
649
649
650
650
// Returns the set of constructors covered by `self` but not by
651
651
// anything in `other_ctors`.
652
- fn subtract_ctors (
653
- & self ,
654
- tcx : TyCtxt < ' tcx > ,
655
- param_env : ty:: ParamEnv < ' tcx > ,
656
- other_ctors : & Vec < Constructor < ' tcx > > ,
657
- ) -> Vec < Constructor < ' tcx > > {
652
+ fn subtract_ctors ( & self , other_ctors : & Vec < Constructor < ' tcx > > ) -> Vec < Constructor < ' tcx > > {
658
653
match self {
659
654
// Those constructors can only match themselves.
660
655
Single | Variant ( _) => {
@@ -737,22 +732,22 @@ impl<'tcx> Constructor<'tcx> {
737
732
}
738
733
IntRange ( self_range) => {
739
734
let mut remaining_ranges = vec ! [ self_range. clone( ) ] ;
740
- let other_ranges =
741
- other_ctors. into_iter ( ) . filter_map ( |c| IntRange :: from_ctor ( tcx, param_env, c) ) ;
742
- for other_range in other_ranges {
743
- if other_range == * self_range {
744
- // If the `self` range appears directly in a `match` arm, we can
745
- // eliminate it straight away.
746
- remaining_ranges = vec ! [ ] ;
747
- } else {
748
- // Otherwise explicitely compute the remaining ranges.
749
- remaining_ranges = other_range. subtract_from ( remaining_ranges) ;
750
- }
735
+ for other_ctor in other_ctors {
736
+ if let IntRange ( other_range) = other_ctor {
737
+ if other_range == self_range {
738
+ // If the `self` range appears directly in a `match` arm, we can
739
+ // eliminate it straight away.
740
+ remaining_ranges = vec ! [ ] ;
741
+ } else {
742
+ // Otherwise explicitely compute the remaining ranges.
743
+ remaining_ranges = other_range. subtract_from ( remaining_ranges) ;
744
+ }
751
745
752
- // If the ranges that have been considered so far already cover the entire
753
- // range of values, we can return early.
754
- if remaining_ranges. is_empty ( ) {
755
- break ;
746
+ // If the ranges that have been considered so far already cover the entire
747
+ // range of values, we can return early.
748
+ if remaining_ranges. is_empty ( ) {
749
+ break ;
750
+ }
756
751
}
757
752
}
758
753
@@ -763,7 +758,7 @@ impl<'tcx> Constructor<'tcx> {
763
758
if other_ctors. iter ( ) . any ( |c| {
764
759
c == self
765
760
// FIXME(Nadrieril): This condition looks fishy
766
- || IntRange :: from_ctor ( tcx , param_env , c ) . is_some ( )
761
+ || c . is_integral_range ( )
767
762
} ) {
768
763
vec ! [ ]
769
764
} else {
@@ -1310,26 +1305,15 @@ impl<'tcx> IntRange<'tcx> {
1310
1305
}
1311
1306
}
1312
1307
1313
- fn from_ctor (
1314
- _tcx : TyCtxt < ' tcx > ,
1315
- _param_env : ty:: ParamEnv < ' tcx > ,
1316
- ctor : & Constructor < ' tcx > ,
1317
- ) -> Option < IntRange < ' tcx > > {
1318
- // Floating-point ranges are permitted and we don't want
1319
- // to consider them when constructing integer ranges.
1320
- match ctor {
1321
- IntRange ( range) => Some ( range. clone ( ) ) ,
1322
- _ => None ,
1323
- }
1324
- }
1325
-
1326
1308
fn from_pat (
1327
1309
tcx : TyCtxt < ' tcx > ,
1328
1310
param_env : ty:: ParamEnv < ' tcx > ,
1329
1311
pat : & Pat < ' tcx > ,
1330
1312
) -> Option < IntRange < ' tcx > > {
1331
- let ctor = pat_constructor ( tcx, param_env, pat) ?;
1332
- IntRange :: from_ctor ( tcx, param_env, & ctor)
1313
+ match pat_constructor ( tcx, param_env, pat) ? {
1314
+ IntRange ( range) => Some ( range) ,
1315
+ _ => None ,
1316
+ }
1333
1317
}
1334
1318
1335
1319
// The return value of `signed_bias` should be XORed with an endpoint to encode/decode it.
@@ -1436,20 +1420,13 @@ impl<'tcx> std::cmp::PartialEq for IntRange<'tcx> {
1436
1420
1437
1421
// A struct to compute a set of constructors equivalent to `all_ctors \ used_ctors`.
1438
1422
struct MissingConstructors < ' tcx > {
1439
- tcx : TyCtxt < ' tcx > ,
1440
- param_env : ty:: ParamEnv < ' tcx > ,
1441
1423
all_ctors : Vec < Constructor < ' tcx > > ,
1442
1424
used_ctors : Vec < Constructor < ' tcx > > ,
1443
1425
}
1444
1426
1445
1427
impl < ' tcx > MissingConstructors < ' tcx > {
1446
- fn new (
1447
- tcx : TyCtxt < ' tcx > ,
1448
- param_env : ty:: ParamEnv < ' tcx > ,
1449
- all_ctors : Vec < Constructor < ' tcx > > ,
1450
- used_ctors : Vec < Constructor < ' tcx > > ,
1451
- ) -> Self {
1452
- MissingConstructors { tcx, param_env, all_ctors, used_ctors }
1428
+ fn new ( all_ctors : Vec < Constructor < ' tcx > > , used_ctors : Vec < Constructor < ' tcx > > ) -> Self {
1429
+ MissingConstructors { all_ctors, used_ctors }
1453
1430
}
1454
1431
1455
1432
fn into_inner ( self ) -> ( Vec < Constructor < ' tcx > > , Vec < Constructor < ' tcx > > ) {
@@ -1467,9 +1444,7 @@ impl<'tcx> MissingConstructors<'tcx> {
1467
1444
1468
1445
/// Iterate over all_ctors \ used_ctors
1469
1446
fn iter < ' a > ( & ' a self ) -> impl Iterator < Item = Constructor < ' tcx > > + Captures < ' a > {
1470
- self . all_ctors . iter ( ) . flat_map ( move |req_ctor| {
1471
- req_ctor. subtract_ctors ( self . tcx , self . param_env , & self . used_ctors )
1472
- } )
1447
+ self . all_ctors . iter ( ) . flat_map ( move |req_ctor| req_ctor. subtract_ctors ( & self . used_ctors ) )
1473
1448
}
1474
1449
}
1475
1450
@@ -1610,7 +1585,7 @@ pub fn is_useful<'p, 'a, 'tcx>(
1610
1585
// non-wildcard patterns in the current column. To determine if
1611
1586
// the set is empty, we can check that `.peek().is_none()`, so
1612
1587
// we only fully construct them on-demand, because they're rarely used and can be big.
1613
- let missing_ctors = MissingConstructors :: new ( cx . tcx , cx . param_env , all_ctors, used_ctors) ;
1588
+ let missing_ctors = MissingConstructors :: new ( all_ctors, used_ctors) ;
1614
1589
1615
1590
debug ! (
1616
1591
"missing_ctors.empty()={:#?} is_privately_empty={:#?} is_declared_nonexhaustive={:#?}" ,
@@ -2274,12 +2249,9 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
2274
2249
// If the constructor is a:
2275
2250
// - Single value: add a row if the pattern contains the constructor.
2276
2251
// - Range: add a row if the constructor intersects the pattern.
2277
- if constructor. is_integral_range ( ) {
2278
- match (
2279
- IntRange :: from_ctor ( cx. tcx , cx. param_env , constructor) ,
2280
- IntRange :: from_pat ( cx. tcx , cx. param_env , pat) ,
2281
- ) {
2282
- ( Some ( ctor) , Some ( pat) ) => ctor. intersection ( cx. tcx , & pat) . map ( |_| {
2252
+ if let IntRange ( ctor) = constructor {
2253
+ match IntRange :: from_pat ( cx. tcx , cx. param_env , pat) {
2254
+ Some ( pat) => ctor. intersection ( cx. tcx , & pat) . map ( |_| {
2283
2255
// Constructor splitting should ensure that all intersections we encounter
2284
2256
// are actually inclusions.
2285
2257
let ( pat_lo, pat_hi) = pat. boundaries ( ) ;
0 commit comments