@@ -646,6 +646,41 @@ impl<'tcx> Constructor<'tcx> {
646646 }
647647 }
648648
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+
649684 /// This returns one wildcard pattern for each argument to this constructor.
650685 fn wildcard_subpatterns < ' a > (
651686 & self ,
@@ -1313,33 +1348,7 @@ impl<'tcx> MissingConstructors<'tcx> {
13131348 /// Iterate over all_ctors \ used_ctors
13141349 fn iter < ' a > ( & ' a self ) -> impl Iterator < Item = Constructor < ' tcx > > + Captures < ' a > {
13151350 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 )
13431352 } )
13441353 }
13451354}
0 commit comments