about summary refs log tree commit diff
diff options
context:
space:
mode:
authorouz-a <oguz.agcayazi@gmail.com>2022-06-24 14:16:48 +0300
committerouz-a <oguz.agcayazi@gmail.com>2022-06-24 14:16:48 +0300
commit661d488bfd7cd4888400a23b9f6ea9bb15cacaf5 (patch)
treef7cb81a0c6efeb6caebd034d338b65b23ef0bab8
parent90abfe9ce27c81808e3f74861072df6734f6a45d (diff)
downloadrust-661d488bfd7cd4888400a23b9f6ea9bb15cacaf5.tar.gz
rust-661d488bfd7cd4888400a23b9f6ea9bb15cacaf5.zip
use true recursion
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/usefulness.rs33
1 files changed, 19 insertions, 14 deletions
diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
index 5bb2f00d3cf..5773ba8065c 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs
@@ -364,8 +364,8 @@ impl<'a, 'p, 'tcx> fmt::Debug for PatCtxt<'a, 'p, 'tcx> {
 /// A row of a matrix. Rows of len 1 are very common, which is why `SmallVec[_; 2]`
 /// works well.
 #[derive(Clone)]
-struct PatStack<'p, 'tcx> {
-    pats: SmallVec<[&'p DeconstructedPat<'p, 'tcx>; 2]>,
+pub(crate) struct PatStack<'p, 'tcx> {
+    pub(crate) pats: SmallVec<[&'p DeconstructedPat<'p, 'tcx>; 2]>,
 }
 
 impl<'p, 'tcx> PatStack<'p, 'tcx> {
@@ -403,6 +403,21 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
         })
     }
 
+    // Recursively expand all patterns into their subpatterns and push each `PatStack` to matrix.
+    fn expand_and_extend<'a>(&'a self, matrix: &mut Matrix<'p, 'tcx>) {
+        if !self.is_empty() && self.head().is_or_pat() {
+            for pat in self.head().iter_fields() {
+                let mut new_patstack = PatStack::from_pattern(pat);
+                new_patstack.pats.extend_from_slice(&self.pats[1..]);
+                if !new_patstack.is_empty() && new_patstack.head().is_or_pat() {
+                    new_patstack.expand_and_extend(matrix);
+                } else if !new_patstack.is_empty() {
+                    matrix.push(new_patstack);
+                }
+            }
+        }
+    }
+
     /// This computes `S(self.head().ctor(), self)`. See top of the file for explanations.
     ///
     /// Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
@@ -436,7 +451,7 @@ impl<'p, 'tcx> fmt::Debug for PatStack<'p, 'tcx> {
 /// A 2D matrix.
 #[derive(Clone)]
 pub(super) struct Matrix<'p, 'tcx> {
-    patterns: Vec<PatStack<'p, 'tcx>>,
+    pub patterns: Vec<PatStack<'p, 'tcx>>,
 }
 
 impl<'p, 'tcx> Matrix<'p, 'tcx> {
@@ -453,17 +468,7 @@ impl<'p, 'tcx> Matrix<'p, 'tcx> {
     /// expands it.
     fn push(&mut self, row: PatStack<'p, 'tcx>) {
         if !row.is_empty() && row.head().is_or_pat() {
-            let pats = row.expand_or_pat();
-            let mut no_inner_or = true;
-            for pat in pats {
-                if !pat.is_empty() && pat.head().is_or_pat() {
-                    self.patterns.extend(pat.expand_or_pat());
-                    no_inner_or = false;
-                }
-            }
-            if no_inner_or {
-                self.patterns.extend(row.expand_or_pat());
-            }
+            row.expand_and_extend(self);
         } else {
             self.patterns.push(row);
         }