@@ -659,12 +659,7 @@ impl<'tcx> Constructor<'tcx> {
659
659
660
660
// Returns the set of constructors covered by `self` but not by
661
661
// anything in `other_ctors`.
662
- fn subtract_ctors (
663
- & self ,
664
- tcx : TyCtxt < ' tcx > ,
665
- param_env : ty:: ParamEnv < ' tcx > ,
666
- other_ctors : & Vec < Constructor < ' tcx > > ,
667
- ) -> Vec < Constructor < ' tcx > > {
662
+ fn subtract_ctors ( & self , other_ctors : & Vec < Constructor < ' tcx > > ) -> Vec < Constructor < ' tcx > > {
668
663
match self {
669
664
// Those constructors can only match themselves.
670
665
Single | Variant ( _) => {
@@ -747,22 +742,22 @@ impl<'tcx> Constructor<'tcx> {
747
742
}
748
743
IntRange ( self_range) => {
749
744
let mut remaining_ranges = vec ! [ self_range. clone( ) ] ;
750
- let other_ranges =
751
- other_ctors. into_iter ( ) . filter_map ( |c| IntRange :: from_ctor ( tcx, param_env, c) ) ;
752
- for other_range in other_ranges {
753
- if other_range == * self_range {
754
- // If the `self` range appears directly in a `match` arm, we can
755
- // eliminate it straight away.
756
- remaining_ranges = vec ! [ ] ;
757
- } else {
758
- // Otherwise explicitely compute the remaining ranges.
759
- remaining_ranges = other_range. subtract_from ( remaining_ranges) ;
760
- }
745
+ for other_ctor in other_ctors {
746
+ if let IntRange ( other_range) = other_ctor {
747
+ if other_range == self_range {
748
+ // If the `self` range appears directly in a `match` arm, we can
749
+ // eliminate it straight away.
750
+ remaining_ranges = vec ! [ ] ;
751
+ } else {
752
+ // Otherwise explicitely compute the remaining ranges.
753
+ remaining_ranges = other_range. subtract_from ( remaining_ranges) ;
754
+ }
761
755
762
- // If the ranges that have been considered so far already cover the entire
763
- // range of values, we can return early.
764
- if remaining_ranges. is_empty ( ) {
765
- break ;
756
+ // If the ranges that have been considered so far already cover the entire
757
+ // range of values, we can return early.
758
+ if remaining_ranges. is_empty ( ) {
759
+ break ;
760
+ }
766
761
}
767
762
}
768
763
@@ -773,7 +768,7 @@ impl<'tcx> Constructor<'tcx> {
773
768
if other_ctors. iter ( ) . any ( |c| {
774
769
c == self
775
770
// FIXME(Nadrieril): This condition looks fishy
776
- || IntRange :: from_ctor ( tcx , param_env , c ) . is_some ( )
771
+ || c . is_integral_range ( )
777
772
} ) {
778
773
vec ! [ ]
779
774
} else {
@@ -1364,26 +1359,15 @@ impl<'tcx> IntRange<'tcx> {
1364
1359
}
1365
1360
}
1366
1361
1367
- fn from_ctor (
1368
- _tcx : TyCtxt < ' tcx > ,
1369
- _param_env : ty:: ParamEnv < ' tcx > ,
1370
- ctor : & Constructor < ' tcx > ,
1371
- ) -> Option < IntRange < ' tcx > > {
1372
- // Floating-point ranges are permitted and we don't want
1373
- // to consider them when constructing integer ranges.
1374
- match ctor {
1375
- IntRange ( range) => Some ( range. clone ( ) ) ,
1376
- _ => None ,
1377
- }
1378
- }
1379
-
1380
1362
fn from_pat (
1381
1363
tcx : TyCtxt < ' tcx > ,
1382
1364
param_env : ty:: ParamEnv < ' tcx > ,
1383
1365
pat : & Pat < ' tcx > ,
1384
1366
) -> Option < IntRange < ' tcx > > {
1385
- let ctor = pat_constructor ( tcx, param_env, pat) ?;
1386
- IntRange :: from_ctor ( tcx, param_env, & ctor)
1367
+ match pat_constructor ( tcx, param_env, pat) ? {
1368
+ IntRange ( range) => Some ( range) ,
1369
+ _ => None ,
1370
+ }
1387
1371
}
1388
1372
1389
1373
// The return value of `signed_bias` should be XORed with an endpoint to encode/decode it.
@@ -1490,20 +1474,13 @@ impl<'tcx> std::cmp::PartialEq for IntRange<'tcx> {
1490
1474
1491
1475
// A struct to compute a set of constructors equivalent to `all_ctors \ used_ctors`.
1492
1476
struct MissingConstructors < ' tcx > {
1493
- tcx : TyCtxt < ' tcx > ,
1494
- param_env : ty:: ParamEnv < ' tcx > ,
1495
1477
all_ctors : Vec < Constructor < ' tcx > > ,
1496
1478
used_ctors : Vec < Constructor < ' tcx > > ,
1497
1479
}
1498
1480
1499
1481
impl < ' tcx > MissingConstructors < ' tcx > {
1500
- fn new (
1501
- tcx : TyCtxt < ' tcx > ,
1502
- param_env : ty:: ParamEnv < ' tcx > ,
1503
- all_ctors : Vec < Constructor < ' tcx > > ,
1504
- used_ctors : Vec < Constructor < ' tcx > > ,
1505
- ) -> Self {
1506
- MissingConstructors { tcx, param_env, all_ctors, used_ctors }
1482
+ fn new ( all_ctors : Vec < Constructor < ' tcx > > , used_ctors : Vec < Constructor < ' tcx > > ) -> Self {
1483
+ MissingConstructors { all_ctors, used_ctors }
1507
1484
}
1508
1485
1509
1486
fn into_inner ( self ) -> ( Vec < Constructor < ' tcx > > , Vec < Constructor < ' tcx > > ) {
@@ -1521,9 +1498,7 @@ impl<'tcx> MissingConstructors<'tcx> {
1521
1498
1522
1499
/// Iterate over all_ctors \ used_ctors
1523
1500
fn iter < ' a > ( & ' a self ) -> impl Iterator < Item = Constructor < ' tcx > > + Captures < ' a > {
1524
- self . all_ctors . iter ( ) . flat_map ( move |req_ctor| {
1525
- req_ctor. subtract_ctors ( self . tcx , self . param_env , & self . used_ctors )
1526
- } )
1501
+ self . all_ctors . iter ( ) . flat_map ( move |req_ctor| req_ctor. subtract_ctors ( & self . used_ctors ) )
1527
1502
}
1528
1503
}
1529
1504
@@ -1649,7 +1624,7 @@ pub fn is_useful<'p, 'a, 'tcx>(
1649
1624
// Missing constructors are those that are not matched by any non-wildcard patterns in the
1650
1625
// current column. We only fully construct them on-demand, because they're rarely used and
1651
1626
// can be big.
1652
- let missing_ctors = MissingConstructors :: new ( cx . tcx , cx . param_env , all_ctors, used_ctors) ;
1627
+ let missing_ctors = MissingConstructors :: new ( all_ctors, used_ctors) ;
1653
1628
1654
1629
debug ! ( "missing_ctors.empty()={:#?}" , missing_ctors. is_empty( ) , ) ;
1655
1630
@@ -2305,12 +2280,9 @@ fn specialize_one_pattern<'p, 'a: 'p, 'q: 'p, 'tcx>(
2305
2280
// If the constructor is a:
2306
2281
// - Single value: add a row if the pattern contains the constructor.
2307
2282
// - Range: add a row if the constructor intersects the pattern.
2308
- if constructor. is_integral_range ( ) {
2309
- match (
2310
- IntRange :: from_ctor ( cx. tcx , cx. param_env , constructor) ,
2311
- IntRange :: from_pat ( cx. tcx , cx. param_env , pat) ,
2312
- ) {
2313
- ( Some ( ctor) , Some ( pat) ) => ctor. intersection ( cx. tcx , & pat) . map ( |_| {
2283
+ if let IntRange ( ctor) = constructor {
2284
+ match IntRange :: from_pat ( cx. tcx , cx. param_env , pat) {
2285
+ Some ( pat) => ctor. intersection ( cx. tcx , & pat) . map ( |_| {
2314
2286
// Constructor splitting should ensure that all intersections we encounter
2315
2287
// are actually inclusions.
2316
2288
let ( pat_lo, pat_hi) = pat. boundaries ( ) ;
0 commit comments