]> git.lizzy.rs Git - rust.git/commitdiff
Refactor condition
authorvarkor <github@varkor.com>
Fri, 22 Jun 2018 22:52:56 +0000 (23:52 +0100)
committervarkor <github@varkor.com>
Thu, 16 Aug 2018 19:09:05 +0000 (20:09 +0100)
src/librustc_mir/hair/pattern/_match.rs

index 5d990dfa8dfe32d378776050c99d5366ee4a4159..60a8c89995a00b5b473746ef024af79b1659d7b3 100644 (file)
@@ -35,6 +35,7 @@
 use std::cmp::{self, Ordering};
 use std::fmt;
 use std::iter::{FromIterator, IntoIterator};
+use std::ops::RangeInclusive;
 
 pub fn expand_pattern<'a, 'tcx>(cx: &MatchCheckCtxt<'a, 'tcx>, pat: Pattern<'tcx>)
                                 -> &'a Pattern<'tcx>
@@ -274,7 +275,7 @@ fn variant_index_for_adt(&self, adt: &'tcx ty::AdtDef) -> usize {
     }
 }
 
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub enum Usefulness<'tcx> {
     Useful,
     UsefulWithWitness(Vec<Witness<'tcx>>),
@@ -290,7 +291,7 @@ fn is_useful(&self) -> bool {
     }
 }
 
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
 pub enum WitnessPreference {
     ConstructWitness,
     LeaveOutWitness
@@ -303,7 +304,7 @@ struct PatternContext<'tcx> {
 }
 
 /// A stack of patterns in reverse order of construction
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub struct Witness<'tcx>(Vec<Pattern<'tcx>>);
 
 impl<'tcx> Witness<'tcx> {
@@ -418,10 +419,6 @@ fn apply_constructor<'a>(
 /// but is instead bounded by the maximum fixed length of slice patterns in
 /// the column of patterns being analyzed.
 ///
-/// This intentionally does not list ConstantValue specializations for
-/// non-booleans, because we currently assume that there is always a
-/// "non-standard constant" that matches. See issue #12483.
-///
 /// We make sure to omit constructors that are statically impossible. eg for
 /// Option<!> we do not include Some(_) in the returned list of constructors.
 fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
@@ -530,7 +527,7 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>(
     //     `[true, ..]`
     //     `[.., false]`
     // Then any slice of length ≥1 that matches one of these two
-    // patterns can be  be trivially turned to a slice of any
+    // patterns can be trivially turned to a slice of any
     // other length ≥1 that matches them and vice-versa - for
     // but the slice from length 2 `[false, true]` that matches neither
     // of these patterns can't be turned to a slice from length 1 that
@@ -823,33 +820,32 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
         // as patterns in the `match` expression, but did not.
         let mut missing_ctors = vec![];
         for req_ctor in &all_ctors {
-            if consider_value_constructors {
-                let mut refined_ctors = vec![req_ctor.clone()];
-                for used_ctor in &used_ctors {
-                    // Refine the required constructors for the type by subtracting
-                    // the range defined by the current constructor pattern.
-                    refined_ctors = match IntRange::from_ctor(cx.tcx, used_ctor) {
-                        Some(interval) => interval.subtract_from(cx.tcx, refined_ctors),
-                        None => refined_ctors,
-                    };
-                    // If the constructor patterns that have been considered so far
-                    // already cover the entire range of values, then we the
-                    // constructor is not missing, and we can move on to the next one.
-                    if refined_ctors.is_empty() {
-                        break;
+            let mut refined_ctors = vec![req_ctor.clone()];
+            for used_ctor in &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 exhaustive_integer_patterns {
+                    if let Some(interval) = IntRange::from_ctor(cx.tcx, used_ctor) {
+                        // Refine the required constructors for the type by subtracting
+                        // the range defined by the current constructor pattern.
+                        refined_ctors = interval.subtract_from(cx.tcx, refined_ctors);
                     }
                 }
-                // 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.
-                missing_ctors.extend(refined_ctors);
-            } else {
-                // A constructor is missing if it never appears in a `match` arm.
-                if !used_ctors.iter().any(|used_ctor| used_ctor == req_ctor) {
-                    missing_ctors.push(req_ctor.clone());
+
+                // If the constructor patterns that have been considered so far
+                // already cover the entire range of values, then we 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.
+            missing_ctors.extend(refined_ctors);
         }
 
         // `missing_ctors` is the set of constructors from the same type as the