about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSam Radhakrishan <sk09idm@gmail.com>2019-09-19 22:12:05 +0530
committerSam Radhakrishan <sk09idm@gmail.com>2019-09-22 00:00:34 +0530
commita2a57bc6cf383fc113335148296c7965bb29e9a2 (patch)
treec5e2b826eb82e1c883499142663ccc372435d9aa
parented8b708c1a6bf6d94f860eeb6a6b0b442c380d7f (diff)
downloadrust-a2a57bc6cf383fc113335148296c7965bb29e9a2.tar.gz
rust-a2a57bc6cf383fc113335148296c7965bb29e9a2.zip
Fixes #63962. Hint about missing tuple parentheses in patterns
-rw-r--r--src/librustc_typeck/check/pat.rs41
-rw-r--r--src/test/ui/error-codes/E0023.rs2
-rw-r--r--src/test/ui/error-codes/E0023.stderr21
3 files changed, 53 insertions, 11 deletions
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index d93a4052cd3..d687a5084e2 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -676,18 +676,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         } else {
             // Pattern has wrong number of fields.
-            self.e0023(pat.span, res, &subpats, &variant.fields);
+            self.e0023(pat.span, res, &subpats, &variant.fields, expected);
             on_error();
             return tcx.types.err;
         }
         pat_ty
     }
 
-    fn e0023(&self, pat_span: Span, res: Res, subpats: &'tcx [P<Pat>], fields: &[ty::FieldDef]) {
+    fn e0023(
+        &self,
+        pat_span: Span,
+        res: Res,
+        subpats: &'tcx [P<Pat>],
+        fields: &[ty::FieldDef],
+        expected: Ty<'tcx>
+    ) {
         let subpats_ending = pluralise!(subpats.len());
         let fields_ending = pluralise!(fields.len());
+        let missing_parenthesis = match expected.sty {
+            ty::Adt(_, substs) if fields.len() == 1 => {
+                let field_ty = fields[0].ty(self.tcx, substs);
+                match field_ty.sty {
+                    ty::Tuple(_) => field_ty.tuple_fields().count() == subpats.len(),
+                    _ => false,
+                }
+            }
+            _ => false,
+        };
         let res_span = self.tcx.def_span(res.def_id());
-        struct_span_err!(
+        let mut err = struct_span_err!(
             self.tcx.sess,
             pat_span,
             E0023,
@@ -697,15 +714,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             res.descr(),
             fields.len(),
             fields_ending,
-        )
-            .span_label(pat_span, format!(
+        );
+        err.span_label(pat_span, format!(
                 "expected {} field{}, found {}",
                 fields.len(),
                 fields_ending,
                 subpats.len(),
             ))
-            .span_label(res_span, format!("{} defined here", res.descr()))
-            .emit();
+            .span_label(res_span, format!("{} defined here", res.descr()));
+
+        if missing_parenthesis {
+            err.multipart_suggestion(
+                "missing parenthesis",
+                vec![(subpats[0].span.shrink_to_lo(), "(".to_string()),
+                    (subpats[subpats.len()-1].span.shrink_to_hi(), ")".to_string())],
+                Applicability::MachineApplicable,
+            );
+        }
+
+        err.emit();
     }
 
     fn check_pat_tuple(
diff --git a/src/test/ui/error-codes/E0023.rs b/src/test/ui/error-codes/E0023.rs
index 2a97e9048a4..dc421e060e8 100644
--- a/src/test/ui/error-codes/E0023.rs
+++ b/src/test/ui/error-codes/E0023.rs
@@ -1,6 +1,7 @@
 enum Fruit {
     Apple(String, String),
     Pear(u32),
+    Orange((String, String)),
 }
 
 
@@ -10,5 +11,6 @@ fn main() {
         Fruit::Apple(a) => {}, //~ ERROR E0023
         Fruit::Apple(a, b, c) => {}, //~ ERROR E0023
         Fruit::Pear(1, 2) => {}, //~ ERROR E0023
+        Fruit::Orange(a, b) => {}, //~ ERROR E0023
     }
 }
diff --git a/src/test/ui/error-codes/E0023.stderr b/src/test/ui/error-codes/E0023.stderr
index d04e494c258..8ae7d01ed5f 100644
--- a/src/test/ui/error-codes/E0023.stderr
+++ b/src/test/ui/error-codes/E0023.stderr
@@ -1,5 +1,5 @@
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/E0023.rs:10:9
+  --> $DIR/E0023.rs:11:9
    |
 LL |     Apple(String, String),
    |     --------------------- tuple variant defined here
@@ -8,7 +8,7 @@ LL |         Fruit::Apple(a) => {},
    |         ^^^^^^^^^^^^^^^ expected 2 fields, found 1
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
-  --> $DIR/E0023.rs:11:9
+  --> $DIR/E0023.rs:12:9
    |
 LL |     Apple(String, String),
    |     --------------------- tuple variant defined here
@@ -17,7 +17,7 @@ LL |         Fruit::Apple(a, b, c) => {},
    |         ^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
-  --> $DIR/E0023.rs:12:9
+  --> $DIR/E0023.rs:13:9
    |
 LL |     Pear(u32),
    |     --------- tuple variant defined here
@@ -25,6 +25,19 @@ LL |     Pear(u32),
 LL |         Fruit::Pear(1, 2) => {},
    |         ^^^^^^^^^^^^^^^^^ expected 1 field, found 2
 
-error: aborting due to 3 previous errors
+error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
+  --> $DIR/E0023.rs:14:9
+   |
+LL |     Orange((String, String)),
+   |     ------------------------ tuple variant defined here
+...
+LL |         Fruit::Orange(a, b) => {},
+   |         ^^^^^^^^^^^^^^^^^^^ expected 1 field, found 2
+help: missing parenthesis
+   |
+LL |         Fruit::Orange((a, b)) => {},
+   |                       ^    ^
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0023`.