]> git.lizzy.rs Git - rust.git/commitdiff
typeck/pat.rs: extract `check_pat_tuple`.
authorMazdak Farrokhzad <twingoow@gmail.com>
Sat, 24 Aug 2019 02:30:03 +0000 (04:30 +0200)
committerMazdak Farrokhzad <twingoow@gmail.com>
Sat, 24 Aug 2019 17:15:26 +0000 (19:15 +0200)
src/librustc_typeck/check/pat.rs

index fda5d3a2ecd4ab0c0cf1f1a2352145068c882e25..be128ea358e7ed21ed37f7b2de44b2c1eb7eca21 100644 (file)
@@ -105,48 +105,7 @@ pub fn check_pat_walk(
                 expected_ty
             }
             PatKind::Tuple(ref elements, ddpos) => {
-                let mut expected_len = elements.len();
-                if ddpos.is_some() {
-                    // Require known type only when `..` is present.
-                    if let ty::Tuple(ref tys) =
-                            self.structurally_resolved_type(pat.span, expected).sty {
-                        expected_len = tys.len();
-                    }
-                }
-                let max_len = cmp::max(expected_len, elements.len());
-
-                let element_tys_iter = (0..max_len).map(|_| {
-                    Kind::from(self.next_ty_var(
-                        // FIXME: `MiscVariable` for now -- obtaining the span and name information
-                        // from all tuple elements isn't trivial.
-                        TypeVariableOrigin {
-                            kind: TypeVariableOriginKind::TypeInference,
-                            span: pat.span,
-                        },
-                    ))
-                });
-                let element_tys = tcx.mk_substs(element_tys_iter);
-                let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
-                if let Some(mut err) = self.demand_eqtype_diag(pat.span, expected, pat_ty) {
-                    err.emit();
-                    // Walk subpatterns with an expected type of `err` in this case to silence
-                    // further errors being emitted when using the bindings. #50333
-                    let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
-                    for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
-                        self.check_pat_walk(elem, &tcx.types.err, def_bm, discrim_span);
-                    }
-                    tcx.mk_tup(element_tys_iter)
-                } else {
-                    for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
-                        self.check_pat_walk(
-                            elem,
-                            &element_tys[i].expect_ty(),
-                            def_bm,
-                            discrim_span,
-                        );
-                    }
-                    pat_ty
-                }
+                self.check_pat_tuple(pat.span, elements, ddpos, expected, def_bm, discrim_span)
             }
             PatKind::Box(ref inner) => {
                 let inner_ty = self.next_ty_var(TypeVariableOrigin {
@@ -807,7 +766,7 @@ fn check_pat_tuple_struct(
             pat.hir_id);
         if !pat_ty.is_fn() {
             report_unexpected_res(res);
-            return self.tcx.types.err;
+            return tcx.types.err;
         }
 
         let variant = match res {
@@ -833,8 +792,9 @@ fn check_pat_tuple_struct(
         self.demand_eqtype_pat(pat.span, expected, pat_ty, match_arm_pat_span);
 
         // Type-check subpatterns.
-        if subpats.len() == variant.fields.len() ||
-                subpats.len() < variant.fields.len() && ddpos.is_some() {
+        if subpats.len() == variant.fields.len()
+            || subpats.len() < variant.fields.len() && ddpos.is_some()
+        {
             let substs = match pat_ty.sty {
                 ty::Adt(_, substs) => substs,
                 _ => bug!("unexpected pattern type {:?}", pat_ty),
@@ -861,6 +821,59 @@ fn check_pat_tuple_struct(
         pat_ty
     }
 
+    fn check_pat_tuple(
+        &self,
+        span: Span,
+        elements: &'tcx [P<hir::Pat>],
+        ddpos: Option<usize>,
+        expected: Ty<'tcx>,
+        def_bm: ty::BindingMode,
+        discrim_span: Option<Span>,
+    ) -> Ty<'tcx> {
+        let tcx = self.tcx;
+        let mut expected_len = elements.len();
+        if ddpos.is_some() {
+            // Require known type only when `..` is present.
+            if let ty::Tuple(ref tys) = self.structurally_resolved_type(span, expected).sty {
+                expected_len = tys.len();
+            }
+        }
+        let max_len = cmp::max(expected_len, elements.len());
+
+        let element_tys_iter = (0..max_len).map(|_| {
+            Kind::from(self.next_ty_var(
+                // FIXME: `MiscVariable` for now -- obtaining the span and name information
+                // from all tuple elements isn't trivial.
+                TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::TypeInference,
+                    span,
+                },
+            ))
+        });
+        let element_tys = tcx.mk_substs(element_tys_iter);
+        let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
+        if let Some(mut err) = self.demand_eqtype_diag(span, expected, pat_ty) {
+            err.emit();
+            // Walk subpatterns with an expected type of `err` in this case to silence
+            // further errors being emitted when using the bindings. #50333
+            let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
+            for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
+                self.check_pat_walk(elem, &tcx.types.err, def_bm, discrim_span);
+            }
+            tcx.mk_tup(element_tys_iter)
+        } else {
+            for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
+                self.check_pat_walk(
+                    elem,
+                    &element_tys[i].expect_ty(),
+                    def_bm,
+                    discrim_span,
+                );
+            }
+            pat_ty
+        }
+    }
+
     fn check_struct_pat_fields(
         &self,
         adt_ty: Ty<'tcx>,