]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/hair/pattern/_match.rs
Remove pattern consideration from split_grouped_constructors
[rust.git] / src / librustc_mir / hair / pattern / _match.rs
index 87ae9648af65b3a0354fe890e9822d667c800674..8c6f1d6759f8adbb74a0677cb3f63095628b7bf6 100644 (file)
@@ -796,6 +796,9 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>(
 /// For example, the pattern `-128...127i8` is encoded as `0..=255`.
 /// This makes comparisons and arithmetic on interval endpoints much more
 /// straightforward. See `signed_bias` for details.
+///
+/// `IntRange` is never used to encode an empty range or a "range" that wraps
+/// around the (offset) space: i.e. `range.lo <= range.hi`.
 struct IntRange<'tcx> {
     pub range: RangeInclusive<u128>,
     pub ty: Ty<'tcx>,
@@ -882,10 +885,8 @@ fn range_to_ctor(
         }
     }
 
-    /// Given an `IntRange` corresponding to a pattern in a `match` and a collection of
-    /// ranges corresponding to the domain of values of a type (say, an integer), return
-    /// a new collection of ranges corresponding to the original ranges minus the ranges
-    /// covered by the `IntRange`.
+    /// Return a collection of ranges that spans the values covered by `ranges`, subtracted
+    /// by the values covered by `self`: i.e. `ranges \ self` (in set notation).
     fn subtract_from(self,
                      tcx: TyCtxt<'_, 'tcx, 'tcx>,
                      ranges: Vec<Constructor<'tcx>>)
@@ -930,7 +931,7 @@ fn intersection(&self, other: &Self) -> Option<Self> {
     }
 }
 
-// Find those constructors that are not matched by any non-wildcard patterns in the current column.
+// Return a set of constructors equivalent to `all_ctors \ used_ctors`.
 fn compute_missing_ctors<'a, 'tcx: 'a>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     all_ctors: &Vec<Constructor<'tcx>>,
@@ -1046,7 +1047,7 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
 
     if let Some(constructors) = pat_constructors(cx, v[0], pcx) {
         debug!("is_useful - expanding constructors: {:#?}", constructors);
-        split_grouped_constructors(cx.tcx, constructors, matrix, v, pcx.ty).into_iter().map(|c|
+        split_grouped_constructors(cx.tcx, constructors, matrix, pcx.ty).into_iter().map(|c|
             is_useful_specialized(cx, matrix, v, c.clone(), pcx.ty, witness)
         ).find(|result| result.is_useful()).unwrap_or(NotUseful)
     } else {
@@ -1079,6 +1080,9 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
         // be a privately-empty enum is when the exhaustive_patterns
         // feature flag is not present, so this is only
         // needed for that case.
+
+        // Find those constructors that are not matched by any non-wildcard patterns in the
+        // current column.
         let missing_ctors = compute_missing_ctors(cx.tcx, &all_ctors, &used_ctors);
 
         let is_privately_empty = all_ctors.is_empty() && !cx.is_uninhabited(pcx.ty);
@@ -1091,7 +1095,7 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
         let is_non_exhaustive = is_privately_empty || is_declared_nonexhaustive;
 
         if missing_ctors.is_empty() && !is_non_exhaustive {
-            split_grouped_constructors(cx.tcx, all_ctors, matrix, v, pcx.ty).into_iter().map(|c| {
+            split_grouped_constructors(cx.tcx, all_ctors, matrix, pcx.ty).into_iter().map(|c| {
                 is_useful_specialized(cx, matrix, v, c.clone(), pcx.ty, witness)
             }).find(|result| result.is_useful()).unwrap_or(NotUseful)
         } else {
@@ -1407,11 +1411,8 @@ fn split_grouped_constructors<'p, 'a: 'p, 'tcx: 'a>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     ctors: Vec<Constructor<'tcx>>,
     &Matrix(ref m): &Matrix<'p, 'tcx>,
-    p: &[&'p Pattern<'tcx>],
     ty: Ty<'tcx>,
 ) -> Vec<Constructor<'tcx>> {
-    let pat = &p[0];
-
     let mut split_ctors = Vec::with_capacity(ctors.len());
 
     for ctor in ctors.into_iter() {
@@ -1423,27 +1424,8 @@ fn split_grouped_constructors<'p, 'a: 'p, 'tcx: 'a>(
                 // of the new pattern `p_({m + 1},1)` (here `pat`) and the constructor range.
                 // Anything else is irrelevant, because it is guaranteed to result in `NotUseful`,
                 // which is the default case anyway, and can be ignored.
-                let mut ctor_range = IntRange::from_ctor(tcx, &ctor).unwrap();
-                if let Some(pat_range) = IntRange::from_pat(tcx, pat) {
-                    if let Some(new_range) = ctor_range.intersection(&pat_range) {
-                        ctor_range = new_range;
-                    } else {
-                        // If the intersection between `pat` and the constructor is empty, the
-                        // entire range is `NotUseful`.
-                        continue;
-                    }
-                } else {
-                    match pat.kind {
-                        box PatternKind::Wild => {
-                            // A wild pattern matches the entire range of values,
-                            // so the current values are fine.
-                        }
-                        // If the pattern is not a value (i.e. a degenerate range), a range or a
-                        // wildcard (which stands for the entire range), then it's guaranteed to
-                        // be `NotUseful`.
-                        _ => continue,
-                    }
-                }
+                let ctor_range = IntRange::from_ctor(tcx, &ctor).unwrap();
+
                 // We're going to collect all the endpoints in the new pattern so we can create
                 // subranges between them.
                 // If there's a single point, we need to identify it as belonging