Skip to content

Commit f332a9c

Browse files
committed
Single diagnostic for all non-mentioned fields in a pattern
1 parent 685c3c1 commit f332a9c

File tree

3 files changed

+41
-5
lines changed

3 files changed

+41
-5
lines changed

src/librustc_typeck/check/_match.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -993,13 +993,25 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
993993
tcx.sess.span_err(span, "`..` cannot be used in union patterns");
994994
}
995995
} else if !etc {
996-
for field in variant.fields
996+
let unmentioned_fields = variant.fields
997997
.iter()
998-
.filter(|field| !used_fields.contains_key(&field.name)) {
998+
.map(|field| field.name)
999+
.filter(|field| !used_fields.contains_key(&field))
1000+
.collect::<Vec<_>>();
1001+
if unmentioned_fields.len() > 0 {
1002+
let field_names = if unmentioned_fields.len() == 1 {
1003+
format!("field `{}`", unmentioned_fields[0])
1004+
} else {
1005+
format!("fields {}",
1006+
unmentioned_fields.iter()
1007+
.map(|name| format!("`{}`", name))
1008+
.collect::<Vec<String>>()
1009+
.join(", "))
1010+
};
9991011
let mut diag = struct_span_err!(tcx.sess, span, E0027,
1000-
"pattern does not mention field `{}`",
1001-
field.name);
1002-
diag.span_label(span, format!("missing field `{}`", field.name));
1012+
"pattern does not mention {}",
1013+
field_names);
1014+
diag.span_label(span, format!("missing {}", field_names));
10031015
if variant.ctor_kind == CtorKind::Fn {
10041016
diag.note("trying to match a tuple variant with a struct variant pattern");
10051017
}

src/test/ui/missing-fields-in-struct-pattern.rs

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ struct S(usize, usize, usize, usize);
1212

1313
fn main() {
1414
if let S { a, b, c, d } = S(1, 2, 3, 4) {
15+
//~^ ERROR struct `S` does not have fields named `a`, `b`, `c`, `d` [E0026]
16+
//~^ ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027]
1517
println!("hi");
1618
}
1719
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error[E0026]: struct `S` does not have fields named `a`, `b`, `c`, `d`
2+
--> $DIR/missing-fields-in-struct-pattern.rs:14:16
3+
|
4+
LL | if let S { a, b, c, d } = S(1, 2, 3, 4) {
5+
| ^ ^ ^ ^ struct `S` does not have field `d`
6+
| | | |
7+
| | | struct `S` does not have field `c`
8+
| | struct `S` does not have field `b`
9+
| struct `S` does not have field `a`
10+
11+
error[E0027]: pattern does not mention fields `0`, `1`, `2`, `3`
12+
--> $DIR/missing-fields-in-struct-pattern.rs:14:12
13+
|
14+
LL | if let S { a, b, c, d } = S(1, 2, 3, 4) {
15+
| ^^^^^^^^^^^^^^^^ missing fields `0`, `1`, `2`, `3`
16+
|
17+
= note: trying to match a tuple variant with a struct variant pattern
18+
19+
error: aborting due to 2 previous errors
20+
21+
Some errors occurred: E0026, E0027.
22+
For more information about an error, try `rustc --explain E0026`.

0 commit comments

Comments
 (0)