Skip to content

Commit

Permalink
Detect tuple variants used as struct pattern and suggest correct pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Aug 11, 2020
1 parent 4b9ac51 commit 17ada05
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 14 deletions.
11 changes: 10 additions & 1 deletion src/librustc_resolve/late/diagnostics.rs
Expand Up @@ -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);
Expand Down
16 changes: 11 additions & 5 deletions src/test/ui/empty/empty-struct-tuple-pat.stderr
Expand Up @@ -23,23 +23,29 @@ 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
|
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

Expand Down
14 changes: 10 additions & 4 deletions src/test/ui/issues/issue-32004.stderr
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-63983.stderr
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/test/ui/parser/recover-from-bad-variant.rs
Expand Up @@ -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
}
}
11 changes: 9 additions & 2 deletions src/test/ui/parser/recover-from-bad-variant.stderr
Expand Up @@ -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`.

0 comments on commit 17ada05

Please sign in to comment.