]> git.lizzy.rs Git - rust.git/commitdiff
typeck/pat.rs: extract `calc_default_binding_mode`.
authorMazdak Farrokhzad <twingoow@gmail.com>
Fri, 23 Aug 2019 14:06:33 +0000 (16:06 +0200)
committerMazdak Farrokhzad <twingoow@gmail.com>
Sat, 24 Aug 2019 17:15:05 +0000 (19:15 +0200)
src/librustc_typeck/check/pat.rs

index ce033b85fce050bc53b97639837cf9b8fe88eefa..a9e6cfb41a469fc3f7128e9f78d7d7fa14912309 100644 (file)
@@ -60,29 +60,8 @@ pub fn check_pat_walk(
             PatKind::Path(qpath) => Some(self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span)),
             _ => None,
         };
-
-        let is_non_ref_pat = self.is_non_ref_pat(pat, path_resolution.map(|(res, ..)| res));
-        let (expected, def_bm) = if is_non_ref_pat {
-            debug!("pattern is non reference pattern");
-            self.peel_off_references(pat, expected, def_bm)
-        } else {
-            // When you encounter a `&pat` pattern, reset to "by
-            // value". This is so that `x` and `y` here are by value,
-            // as they appear to be:
-            //
-            // ```
-            // match &(&22, &44) {
-            //   (&x, &y) => ...
-            // }
-            // ```
-            //
-            // See issue #46688.
-            let def_bm = match pat.node {
-                PatKind::Ref(..) => ty::BindByValue(hir::MutImmutable),
-                _ => def_bm,
-            };
-            (expected, def_bm)
-        };
+        let is_nrp = self.is_non_ref_pat(pat, path_resolution.map(|(res, ..)| res));
+        let (expected, def_bm) = self.calc_default_binding_mode(pat, expected, def_bm, is_nrp);
 
         let ty = match pat.node {
             PatKind::Wild => {
@@ -495,6 +474,38 @@ pub fn check_pat_walk(
         // subtyping.
     }
 
+    /// Compute the new expected type and default binding mode from the old ones
+    /// as well as the pattern form we are currently checking.
+    fn calc_default_binding_mode(
+        &self,
+        pat: &'tcx hir::Pat,
+        expected: Ty<'tcx>,
+        def_bm: ty::BindingMode,
+        is_non_ref_pat: bool,
+    ) -> (Ty<'tcx>, ty::BindingMode) {
+        if is_non_ref_pat {
+            debug!("pattern is non reference pattern");
+            self.peel_off_references(pat, expected, def_bm)
+        } else {
+            // When you encounter a `&pat` pattern, reset to "by
+            // value". This is so that `x` and `y` here are by value,
+            // as they appear to be:
+            //
+            // ```
+            // match &(&22, &44) {
+            //   (&x, &y) => ...
+            // }
+            // ```
+            //
+            // See issue #46688.
+            let def_bm = match pat.node {
+                PatKind::Ref(..) => ty::BindByValue(hir::MutImmutable),
+                _ => def_bm,
+            };
+            (expected, def_bm)
+        }
+    }
+
     /// Is the pattern a "non reference pattern"?
     /// When the pattern is a path pattern, `opt_path_res` must be `Some(res)`.
     fn is_non_ref_pat(&self, pat: &'tcx hir::Pat, opt_path_res: Option<Res>) -> bool {