@@ -763,35 +763,30 @@ impl<'tcx> Constructor<'tcx> {
763
763
remaining_ctors
764
764
}
765
765
ConstantRange ( ..) | ConstantValue ( ..) => {
766
- if let Some ( _self_range) = IntRange :: from_ctor ( tcx, param_env, self ) {
767
- let mut remaining_ctors = vec ! [ self . clone( ) ] ;
768
- for other_ctor in other_ctors {
769
- if other_ctor == self {
770
- // If a constructor appears in a `match` arm, we can
766
+ if let Some ( self_range) = IntRange :: from_ctor ( tcx, param_env, self ) {
767
+ let mut remaining_ranges = vec ! [ self_range. clone( ) ] ;
768
+ let other_ranges = other_ctors
769
+ . into_iter ( )
770
+ . filter_map ( |c| IntRange :: from_ctor ( tcx, param_env, c) ) ;
771
+ for other_range in other_ranges {
772
+ if other_range == self_range {
773
+ // If the `self` range appears directly in a `match` arm, we can
771
774
// eliminate it straight away.
772
- remaining_ctors = vec ! [ ]
773
- } else if let Some ( interval) =
774
- IntRange :: from_ctor ( tcx, param_env, other_ctor)
775
- {
776
- // Refine the required constructors for the type by subtracting
777
- // the range defined by the current constructor pattern.
778
- remaining_ctors =
779
- interval. subtract_from ( tcx, param_env, remaining_ctors) ;
775
+ remaining_ranges = vec ! [ ] ;
776
+ } else {
777
+ // Otherwise explicitely compute the remaining ranges.
778
+ remaining_ranges = other_range. subtract_from ( remaining_ranges) ;
780
779
}
781
780
782
- // If the constructor patterns that have been considered so far
783
- // already cover the entire range of values, then we know the
784
- // constructor is not missing, and we can move on to the next one.
785
- if remaining_ctors. is_empty ( ) {
781
+ // If the ranges that have been considered so far already cover the entire
782
+ // range of values, we can return early.
783
+ if remaining_ranges. is_empty ( ) {
786
784
break ;
787
785
}
788
786
}
789
787
790
- // If a constructor has not been matched, then it is missing.
791
- // We add `remaining_ctors` instead of `self`, because then we can
792
- // provide more detailed error information about precisely which
793
- // ranges have been omitted.
794
- remaining_ctors
788
+ // Convert the ranges back into constructors
789
+ remaining_ranges. into_iter ( ) . map ( |range| range. into_ctor ( tcx) ) . collect ( )
795
790
} else {
796
791
if other_ctors. iter ( ) . any ( |c| {
797
792
c == self
@@ -1418,38 +1413,27 @@ impl<'tcx> IntRange<'tcx> {
1418
1413
1419
1414
/// Returns a collection of ranges that spans the values covered by `ranges`, subtracted
1420
1415
/// by the values covered by `self`: i.e., `ranges \ self` (in set notation).
1421
- fn subtract_from (
1422
- self ,
1423
- tcx : TyCtxt < ' tcx > ,
1424
- param_env : ty:: ParamEnv < ' tcx > ,
1425
- ranges : Vec < Constructor < ' tcx > > ,
1426
- ) -> Vec < Constructor < ' tcx > > {
1427
- let ranges = ranges
1428
- . into_iter ( )
1429
- . filter_map ( |r| IntRange :: from_ctor ( tcx, param_env, & r) . map ( |i| i. range ) ) ;
1416
+ fn subtract_from ( self , ranges : Vec < IntRange < ' tcx > > ) -> Vec < IntRange < ' tcx > > {
1430
1417
let mut remaining_ranges = vec ! [ ] ;
1431
1418
let ty = self . ty ;
1432
1419
let span = self . span ;
1433
1420
let ( lo, hi) = self . range . into_inner ( ) ;
1434
1421
for subrange in ranges {
1435
- let ( subrange_lo, subrange_hi) = subrange. into_inner ( ) ;
1422
+ let ( subrange_lo, subrange_hi) = subrange. range . into_inner ( ) ;
1436
1423
if lo > subrange_hi || subrange_lo > hi {
1437
1424
// The pattern doesn't intersect with the subrange at all,
1438
1425
// so the subrange remains untouched.
1439
- remaining_ranges
1440
- . push ( IntRange { range : subrange_lo..=subrange_hi, ty, span } . into_ctor ( tcx) ) ;
1426
+ remaining_ranges. push ( IntRange { range : subrange_lo..=subrange_hi, ty, span } ) ;
1441
1427
} else {
1442
1428
if lo > subrange_lo {
1443
1429
// The pattern intersects an upper section of the
1444
1430
// subrange, so a lower section will remain.
1445
- remaining_ranges
1446
- . push ( IntRange { range : subrange_lo..=( lo - 1 ) , ty, span } . into_ctor ( tcx) ) ;
1431
+ remaining_ranges. push ( IntRange { range : subrange_lo..=( lo - 1 ) , ty, span } ) ;
1447
1432
}
1448
1433
if hi < subrange_hi {
1449
1434
// The pattern intersects a lower section of the
1450
1435
// subrange, so an upper section will remain.
1451
- remaining_ranges
1452
- . push ( IntRange { range : ( hi + 1 ) ..=subrange_hi, ty, span } . into_ctor ( tcx) ) ;
1436
+ remaining_ranges. push ( IntRange { range : ( hi + 1 ) ..=subrange_hi, ty, span } ) ;
1453
1437
}
1454
1438
}
1455
1439
}
@@ -1491,6 +1475,13 @@ impl<'tcx> IntRange<'tcx> {
1491
1475
}
1492
1476
}
1493
1477
1478
+ // Ignore spans when comparing, they don't carry semantic information as they are only for lints.
1479
+ impl < ' tcx > std:: cmp:: PartialEq for IntRange < ' tcx > {
1480
+ fn eq ( & self , other : & Self ) -> bool {
1481
+ self . range == other. range && self . ty == other. ty
1482
+ }
1483
+ }
1484
+
1494
1485
// A struct to compute a set of constructors equivalent to `all_ctors \ used_ctors`.
1495
1486
struct MissingConstructors < ' tcx > {
1496
1487
tcx : TyCtxt < ' tcx > ,
0 commit comments