@@ -646,6 +646,41 @@ impl<'tcx> Constructor<'tcx> {
646
646
}
647
647
}
648
648
649
+ // Returns the set of constructors covered by `self` but not by
650
+ // anything in `other_ctors`.
651
+ fn subtract_ctors (
652
+ & self ,
653
+ tcx : TyCtxt < ' tcx > ,
654
+ param_env : ty:: ParamEnv < ' tcx > ,
655
+ other_ctors : & Vec < Constructor < ' tcx > > ,
656
+ ) -> Vec < Constructor < ' tcx > > {
657
+ let mut refined_ctors = vec ! [ self . clone( ) ] ;
658
+ for other_ctor in other_ctors {
659
+ if other_ctor == self {
660
+ // If a constructor appears in a `match` arm, we can
661
+ // eliminate it straight away.
662
+ refined_ctors = vec ! [ ]
663
+ } else if let Some ( interval) = IntRange :: from_ctor ( tcx, param_env, other_ctor) {
664
+ // Refine the required constructors for the type by subtracting
665
+ // the range defined by the current constructor pattern.
666
+ refined_ctors = interval. subtract_from ( tcx, param_env, refined_ctors) ;
667
+ }
668
+
669
+ // If the constructor patterns that have been considered so far
670
+ // already cover the entire range of values, then we know the
671
+ // constructor is not missing, and we can move on to the next one.
672
+ if refined_ctors. is_empty ( ) {
673
+ break ;
674
+ }
675
+ }
676
+
677
+ // If a constructor has not been matched, then it is missing.
678
+ // We add `refined_ctors` instead of `self`, because then we can
679
+ // provide more detailed error information about precisely which
680
+ // ranges have been omitted.
681
+ refined_ctors
682
+ }
683
+
649
684
/// This returns one wildcard pattern for each argument to this constructor.
650
685
fn wildcard_subpatterns < ' a > (
651
686
& self ,
@@ -1313,33 +1348,7 @@ impl<'tcx> MissingConstructors<'tcx> {
1313
1348
/// Iterate over all_ctors \ used_ctors
1314
1349
fn iter < ' a > ( & ' a self ) -> impl Iterator < Item = Constructor < ' tcx > > + Captures < ' a > {
1315
1350
self . all_ctors . iter ( ) . flat_map ( move |req_ctor| {
1316
- let mut refined_ctors = vec ! [ req_ctor. clone( ) ] ;
1317
- for used_ctor in & self . used_ctors {
1318
- if used_ctor == req_ctor {
1319
- // If a constructor appears in a `match` arm, we can
1320
- // eliminate it straight away.
1321
- refined_ctors = vec ! [ ]
1322
- } else if let Some ( interval) =
1323
- IntRange :: from_ctor ( self . tcx , self . param_env , used_ctor)
1324
- {
1325
- // Refine the required constructors for the type by subtracting
1326
- // the range defined by the current constructor pattern.
1327
- refined_ctors = interval. subtract_from ( self . tcx , self . param_env , refined_ctors) ;
1328
- }
1329
-
1330
- // If the constructor patterns that have been considered so far
1331
- // already cover the entire range of values, then we know the
1332
- // constructor is not missing, and we can move on to the next one.
1333
- if refined_ctors. is_empty ( ) {
1334
- break ;
1335
- }
1336
- }
1337
-
1338
- // If a constructor has not been matched, then it is missing.
1339
- // We add `refined_ctors` instead of `req_ctor`, because then we can
1340
- // provide more detailed error information about precisely which
1341
- // ranges have been omitted.
1342
- refined_ctors
1351
+ req_ctor. subtract_ctors ( self . tcx , self . param_env , & self . used_ctors )
1343
1352
} )
1344
1353
}
1345
1354
}
0 commit comments