diff options
| author | Nadrieril <nadrieril+git@gmail.com> | 2019-11-17 19:24:48 +0000 |
|---|---|---|
| committer | Nadrieril <nadrieril+git@gmail.com> | 2019-11-17 19:58:11 +0000 |
| commit | 7f5e0441e2246451e3b03ac907c4308d071e99fd (patch) | |
| tree | 69e5eb0ef6f2924cdb0ae06bd39cd3806c374d54 | |
| parent | bd0e3ccd0bf81b57f115b344dcf424a3ed626cab (diff) | |
| download | rust-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.rs | 72 |
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 { |
