about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-08-12 18:50:20 +0000
committerbors <bors@rust-lang.org>2020-08-12 18:50:20 +0000
commitef1d58e7c90aa9885c906a6eb7398a2b6256d075 (patch)
treec0788874d3b69212d35bbd020a33502a03f7db58
parent3df25ae186e89c885d9a71cd37fbd7a37e39fc85 (diff)
parent17ada052e7f8b785eaadb6fb49197357ad644d65 (diff)
downloadrust-ef1d58e7c90aa9885c906a6eb7398a2b6256d075.tar.gz
rust-ef1d58e7c90aa9885c906a6eb7398a2b6256d075.zip
Auto merge of #75354 - estebank:tuple-struct-as-struct-pat, r=petrochenkov
Detect tuple variants used as struct pattern and suggest correct pattern

Fix #61326

r? @petrochenkov
-rw-r--r--src/librustc_resolve/late/diagnostics.rs11
-rw-r--r--src/test/ui/empty/empty-struct-tuple-pat.stderr16
-rw-r--r--src/test/ui/issues/issue-32004.stderr14
-rw-r--r--src/test/ui/issues/issue-63983.stderr2
-rw-r--r--src/test/ui/parser/recover-from-bad-variant.rs3
-rw-r--r--src/test/ui/parser/recover-from-bad-variant.stderr11
6 files changed, 43 insertions, 14 deletions
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index c57c0e51941..f0ea325d2ab 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -701,7 +701,16 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
                 if let Some(span) = self.def_span(def_id) {
                     err.span_label(span, &format!("`{}` defined here", path_str));
                 }
-                err.span_label(span, format!("did you mean `{}( /* fields */ )`?", path_str));
+                let fields =
+                    self.r.field_names.get(&def_id).map_or("/* fields */".to_string(), |fields| {
+                        vec!["_"; fields.len()].join(", ")
+                    });
+                err.span_suggestion(
+                    span,
+                    "use the tuple variant pattern syntax instead",
+                    format!("{}({})", path_str, fields),
+                    Applicability::HasPlaceholders,
+                );
             }
             (Res::SelfTy(..), _) if ns == ValueNS => {
                 err.span_label(span, fallback_label);
diff --git a/src/test/ui/empty/empty-struct-tuple-pat.stderr b/src/test/ui/empty/empty-struct-tuple-pat.stderr
index 7b21d31635c..7b0d9717e63 100644
--- a/src/test/ui/empty/empty-struct-tuple-pat.stderr
+++ b/src/test/ui/empty/empty-struct-tuple-pat.stderr
@@ -23,16 +23,13 @@ LL |     Empty4()
    |     -------- `E::Empty4` defined here
 ...
 LL |         E::Empty4 => ()
-   |         ^^^^^^^^^ did you mean `E::Empty4( /* fields */ )`?
+   |         ^^^^^^^^^ help: use the tuple variant pattern syntax instead: `E::Empty4()`
 
 error[E0532]: expected unit struct, unit variant or constant, found tuple variant `XE::XEmpty5`
   --> $DIR/empty-struct-tuple-pat.rs:33:9
    |
 LL |         XE::XEmpty5 => (),
-   |         ^^^^-------
-   |         |   |
-   |         |   help: a unit variant with a similar name exists: `XEmpty4`
-   |         did you mean `XE::XEmpty5( /* fields */ )`?
+   |         ^^^^^^^^^^^
    | 
   ::: $DIR/auxiliary/empty-struct.rs:7:5
    |
@@ -40,6 +37,15 @@ LL |     XEmpty4,
    |     ------- similarly named unit variant `XEmpty4` defined here
 LL |     XEmpty5(),
    |     --------- `XE::XEmpty5` defined here
+   |
+help: use the tuple variant pattern syntax instead
+   |
+LL |         XE::XEmpty5(/* fields */) => (),
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+help: a unit variant with a similar name exists
+   |
+LL |         XE::XEmpty4 => (),
+   |             ^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/issues/issue-32004.stderr b/src/test/ui/issues/issue-32004.stderr
index ab723e26680..f95afb9c1fd 100644
--- a/src/test/ui/issues/issue-32004.stderr
+++ b/src/test/ui/issues/issue-32004.stderr
@@ -7,10 +7,16 @@ LL |     Baz
    |     --- similarly named unit variant `Baz` defined here
 ...
 LL |         Foo::Bar => {}
-   |         ^^^^^---
-   |         |    |
-   |         |    help: a unit variant with a similar name exists: `Baz`
-   |         did you mean `Foo::Bar( /* fields */ )`?
+   |         ^^^^^^^^
+   |
+help: use the tuple variant pattern syntax instead
+   |
+LL |         Foo::Bar(_) => {}
+   |         ^^^^^^^^^^^
+help: a unit variant with a similar name exists
+   |
+LL |         Foo::Baz => {}
+   |              ^^^
 
 error[E0532]: expected tuple struct or tuple variant, found unit struct `S`
   --> $DIR/issue-32004.rs:16:9
diff --git a/src/test/ui/issues/issue-63983.stderr b/src/test/ui/issues/issue-63983.stderr
index 771a5c285af..eb042834102 100644
--- a/src/test/ui/issues/issue-63983.stderr
+++ b/src/test/ui/issues/issue-63983.stderr
@@ -5,7 +5,7 @@ LL |     Tuple(i32),
    |     ---------- `MyEnum::Tuple` defined here
 ...
 LL |         MyEnum::Tuple => "",
-   |         ^^^^^^^^^^^^^ did you mean `MyEnum::Tuple( /* fields */ )`?
+   |         ^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `MyEnum::Tuple(_)`
 
 error[E0532]: expected unit struct, unit variant or constant, found struct variant `MyEnum::Struct`
   --> $DIR/issue-63983.rs:10:9
diff --git a/src/test/ui/parser/recover-from-bad-variant.rs b/src/test/ui/parser/recover-from-bad-variant.rs
index 27b03c0c2db..1bcef450bb9 100644
--- a/src/test/ui/parser/recover-from-bad-variant.rs
+++ b/src/test/ui/parser/recover-from-bad-variant.rs
@@ -9,6 +9,7 @@ fn main() {
     match x {
         Enum::Foo(a, b) => {}
         //~^ ERROR expected tuple struct or tuple variant, found struct variant `Enum::Foo`
-        Enum::Bar(a, b) => {}
+        Enum::Bar { a, b } => {}
+        //~^ ERROR tuple variant `Enum::Bar` written as struct variant
     }
 }
diff --git a/src/test/ui/parser/recover-from-bad-variant.stderr b/src/test/ui/parser/recover-from-bad-variant.stderr
index 6986d966d69..89232a519d7 100644
--- a/src/test/ui/parser/recover-from-bad-variant.stderr
+++ b/src/test/ui/parser/recover-from-bad-variant.stderr
@@ -18,6 +18,13 @@ LL |     Foo { a: usize, b: usize },
 LL |         Enum::Foo(a, b) => {}
    |         ^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `Enum::Foo { a, b }`
 
-error: aborting due to 2 previous errors
+error[E0769]: tuple variant `Enum::Bar` written as struct variant
+  --> $DIR/recover-from-bad-variant.rs:12:9
+   |
+LL |         Enum::Bar { a, b } => {}
+   |         ^^^^^^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `Enum::Bar(a, b)`
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0532`.
+Some errors have detailed explanations: E0532, E0769.
+For more information about an error, try `rustc --explain E0532`.