about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-03-25 08:35:17 +0100
committerMazdak Farrokhzad <twingoow@gmail.com>2020-03-25 08:35:17 +0100
commitbd156846fa84fde77cc801ea3b1f4d5750db94a4 (patch)
treee8597581ccfad8d3a1e3eb2046d30198a955b22f
parent58fee523cfe1e242cbf8776bb8513fb8325bc0ab (diff)
downloadrust-bd156846fa84fde77cc801ea3b1f4d5750db94a4.tar.gz
rust-bd156846fa84fde77cc801ea3b1f4d5750db94a4.zip
improve non-exhaustive struct pat error
-rw-r--r--src/librustc_typeck/check/pat.rs32
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/struct.stderr15
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/variant.stderr10
3 files changed, 49 insertions, 8 deletions
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index d3b1ea8778d..ea04454a356 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -1082,14 +1082,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Require `..` if struct has non_exhaustive attribute.
         if variant.is_field_list_non_exhaustive() && !adt.did.is_local() && !etc {
-            struct_span_err!(
-                tcx.sess,
-                pat.span,
-                E0638,
-                "`..` required with {} marked as non-exhaustive",
-                adt.variant_descr()
-            )
-            .emit();
+            self.error_foreign_non_exhaustive_spat(pat, adt.variant_descr(), fields.is_empty());
         }
 
         // Report an error if incorrect number of the fields were specified.
@@ -1108,6 +1101,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         no_field_errors
     }
 
+    fn error_foreign_non_exhaustive_spat(&self, pat: &Pat<'_>, descr: &str, no_fields: bool) {
+        let sess = self.tcx.sess;
+        let sm = sess.source_map();
+        let sp_brace = sm.end_point(pat.span);
+        let sp_comma = sm.end_point(pat.span.with_hi(sp_brace.hi()));
+        let sugg = if no_fields || sp_brace != sp_comma { ".. }" } else { ", .. }" };
+
+        let mut err = struct_span_err!(
+            sess,
+            pat.span,
+            E0638,
+            "`..` required with {} marked as non-exhaustive",
+            descr
+        );
+        err.span_suggestion_verbose(
+            sp_comma,
+            "add `..` at the end of the field list",
+            sugg.to_string(),
+            Applicability::MachineApplicable,
+        );
+        err.emit();
+    }
+
     fn error_field_already_bound(&self, span: Span, ident: ast::Ident, other_field: Span) {
         struct_span_err!(
             self.tcx.sess,
diff --git a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr
index 4e91e7bff34..b1351e6fb9c 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr
@@ -62,18 +62,33 @@ error[E0638]: `..` required with struct marked as non-exhaustive
    |
 LL |     let NormalStruct { first_field, second_field } = ns;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: add `..` at the end of the field list
+   |
+LL |     let NormalStruct { first_field, second_field , .. } = ns;
+   |                                                  ^^^^^^
 
 error[E0638]: `..` required with struct marked as non-exhaustive
   --> $DIR/struct.rs:26:9
    |
 LL |     let TupleStruct { 0: first_field, 1: second_field } = ts;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: add `..` at the end of the field list
+   |
+LL |     let TupleStruct { 0: first_field, 1: second_field , .. } = ts;
+   |                                                       ^^^^^^
 
 error[E0638]: `..` required with struct marked as non-exhaustive
   --> $DIR/struct.rs:35:9
    |
 LL |     let UnitStruct { } = us;
    |         ^^^^^^^^^^^^^^
+   |
+help: add `..` at the end of the field list
+   |
+LL |     let UnitStruct { .. } = us;
+   |                      ^^^^
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/variant.stderr b/src/test/ui/rfc-2008-non-exhaustive/variant.stderr
index ae4f6aff11a..94432ce29d5 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/variant.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/variant.stderr
@@ -69,12 +69,22 @@ error[E0638]: `..` required with variant marked as non-exhaustive
    |
 LL |         NonExhaustiveVariants::Struct { field } => ""
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: add `..` at the end of the field list
+   |
+LL |         NonExhaustiveVariants::Struct { field , .. } => ""
+   |                                               ^^^^^^
 
 error[E0638]: `..` required with variant marked as non-exhaustive
   --> $DIR/variant.rs:30:12
    |
 LL |     if let NonExhaustiveVariants::Struct { field } = variant_struct {
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: add `..` at the end of the field list
+   |
+LL |     if let NonExhaustiveVariants::Struct { field , .. } = variant_struct {
+   |                                                  ^^^^^^
 
 error: aborting due to 8 previous errors