Skip to content

Commit ef1d58e

Browse files
committed
Auto merge of rust-lang#75354 - estebank:tuple-struct-as-struct-pat, r=petrochenkov
Detect tuple variants used as struct pattern and suggest correct pattern Fix rust-lang#61326 r? @petrochenkov
2 parents 3df25ae + 17ada05 commit ef1d58e

6 files changed

+43
-14
lines changed

src/librustc_resolve/late/diagnostics.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,16 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
701701
if let Some(span) = self.def_span(def_id) {
702702
err.span_label(span, &format!("`{}` defined here", path_str));
703703
}
704-
err.span_label(span, format!("did you mean `{}( /* fields */ )`?", path_str));
704+
let fields =
705+
self.r.field_names.get(&def_id).map_or("/* fields */".to_string(), |fields| {
706+
vec!["_"; fields.len()].join(", ")
707+
});
708+
err.span_suggestion(
709+
span,
710+
"use the tuple variant pattern syntax instead",
711+
format!("{}({})", path_str, fields),
712+
Applicability::HasPlaceholders,
713+
);
705714
}
706715
(Res::SelfTy(..), _) if ns == ValueNS => {
707716
err.span_label(span, fallback_label);

src/test/ui/empty/empty-struct-tuple-pat.stderr

+11-5
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,29 @@ LL | Empty4()
2323
| -------- `E::Empty4` defined here
2424
...
2525
LL | E::Empty4 => ()
26-
| ^^^^^^^^^ did you mean `E::Empty4( /* fields */ )`?
26+
| ^^^^^^^^^ help: use the tuple variant pattern syntax instead: `E::Empty4()`
2727

2828
error[E0532]: expected unit struct, unit variant or constant, found tuple variant `XE::XEmpty5`
2929
--> $DIR/empty-struct-tuple-pat.rs:33:9
3030
|
3131
LL | XE::XEmpty5 => (),
32-
| ^^^^-------
33-
| | |
34-
| | help: a unit variant with a similar name exists: `XEmpty4`
35-
| did you mean `XE::XEmpty5( /* fields */ )`?
32+
| ^^^^^^^^^^^
3633
|
3734
::: $DIR/auxiliary/empty-struct.rs:7:5
3835
|
3936
LL | XEmpty4,
4037
| ------- similarly named unit variant `XEmpty4` defined here
4138
LL | XEmpty5(),
4239
| --------- `XE::XEmpty5` defined here
40+
|
41+
help: use the tuple variant pattern syntax instead
42+
|
43+
LL | XE::XEmpty5(/* fields */) => (),
44+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
45+
help: a unit variant with a similar name exists
46+
|
47+
LL | XE::XEmpty4 => (),
48+
| ^^^^^^^
4349

4450
error: aborting due to 4 previous errors
4551

src/test/ui/issues/issue-32004.stderr

+10-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,16 @@ LL | Baz
77
| --- similarly named unit variant `Baz` defined here
88
...
99
LL | Foo::Bar => {}
10-
| ^^^^^---
11-
| | |
12-
| | help: a unit variant with a similar name exists: `Baz`
13-
| did you mean `Foo::Bar( /* fields */ )`?
10+
| ^^^^^^^^
11+
|
12+
help: use the tuple variant pattern syntax instead
13+
|
14+
LL | Foo::Bar(_) => {}
15+
| ^^^^^^^^^^^
16+
help: a unit variant with a similar name exists
17+
|
18+
LL | Foo::Baz => {}
19+
| ^^^
1420

1521
error[E0532]: expected tuple struct or tuple variant, found unit struct `S`
1622
--> $DIR/issue-32004.rs:16:9

src/test/ui/issues/issue-63983.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | Tuple(i32),
55
| ---------- `MyEnum::Tuple` defined here
66
...
77
LL | MyEnum::Tuple => "",
8-
| ^^^^^^^^^^^^^ did you mean `MyEnum::Tuple( /* fields */ )`?
8+
| ^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `MyEnum::Tuple(_)`
99

1010
error[E0532]: expected unit struct, unit variant or constant, found struct variant `MyEnum::Struct`
1111
--> $DIR/issue-63983.rs:10:9

src/test/ui/parser/recover-from-bad-variant.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ fn main() {
99
match x {
1010
Enum::Foo(a, b) => {}
1111
//~^ ERROR expected tuple struct or tuple variant, found struct variant `Enum::Foo`
12-
Enum::Bar(a, b) => {}
12+
Enum::Bar { a, b } => {}
13+
//~^ ERROR tuple variant `Enum::Bar` written as struct variant
1314
}
1415
}

src/test/ui/parser/recover-from-bad-variant.stderr

+9-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ LL | Foo { a: usize, b: usize },
1818
LL | Enum::Foo(a, b) => {}
1919
| ^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `Enum::Foo { a, b }`
2020

21-
error: aborting due to 2 previous errors
21+
error[E0769]: tuple variant `Enum::Bar` written as struct variant
22+
--> $DIR/recover-from-bad-variant.rs:12:9
23+
|
24+
LL | Enum::Bar { a, b } => {}
25+
| ^^^^^^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `Enum::Bar(a, b)`
26+
27+
error: aborting due to 3 previous errors
2228

23-
For more information about this error, try `rustc --explain E0532`.
29+
Some errors have detailed explanations: E0532, E0769.
30+
For more information about an error, try `rustc --explain E0532`.

0 commit comments

Comments
 (0)