about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2015-11-16 17:26:14 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2015-11-19 11:41:09 +0300
commit4573bb8e967e8f21f711bf9fd1dd756342829b1f (patch)
tree7f842d63058a71a97edacaa3dabd769b76733905
parent35749923eed9060118878c8cb812bafd32bbcd7e (diff)
downloadrust-4573bb8e967e8f21f711bf9fd1dd756342829b1f.tar.gz
rust-4573bb8e967e8f21f711bf9fd1dd756342829b1f.zip
Add special case for `UnitVariant(..)` patterns
-rw-r--r--src/librustc_typeck/check/_match.rs25
-rw-r--r--src/test/compile-fail/empty-struct-unit-pat.rs2
-rw-r--r--src/test/compile-fail/match-pattern-field-mismatch-2.rs3
-rw-r--r--src/test/compile-fail/pattern-error-continue.rs3
4 files changed, 20 insertions, 13 deletions
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 21958387056..7cc81027f02 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -139,7 +139,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
                 if pat_is_resolved_const(&tcx.def_map.borrow(), pat) => {
             if let hir::PatEnum(ref path, ref subpats) = pat.node {
                 if !(subpats.is_some() && subpats.as_ref().unwrap().is_empty()) {
-                    bad_struct_kind_err(tcx.sess, pat.span, path);
+                    bad_struct_kind_err(tcx.sess, pat.span, path, false);
                     return;
                 }
             }
@@ -581,9 +581,9 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx hir::Pat,
 }
 
 // This function exists due to the warning "diagnostic code E0164 already used"
-fn bad_struct_kind_err(sess: &Session, span: Span, path: &hir::Path) {
+fn bad_struct_kind_err(sess: &Session, span: Span, path: &hir::Path, is_warning: bool) {
     let name = pprust::path_to_string(path);
-    span_err!(sess, span, E0164,
+    span_err_or_warn!(is_warning, sess, span, E0164,
         "`{}` does not name a tuple variant or a tuple struct", name);
 }
 
@@ -634,8 +634,8 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
                      path_scheme, &ctor_predicates,
                      opt_ty, def, pat.span, pat.id);
 
-    let report_bad_struct_kind = || {
-        bad_struct_kind_err(tcx.sess, pat.span, path);
+    let report_bad_struct_kind = |is_warning| {
+        bad_struct_kind_err(tcx.sess, pat.span, path, is_warning);
         fcx.write_error(pat.id);
 
         if let Some(subpats) = subpats {
@@ -650,7 +650,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     // function uses checks specific to structs and enums.
     if path_res.depth != 0 {
         if is_tuple_struct_pat {
-            report_bad_struct_kind();
+            report_bad_struct_kind(false);
         } else {
             let pat_ty = fcx.node_ty(pat.id);
             demand::suptype(fcx, pat.span, expected, pat_ty);
@@ -668,8 +668,13 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
         {
             let variant = enum_def.variant_of_def(def);
             if is_tuple_struct_pat && variant.kind() != ty::VariantKind::Tuple {
-                report_bad_struct_kind();
-                return;
+                // 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()
@@ -682,7 +687,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
         ty::TyStruct(struct_def, expected_substs) => {
             let variant = struct_def.struct_variant();
             if is_tuple_struct_pat && variant.kind() != ty::VariantKind::Tuple {
-                report_bad_struct_kind();
+                report_bad_struct_kind(false);
                 return;
             }
             (variant.fields
@@ -694,7 +699,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
              "struct")
         }
         _ => {
-            report_bad_struct_kind();
+            report_bad_struct_kind(false);
             return;
         }
     };
diff --git a/src/test/compile-fail/empty-struct-unit-pat.rs b/src/test/compile-fail/empty-struct-unit-pat.rs
index f9af71527a1..6cb9a3f007f 100644
--- a/src/test/compile-fail/empty-struct-unit-pat.rs
+++ b/src/test/compile-fail/empty-struct-unit-pat.rs
@@ -34,6 +34,6 @@ fn main() {
     //     E::Empty2() => () // ERROR `E::Empty2` does not name a tuple variant or a tuple struct
     // }
     match e2 {
-        E::Empty2(..) => () //~ ERROR `E::Empty2` does not name a tuple variant or a tuple struct
+        E::Empty2(..) => () //~ WARN `E::Empty2` does not name a tuple variant or a tuple struct
     }
 }
diff --git a/src/test/compile-fail/match-pattern-field-mismatch-2.rs b/src/test/compile-fail/match-pattern-field-mismatch-2.rs
index a4ba93ea173..17debdabb61 100644
--- a/src/test/compile-fail/match-pattern-field-mismatch-2.rs
+++ b/src/test/compile-fail/match-pattern-field-mismatch-2.rs
@@ -20,7 +20,8 @@ fn main() {
           color::rgb(_, _, _) => { }
           color::cmyk(_, _, _, _) => { }
           color::no_color(_) => { }
-          //~^ ERROR `color::no_color` does not name a tuple variant or a tuple struct
+          //~^ ERROR this pattern has 1 field, but the corresponding variant has no fields
+          //~^^ WARN `color::no_color` does not name a tuple variant or a tuple struct
         }
     }
 }
diff --git a/src/test/compile-fail/pattern-error-continue.rs b/src/test/compile-fail/pattern-error-continue.rs
index 891a586423e..1721d1f0ae1 100644
--- a/src/test/compile-fail/pattern-error-continue.rs
+++ b/src/test/compile-fail/pattern-error-continue.rs
@@ -25,7 +25,8 @@ fn f(_c: char) {}
 fn main() {
     match A::B(1, 2) {
         A::B(_, _, _) => (), //~ ERROR this pattern has 3 fields, but
-        A::D(_) => (),       //~ ERROR `A::D` does not name a tuple variant or a tuple struct
+        A::D(_) => (),       //~ ERROR this pattern has 1 field, but
+        //~^ WARN `A::D` does not name a tuple variant or a tuple struct
         _ => ()
     }
     match 'c' {