about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNadrieril <nadrieril+git@gmail.com>2020-10-25 23:03:15 +0000
committerNadrieril <nadrieril+git@gmail.com>2020-10-27 00:46:32 +0000
commit41e7ca499d51913131a5afa5fa76db914cb672cd (patch)
tree3f97b781ac70b82feb406e33125628ca8886b1ba
parentc511955a9ff89089bff313cd8a87a6e62e2783f5 (diff)
downloadrust-41e7ca499d51913131a5afa5fa76db914cb672cd.tar.gz
rust-41e7ca499d51913131a5afa5fa76db914cb672cd.zip
Inline `specialize_one_pattern`
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/_match.rs90
1 files changed, 39 insertions, 51 deletions
diff --git a/compiler/rustc_mir_build/src/thir/pattern/_match.rs b/compiler/rustc_mir_build/src/thir/pattern/_match.rs
index 7dbde71b2a6..d3602dac9e8 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/_match.rs
@@ -407,20 +407,51 @@ impl<'p, 'tcx> PatStack<'p, 'tcx> {
     }
 
     /// This computes `S(constructor, self)`. See top of the file for explanations.
+    ///
+    /// This is the main specialization step. It expands the pattern
+    /// into `arity` patterns based on the constructor. For most patterns, the step is trivial,
+    /// for instance tuple patterns are flattened and box patterns expand into their inner pattern.
+    /// Returns `None` if the pattern does not have the given constructor.
+    ///
+    /// OTOH, slice patterns with a subslice pattern (tail @ ..) can be expanded into multiple
+    /// different patterns.
+    /// Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
+    /// fields filled with wild patterns.
+    ///
+    /// This is roughly the inverse of `Constructor::apply`.
     fn specialize_constructor(
         &self,
         cx: &MatchCheckCtxt<'p, 'tcx>,
-        constructor: &Constructor<'tcx>,
+        ctor: &Constructor<'tcx>,
         ctor_wild_subpatterns: &Fields<'p, 'tcx>,
         is_my_head_ctor: bool,
     ) -> Option<PatStack<'p, 'tcx>> {
-        let new_fields = specialize_one_pattern(
-            cx,
+        // We return `None` if `ctor` is not covered by `self.head()`. If `ctor` is known to be
+        // derived from `self.head()`, or if `self.head()` is a wildcard, then we don't need to
+        // check; otherwise, we compute the constructor of `self.head()` and check for constructor
+        // inclusion.
+        // Note that this shortcut is also necessary for correctness: a pattern should always be
+        // specializable with its own constructor, even in cases where we refuse to inspect values like
+        // opaque constants.
+        if !self.head().is_wildcard() && !is_my_head_ctor {
+            // `unwrap` is safe because `pat` is not a wildcard.
+            let head_ctor = pat_constructor(cx.tcx, cx.param_env, self.head()).unwrap();
+            if !ctor.is_covered_by(cx, &head_ctor, self.head().ty) {
+                return None;
+            }
+        }
+        let new_fields = ctor_wild_subpatterns.replace_with_pattern_arguments(self.head());
+
+        debug!(
+            "specialize_constructor({:#?}, {:#?}, {:#?}) = {:#?}",
             self.head(),
-            constructor,
+            ctor,
             ctor_wild_subpatterns,
-            is_my_head_ctor,
-        )?;
+            new_fields
+        );
+
+        // We pop the head pattern and push the new fields extracted from the arguments of
+        // `self.head()`.
         Some(new_fields.push_on_patstack(&self.0[1..]))
     }
 }
@@ -971,7 +1002,7 @@ impl Slice {
 /// the constructor. See also `Fields`.
 ///
 /// `pat_constructor` retrieves the constructor corresponding to a pattern.
-/// `specialize_one_pattern` returns the list of fields corresponding to a pattern, given a
+/// `specialize_constructor` returns the list of fields corresponding to a pattern, given a
 /// constructor. `Constructor::apply` reconstructs the pattern from a pair of `Constructor` and
 /// `Fields`.
 #[derive(Clone, Debug, PartialEq)]
@@ -1195,7 +1226,7 @@ impl<'tcx> Constructor<'tcx> {
     /// Apply a constructor to a list of patterns, yielding a new pattern. `pats`
     /// must have as many elements as this constructor's arity.
     ///
-    /// This is roughly the inverse of `specialize_one_pattern`.
+    /// This is roughly the inverse of `specialize_constructor`.
     ///
     /// Examples:
     /// `self`: `Constructor::Single`
@@ -2607,46 +2638,3 @@ fn pat_constructor<'tcx>(
         PatKind::Or { .. } => bug!("Or-pattern should have been expanded earlier on."),
     }
 }
-
-/// This is the main specialization step. It expands the pattern
-/// into `arity` patterns based on the constructor. For most patterns, the step is trivial,
-/// for instance tuple patterns are flattened and box patterns expand into their inner pattern.
-/// Returns `None` if the pattern does not have the given constructor.
-///
-/// OTOH, slice patterns with a subslice pattern (tail @ ..) can be expanded into multiple
-/// different patterns.
-/// Structure patterns with a partial wild pattern (Foo { a: 42, .. }) have their missing
-/// fields filled with wild patterns.
-///
-/// This is roughly the inverse of `Constructor::apply`.
-fn specialize_one_pattern<'p, 'tcx>(
-    cx: &MatchCheckCtxt<'p, 'tcx>,
-    pat: &'p Pat<'tcx>,
-    ctor: &Constructor<'tcx>,
-    ctor_wild_subpatterns: &Fields<'p, 'tcx>,
-    is_its_own_ctor: bool, // Whether `ctor` is known to be derived from `pat`
-) -> Option<Fields<'p, 'tcx>> {
-    if pat.is_wildcard() {
-        return Some(ctor_wild_subpatterns.clone());
-    }
-
-    // We return `None` if `ctor` is not covered by `pat`. If `ctor` is known to be derived from
-    // `pat` then we don't need to check; otherwise, we compute the constructor of `pat` and check
-    // for constructor inclusion.
-    // Note that this shortcut is also necessary for correctness: a pattern should always be
-    // specializable with its own constructor, even in cases where we refuse to inspect values like
-    // opaque constants.
-    if !is_its_own_ctor {
-        // `unwrap` is safe because `pat` is not a wildcard.
-        let pat_ctor = pat_constructor(cx.tcx, cx.param_env, pat).unwrap();
-        if !ctor.is_covered_by(cx, &pat_ctor, pat.ty) {
-            return None;
-        }
-    }
-
-    let fields = ctor_wild_subpatterns.replace_with_pattern_arguments(pat);
-
-    debug!("specialize({:#?}, {:#?}, {:#?}) = {:#?}", pat, ctor, ctor_wild_subpatterns, fields);
-
-    Some(fields)
-}