about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNadrieril <nadrieril+git@gmail.com>2019-11-17 19:08:01 +0000
committerNadrieril <nadrieril+git@gmail.com>2019-11-17 19:25:03 +0000
commitbd0e3ccd0bf81b57f115b344dcf424a3ed626cab (patch)
treeee191bde89d778b9a9e543e133301384b0065d9f
parentdaa117eab715f38d08facfb826b04116bc9fe0b7 (diff)
downloadrust-bd0e3ccd0bf81b57f115b344dcf424a3ed626cab.tar.gz
rust-bd0e3ccd0bf81b57f115b344dcf424a3ed626cab.zip
Store SliceKinds directly when subtracting
-rw-r--r--src/librustc_mir/hair/pattern/_match.rs111
1 files changed, 58 insertions, 53 deletions
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index d379f606da4..182c9e22e41 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -594,43 +594,9 @@ enum SliceKind {
     VarLen(u64, u64),
 }
 
-/// A constructor for array and slice patterns.
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-struct Slice {
-    /// `None` if the matched value is a slice, `Some(n)` if it is an array of size `n`.
-    array_len: Option<u64>,
-    /// The kind of pattern it is: fixed-length `[x, y]` or variable length `[x, .., y]`.
-    kind: SliceKind,
-}
-
-impl Slice {
-    /// Returns what patterns this constructor covers: either fixed-length patterns or
-    /// variable-length patterns.
-    fn pattern_kind(self) -> SliceKind {
-        match self {
-            Slice { array_len: Some(len), kind: VarLen(prefix, suffix) }
-                if prefix + suffix == len =>
-            {
-                FixedLen(len)
-            }
-            _ => self.kind,
-        }
-    }
-
-    /// Returns what values this constructor covers: either values of only one given length, or
-    /// values of length above a given length.
-    /// This is different from `pattern_kind()` because in some cases the pattern only takes into
-    /// account a subset of the entries of the array, but still only captures values of a given
-    /// length.
-    fn value_kind(self) -> SliceKind {
-        match self {
-            Slice { array_len: Some(len), kind: VarLen(_, _) } => FixedLen(len),
-            _ => self.kind,
-        }
-    }
-
+impl SliceKind {
     fn arity(self) -> u64 {
-        match self.pattern_kind() {
+        match self {
             FixedLen(length) => length,
             VarLen(prefix, suffix) => prefix + suffix,
         }
@@ -638,7 +604,7 @@ impl Slice {
 
     /// Whether this pattern includes patterns of length `other_len`.
     fn covers_length(self, other_len: u64) -> bool {
-        match self.value_kind() {
+        match self {
             FixedLen(len) => len == other_len,
             VarLen(prefix, suffix) => prefix + suffix <= other_len,
         }
@@ -649,7 +615,7 @@ impl Slice {
     fn subtract(self, other: Self) -> SmallVec<[Self; 1]> {
         // Remember, `VarLen(i, j)` covers the union of `FixedLen` from `i + j` to infinity.
         // Naming: we remove the "neg" constructors from the "pos" ones.
-        match self.value_kind() {
+        match self {
             FixedLen(pos_len) => {
                 if other.covers_length(pos_len) {
                     smallvec![]
@@ -659,7 +625,7 @@ impl Slice {
             }
             VarLen(pos_prefix, pos_suffix) => {
                 let pos_len = pos_prefix + pos_suffix;
-                match other.value_kind() {
+                match other {
                     FixedLen(neg_len) => {
                         if neg_len < pos_len {
                             smallvec![self]
@@ -668,7 +634,6 @@ impl Slice {
                                 .map(FixedLen)
                                 // We know that `neg_len + 1 >= pos_len >= pos_suffix`.
                                 .chain(Some(VarLen(neg_len + 1 - pos_suffix, pos_suffix)))
-                                .map(|kind| Slice { array_len: None, kind })
                                 .collect()
                         }
                     }
@@ -677,10 +642,7 @@ impl Slice {
                         if neg_len <= pos_len {
                             smallvec![]
                         } else {
-                            (pos_len..neg_len)
-                                .map(FixedLen)
-                                .map(|kind| Slice { array_len: None, kind })
-                                .collect()
+                            (pos_len..neg_len).map(FixedLen).collect()
                         }
                     }
                 }
@@ -689,6 +651,46 @@ impl Slice {
     }
 }
 
+/// A constructor for array and slice patterns.
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+struct Slice {
+    /// `None` if the matched value is a slice, `Some(n)` if it is an array of size `n`.
+    array_len: Option<u64>,
+    /// The kind of pattern it is: fixed-length `[x, y]` or variable length `[x, .., y]`.
+    kind: SliceKind,
+}
+
+impl Slice {
+    /// Returns what patterns this constructor covers: either fixed-length patterns or
+    /// variable-length patterns.
+    fn pattern_kind(self) -> SliceKind {
+        match self {
+            Slice { array_len: Some(len), kind: VarLen(prefix, suffix) }
+                if prefix + suffix == len =>
+            {
+                FixedLen(len)
+            }
+            _ => self.kind,
+        }
+    }
+
+    /// Returns what values this constructor covers: either values of only one given length, or
+    /// values of length above a given length.
+    /// This is different from `pattern_kind()` because in some cases the pattern only takes into
+    /// account a subset of the entries of the array, but still only captures values of a given
+    /// length.
+    fn value_kind(self) -> SliceKind {
+        match self {
+            Slice { array_len: Some(len), kind: VarLen(_, _) } => FixedLen(len),
+            _ => self.kind,
+        }
+    }
+
+    fn arity(self) -> u64 {
+        self.pattern_kind().arity()
+    }
+}
+
 #[derive(Clone, Debug, PartialEq)]
 enum Constructor<'tcx> {
     /// The constructor of all patterns that don't vary by constructor,
@@ -743,26 +745,25 @@ impl<'tcx> Constructor<'tcx> {
             &Slice(slice) => match slice.value_kind() {
                 FixedLen(self_len) => {
                     let overlaps = |c: &Constructor<'_>| match *c {
-                        Slice(other_slice) => other_slice.covers_length(self_len),
+                        Slice(other_slice) => other_slice.value_kind().covers_length(self_len),
                         _ => false,
                     };
                     if other_ctors.iter().any(overlaps) { vec![] } else { vec![Slice(slice)] }
                 }
                 VarLen(..) => {
-                    let mut remaining_slices = vec![slice];
+                    let mut remaining_slices = vec![slice.value_kind()];
 
                     // For each used slice, subtract from the current set of slices.
-                    // Naming: we remove the "neg" constructors from the "pos" ones.
-                    for neg_ctor in other_ctors {
-                        let neg_slice = match neg_ctor {
-                            Slice(slice) => *slice,
-                            // FIXME(#65413): If `neg_ctor` is not a slice, we assume it doesn't
+                    for other_ctor in other_ctors {
+                        let other_slice = match other_ctor {
+                            Slice(slice) => slice.value_kind(),
+                            // FIXME(#65413): If `other_ctor` is not a slice, we assume it doesn't
                             // cover any value here.
                             _ => continue,
                         };
                         remaining_slices = remaining_slices
                             .into_iter()
-                            .flat_map(|pos_slice| pos_slice.subtract(neg_slice))
+                            .flat_map(|remaining_slice| remaining_slice.subtract(other_slice))
                             .collect();
 
                         // If the constructors that have been considered so far already cover
@@ -772,7 +773,11 @@ impl<'tcx> Constructor<'tcx> {
                         }
                     }
 
-                    remaining_slices.into_iter().map(Slice).collect()
+                    remaining_slices
+                        .into_iter()
+                        .map(|kind| Slice { array_len: slice.array_len, kind })
+                        .map(Slice)
+                        .collect()
                 }
             },
             IntRange(self_range) => {