about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAriel Ben-Yehuda <ariel.byd@gmail.com>2016-03-04 02:26:42 +0200
committerAriel Ben-Yehuda <ariel.byd@gmail.com>2016-03-04 15:24:28 +0200
commitaf55b4189f8e3105f8acad853525fbb19e0584b0 (patch)
treee03a71d94b34845b000255291a11be09326b55dc /src
parentb9e61c9f403e89415a3787fae90fef5aad8ee477 (diff)
downloadrust-af55b4189f8e3105f8acad853525fbb19e0584b0.tar.gz
rust-af55b4189f8e3105f8acad853525fbb19e0584b0.zip
clean up check_pat_enum
Diffstat (limited to 'src')
-rw-r--r--src/librustc_typeck/check/_match.rs74
1 files changed, 28 insertions, 46 deletions
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index bd2c7b39153..8d0ae0f880d 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -599,12 +599,12 @@ fn bad_struct_kind_err(sess: &Session, pat: &hir::Pat, path: &hir::Path, lint: b
     }
 }
 
-pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
-                                pat: &hir::Pat,
-                                path: &hir::Path,
-                                subpats: Option<&'tcx [P<hir::Pat>]>,
-                                expected: Ty<'tcx>,
-                                is_tuple_struct_pat: bool)
+fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
+                            pat: &hir::Pat,
+                            path: &hir::Path,
+                            subpats: Option<&'tcx [P<hir::Pat>]>,
+                            expected: Ty<'tcx>,
+                            is_tuple_struct_pat: bool)
 {
     // Typecheck the path.
     let fcx = pcx.fcx;
@@ -687,46 +687,14 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     demand::eqtype(fcx, pat.span, expected, pat_ty);
 
     let real_path_ty = fcx.node_ty(pat.id);
-    let (arg_tys, kind_name): (Vec<_>, &'static str) = match real_path_ty.sty {
+    let (kind_name, variant, expected_substs) = match real_path_ty.sty {
         ty::TyEnum(enum_def, expected_substs) => {
             let variant = enum_def.variant_of_def(def);
-            if variant.kind() == ty::VariantKind::Struct {
-                report_bad_struct_kind(false);
-                return;
-            }
-            if is_tuple_struct_pat && variant.kind() != ty::VariantKind::Tuple {
-                // Matching unit variants with tuple variant patterns (`UnitVariant(..)`)
-                // is allowed for backward compatibility.
-                let is_special_case = variant.kind() == ty::VariantKind::Unit;
-                report_bad_struct_kind(is_special_case);
-                if !is_special_case {
-                    return
-                }
-            }
-            (variant.fields
-                    .iter()
-                    .map(|f| fcx.instantiate_type_scheme(pat.span,
-                                                         expected_substs,
-                                                         &f.unsubst_ty()))
-                    .collect(),
-             "variant")
+            ("variant", variant, expected_substs)
         }
         ty::TyStruct(struct_def, expected_substs) => {
             let variant = struct_def.struct_variant();
-            if is_tuple_struct_pat && variant.kind() != ty::VariantKind::Tuple {
-                // Matching unit structs with tuple variant patterns (`UnitVariant(..)`)
-                // is allowed for backward compatibility.
-                let is_special_case = variant.kind() == ty::VariantKind::Unit;
-                report_bad_struct_kind(is_special_case);
-                return;
-            }
-            (variant.fields
-                    .iter()
-                    .map(|f| fcx.instantiate_type_scheme(pat.span,
-                                                         expected_substs,
-                                                         &f.unsubst_ty()))
-                    .collect(),
-             "struct")
+            ("struct", variant, expected_substs)
         }
         _ => {
             report_bad_struct_kind(false);
@@ -734,12 +702,26 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
         }
     };
 
+    match (is_tuple_struct_pat, variant.kind()) {
+        (true, ty::VariantKind::Unit) => {
+            // Matching unit structs with tuple variant patterns (`UnitVariant(..)`)
+            // is allowed for backward compatibility.
+            report_bad_struct_kind(true);
+        }
+        (_, ty::VariantKind::Struct) => {
+            report_bad_struct_kind(false);
+            return
+        }
+        _ => {}
+    }
+
     if let Some(subpats) = subpats {
-        if subpats.len() == arg_tys.len() {
-            for (subpat, arg_ty) in subpats.iter().zip(arg_tys) {
-                check_pat(pcx, &subpat, arg_ty);
+        if subpats.len() == variant.fields.len() {
+            for (subpat, field) in subpats.iter().zip(&variant.fields) {
+                let field_ty = fcx.field_ty(subpat.span, field, expected_substs);
+                check_pat(pcx, &subpat, field_ty);
             }
-        } else if arg_tys.is_empty() {
+        } else if variant.fields.is_empty() {
             span_err!(tcx.sess, pat.span, E0024,
                       "this pattern has {} field{}, but the corresponding {} has no fields",
                       subpats.len(), if subpats.len() == 1 {""} else {"s"}, kind_name);
@@ -752,7 +734,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
                       "this pattern has {} field{}, but the corresponding {} has {} field{}",
                       subpats.len(), if subpats.len() == 1 {""} else {"s"},
                       kind_name,
-                      arg_tys.len(), if arg_tys.len() == 1 {""} else {"s"});
+                      variant.fields.len(), if variant.fields.len() == 1 {""} else {"s"});
 
             for pat in subpats {
                 check_pat(pcx, &pat, tcx.types.err);