Skip to content

Commit ada9ba3

Browse files
committed
Suggest the struct variant pattern syntax on usage of unit variant pattern for a struct variant
1 parent a971212 commit ada9ba3

File tree

8 files changed

+111
-12
lines changed

8 files changed

+111
-12
lines changed

compiler/rustc_hir_typeck/src/lib.rs

+31-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub use coercion::can_coerce;
4545
use fn_ctxt::FnCtxt;
4646
use rustc_data_structures::unord::UnordSet;
4747
use rustc_errors::codes::*;
48-
use rustc_errors::{struct_span_code_err, Applicability, ErrorGuaranteed};
48+
use rustc_errors::{pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
4949
use rustc_hir as hir;
5050
use rustc_hir::def::{DefKind, Res};
5151
use rustc_hir::intravisit::Visitor;
@@ -421,6 +421,36 @@ fn report_unexpected_variant_res(
421421
err.multipart_suggestion_verbose(descr, suggestion, Applicability::MaybeIncorrect);
422422
err
423423
}
424+
Res::Def(DefKind::Variant, _) if expr.is_none() => {
425+
let fields = &tcx.expect_variant_res(res).fields.raw;
426+
427+
let span = qpath.span().shrink_to_hi().to(span.shrink_to_hi());
428+
let (msg, sugg) = if fields.is_empty() {
429+
("use the struct variant pattern syntax".to_string(), " {}".to_string())
430+
} else {
431+
let msg = format!(
432+
"the struct variant's field{s} {are} being ignored",
433+
s = pluralize!(fields.len()),
434+
are = pluralize!("is", fields.len())
435+
);
436+
let fields = fields
437+
.iter()
438+
.map(|field| format!("{}: _", field.name.to_ident_string()))
439+
.collect::<Vec<_>>()
440+
.join(", ");
441+
let sugg = format!(" {{ /* {} */ }}", fields,);
442+
(msg, sugg)
443+
};
444+
445+
err.span_label(span, format!("not a {expected}"));
446+
err.span_suggestion_verbose(
447+
qpath.span().shrink_to_hi().to(span.shrink_to_hi()),
448+
msg,
449+
sugg,
450+
Applicability::HasPlaceholders,
451+
);
452+
err
453+
}
424454
_ => err.with_span_label(span, format!("not a {expected}")),
425455
}
426456
.emit()

tests/ui/empty/empty-struct-braces-pat-1.stderr

+12-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,23 @@ error[E0533]: expected unit struct, unit variant or constant, found struct varia
22
--> $DIR/empty-struct-braces-pat-1.rs:24:9
33
|
44
LL | E::Empty3 => ()
5-
| ^^^^^^^^^ not a unit struct, unit variant or constant
5+
| ^^^^^^^^^- not a unit struct, unit variant or constant
6+
|
7+
help: use the struct variant pattern syntax
8+
|
9+
LL | E::Empty3 {} => ()
10+
| ++
611

712
error[E0533]: expected unit struct, unit variant or constant, found struct variant `XE::XEmpty3`
813
--> $DIR/empty-struct-braces-pat-1.rs:31:9
914
|
1015
LL | XE::XEmpty3 => ()
11-
| ^^^^^^^^^^^ not a unit struct, unit variant or constant
16+
| ^^^^^^^^^^^- not a unit struct, unit variant or constant
17+
|
18+
help: use the struct variant pattern syntax
19+
|
20+
LL | XE::XEmpty3 {} => ()
21+
| ++
1222

1323
error: aborting due to 2 previous errors
1424

tests/ui/empty/empty-struct-braces-pat-3.stderr

+32-4
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,53 @@ error[E0164]: expected tuple struct or tuple variant, found struct variant `E::E
22
--> $DIR/empty-struct-braces-pat-3.rs:17:9
33
|
44
LL | E::Empty3() => ()
5-
| ^^^^^^^^^^^ not a tuple struct or tuple variant
5+
| ^^^^^^^^^--
6+
| |
7+
| not a tuple struct or tuple variant
8+
|
9+
help: use the struct variant pattern syntax
10+
|
11+
LL | E::Empty3 {} => ()
12+
| ~~
613

714
error[E0164]: expected tuple struct or tuple variant, found struct variant `XE::XEmpty3`
815
--> $DIR/empty-struct-braces-pat-3.rs:21:9
916
|
1017
LL | XE::XEmpty3() => ()
11-
| ^^^^^^^^^^^^^ not a tuple struct or tuple variant
18+
| ^^^^^^^^^^^--
19+
| |
20+
| not a tuple struct or tuple variant
21+
|
22+
help: use the struct variant pattern syntax
23+
|
24+
LL | XE::XEmpty3 {} => ()
25+
| ~~
1226

1327
error[E0164]: expected tuple struct or tuple variant, found struct variant `E::Empty3`
1428
--> $DIR/empty-struct-braces-pat-3.rs:25:9
1529
|
1630
LL | E::Empty3(..) => ()
17-
| ^^^^^^^^^^^^^ not a tuple struct or tuple variant
31+
| ^^^^^^^^^----
32+
| |
33+
| not a tuple struct or tuple variant
34+
|
35+
help: use the struct variant pattern syntax
36+
|
37+
LL | E::Empty3 {} => ()
38+
| ~~
1839

1940
error[E0164]: expected tuple struct or tuple variant, found struct variant `XE::XEmpty3`
2041
--> $DIR/empty-struct-braces-pat-3.rs:29:9
2142
|
2243
LL | XE::XEmpty3(..) => ()
23-
| ^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
44+
| ^^^^^^^^^^^----
45+
| |
46+
| not a tuple struct or tuple variant
47+
|
48+
help: use the struct variant pattern syntax
49+
|
50+
LL | XE::XEmpty3 {} => ()
51+
| ~~
2452

2553
error: aborting due to 4 previous errors
2654

tests/ui/issues/issue-63983.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ error[E0533]: expected unit struct, unit variant or constant, found struct varia
1111
--> $DIR/issue-63983.rs:10:9
1212
|
1313
LL | MyEnum::Struct => "",
14-
| ^^^^^^^^^^^^^^ not a unit struct, unit variant or constant
14+
| ^^^^^^^^^^^^^^- not a unit struct, unit variant or constant
15+
|
16+
help: the struct variant's field is being ignored
17+
|
18+
LL | MyEnum::Struct { /* s: _ */ } => "",
19+
| ++++++++++++++
1520

1621
error: aborting due to 2 previous errors
1722

tests/ui/parser/recover/recover-from-bad-variant.stderr

+8-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,14 @@ error[E0164]: expected tuple struct or tuple variant, found struct variant `Enum
1818
--> $DIR/recover-from-bad-variant.rs:10:9
1919
|
2020
LL | Enum::Foo(a, b) => {}
21-
| ^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
21+
| ^^^^^^^^^------
22+
| |
23+
| not a tuple struct or tuple variant
24+
|
25+
help: the struct variant's fields are being ignored
26+
|
27+
LL | Enum::Foo { /* a: _, b: _ */ } => {}
28+
| ~~~~~~~~~~~~~~~~~~~~
2229

2330
error[E0769]: tuple variant `Enum::Bar` written as struct variant
2431
--> $DIR/recover-from-bad-variant.rs:12:9

tests/ui/pattern/pat-struct

Whitespace-only changes.

tests/ui/suggestions/issue-84700.stderr

+8-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,14 @@ error[E0164]: expected tuple struct or tuple variant, found struct variant `Farm
1111
--> $DIR/issue-84700.rs:17:9
1212
|
1313
LL | FarmAnimal::Chicken(_) => "cluck, cluck!".to_string(),
14-
| ^^^^^^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
14+
| ^^^^^^^^^^^^^^^^^^^---
15+
| |
16+
| not a tuple struct or tuple variant
17+
|
18+
help: the struct variant's field is being ignored
19+
|
20+
LL | FarmAnimal::Chicken { /* num_eggs: _ */ } => "cluck, cluck!".to_string(),
21+
| ~~~~~~~~~~~~~~~~~~~~~
1522

1623
error: aborting due to 2 previous errors
1724

tests/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr

+14-2
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,25 @@ error[E0533]: expected unit struct, unit variant or constant, found struct varia
1313
--> $DIR/incorrect-variant-form-through-alias-caught.rs:10:9
1414
|
1515
LL | let Alias::Braced = panic!();
16-
| ^^^^^^^^^^^^^ not a unit struct, unit variant or constant
16+
| ^^^^^^^^^^^^^- not a unit struct, unit variant or constant
17+
|
18+
help: use the struct variant pattern syntax
19+
|
20+
LL | let Alias::Braced {} = panic!();
21+
| ++
1722

1823
error[E0164]: expected tuple struct or tuple variant, found struct variant `Alias::Braced`
1924
--> $DIR/incorrect-variant-form-through-alias-caught.rs:12:9
2025
|
2126
LL | let Alias::Braced(..) = panic!();
22-
| ^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
27+
| ^^^^^^^^^^^^^----
28+
| |
29+
| not a tuple struct or tuple variant
30+
|
31+
help: use the struct variant pattern syntax
32+
|
33+
LL | let Alias::Braced {} = panic!();
34+
| ~~
2335

2436
error[E0618]: expected function, found enum variant `Alias::Unit`
2537
--> $DIR/incorrect-variant-form-through-alias-caught.rs:15:5

0 commit comments

Comments
 (0)