about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNadrieril <nadrieril@gmail.com>2019-10-27 16:58:04 +0000
committerNadrieril <nadrieril+git@gmail.com>2019-11-01 17:23:04 +0000
commitb7fa9f12ca62fc4f95306fa0c233de948edf303c (patch)
tree6725f7409cd5f87607063c94016bd66e43648d4a /src
parent92101b7655d915ae636efcc09d9df18783d8412e (diff)
downloadrust-b7fa9f12ca62fc4f95306fa0c233de948edf303c.tar.gz
rust-b7fa9f12ca62fc4f95306fa0c233de948edf303c.zip
Factor out constructor subtraction
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/hair/pattern/_match.rs63
1 files changed, 36 insertions, 27 deletions
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index 986d2584e4e..5d5cf9dfac7 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -646,6 +646,41 @@ impl<'tcx> Constructor<'tcx> {
         }
     }
 
+    // Returns the set of constructors covered by `self` but not by
+    // anything in `other_ctors`.
+    fn subtract_ctors(
+        &self,
+        tcx: TyCtxt<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        other_ctors: &Vec<Constructor<'tcx>>,
+    ) -> Vec<Constructor<'tcx>> {
+        let mut refined_ctors = vec![self.clone()];
+        for other_ctor in other_ctors {
+            if other_ctor == self {
+                // If a constructor appears in a `match` arm, we can
+                // eliminate it straight away.
+                refined_ctors = vec![]
+            } else if let Some(interval) = IntRange::from_ctor(tcx, param_env, other_ctor) {
+                // Refine the required constructors for the type by subtracting
+                // the range defined by the current constructor pattern.
+                refined_ctors = interval.subtract_from(tcx, param_env, refined_ctors);
+            }
+
+            // If the constructor patterns that have been considered so far
+            // already cover the entire range of values, then we know the
+            // constructor is not missing, and we can move on to the next one.
+            if refined_ctors.is_empty() {
+                break;
+            }
+        }
+
+        // If a constructor has not been matched, then it is missing.
+        // We add `refined_ctors` instead of `self`, because then we can
+        // provide more detailed error information about precisely which
+        // ranges have been omitted.
+        refined_ctors
+    }
+
     /// This returns one wildcard pattern for each argument to this constructor.
     fn wildcard_subpatterns<'a>(
         &self,
@@ -1313,33 +1348,7 @@ impl<'tcx> MissingConstructors<'tcx> {
     /// Iterate over all_ctors \ used_ctors
     fn iter<'a>(&'a self) -> impl Iterator<Item = Constructor<'tcx>> + Captures<'a> {
         self.all_ctors.iter().flat_map(move |req_ctor| {
-            let mut refined_ctors = vec![req_ctor.clone()];
-            for used_ctor in &self.used_ctors {
-                if used_ctor == req_ctor {
-                    // If a constructor appears in a `match` arm, we can
-                    // eliminate it straight away.
-                    refined_ctors = vec![]
-                } else if let Some(interval) =
-                    IntRange::from_ctor(self.tcx, self.param_env, used_ctor)
-                {
-                    // Refine the required constructors for the type by subtracting
-                    // the range defined by the current constructor pattern.
-                    refined_ctors = interval.subtract_from(self.tcx, self.param_env, refined_ctors);
-                }
-
-                // If the constructor patterns that have been considered so far
-                // already cover the entire range of values, then we know the
-                // constructor is not missing, and we can move on to the next one.
-                if refined_ctors.is_empty() {
-                    break;
-                }
-            }
-
-            // If a constructor has not been matched, then it is missing.
-            // We add `refined_ctors` instead of `req_ctor`, because then we can
-            // provide more detailed error information about precisely which
-            // ranges have been omitted.
-            refined_ctors
+            req_ctor.subtract_ctors(self.tcx, self.param_env, &self.used_ctors)
         })
     }
 }