about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNadrieril <nadrieril+git@gmail.com>2019-11-17 19:24:48 +0000
committerNadrieril <nadrieril+git@gmail.com>2019-11-17 19:58:11 +0000
commit7f5e0441e2246451e3b03ac907c4308d071e99fd (patch)
tree69e5eb0ef6f2924cdb0ae06bd39cd3806c374d54
parentbd0e3ccd0bf81b57f115b344dcf424a3ed626cab (diff)
downloadrust-7f5e0441e2246451e3b03ac907c4308d071e99fd.tar.gz
rust-7f5e0441e2246451e3b03ac907c4308d071e99fd.zip
`ConstantValue` is the only other ctor allowed when subtracting from slice ctors
-rw-r--r--src/librustc_mir/hair/pattern/_match.rs72
1 files changed, 39 insertions, 33 deletions
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index 182c9e22e41..a6afea22881 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -742,44 +742,50 @@ impl<'tcx> Constructor<'tcx> {
             Single | Variant(_) | ConstantValue(..) | FloatRange(..) => {
                 if other_ctors.iter().any(|c| c == self) { vec![] } else { vec![self.clone()] }
             }
-            &Slice(slice) => match slice.value_kind() {
-                FixedLen(self_len) => {
-                    let overlaps = |c: &Constructor<'_>| match *c {
-                        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.value_kind()];
-
-                    // For each used slice, subtract from the current set of slices.
-                    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(|remaining_slice| remaining_slice.subtract(other_slice))
-                            .collect();
+            &Slice(slice) => {
+                let mut other_slices = other_ctors
+                    .iter()
+                    .filter_map(|c: &Constructor<'_>| match c {
+                        Slice(slice) => Some(*slice),
+                        // FIXME(#65413): We ignore `ConstantValue`s here.
+                        ConstantValue(..) => None,
+                        _ => bug!("bad slice pattern constructor {:?}", c),
+                    })
+                    .map(Slice::value_kind);
 
-                        // If the constructors that have been considered so far already cover
-                        // the entire range of `self`, no need to look at more constructors.
-                        if remaining_slices.is_empty() {
-                            break;
+                match slice.value_kind() {
+                    FixedLen(self_len) => {
+                        if other_slices.any(|other_slice| other_slice.covers_length(self_len)) {
+                            vec![]
+                        } else {
+                            vec![Slice(slice)]
                         }
                     }
+                    kind @ VarLen(..) => {
+                        let mut remaining_slices = vec![kind];
+
+                        // For each used slice, subtract from the current set of slices.
+                        for other_slice in other_slices {
+                            remaining_slices = remaining_slices
+                                .into_iter()
+                                .flat_map(|remaining_slice| remaining_slice.subtract(other_slice))
+                                .collect();
+
+                            // If the constructors that have been considered so far already cover
+                            // the entire range of `self`, no need to look at more constructors.
+                            if remaining_slices.is_empty() {
+                                break;
+                            }
+                        }
 
-                    remaining_slices
-                        .into_iter()
-                        .map(|kind| Slice { array_len: slice.array_len, kind })
-                        .map(Slice)
-                        .collect()
+                        remaining_slices
+                            .into_iter()
+                            .map(|kind| Slice { array_len: slice.array_len, kind })
+                            .map(Slice)
+                            .collect()
+                    }
                 }
-            },
+            }
             IntRange(self_range) => {
                 let mut remaining_ranges = vec![self_range.clone()];
                 for other_ctor in other_ctors {