Skip to content

Commit 155510e

Browse files
committed
Auto merge of #55156 - PramodBisht:issue/52717, r=estebank
Fixed: Multiple errors on single typo in match pattern Here we have fixed the case where we were throwing two diagnostic messages `E0026` and `E0027` for same case. Example ``` error[E0026]: variant `A::A` does not have a field named `fob` --> src/test/ui/issue-52717.rs:20:12 | 20 | A::A { fob } => { println!("{}", fob); } | ^^^ variant `A::A` does not have this field error[E0027]: pattern does not mention field `foo` --> src/test/ui/issue-52717.rs:20:5 | 20 | A::A { fob } => { println!("{}", fob); } | ^^^^^^^^^^^^ missing field `foo` error: aborting due to 2 previous errors ``` Here above we can see that both `E0026` and `E0027` are depicting same thing. So, to fix this issue, we are simply checking if for last element of `inexistent_fields` is there any value lies in `unmentioned_fields` using levenshtein algorithm, if it does then for that case we are simply deleting element from `unmentioned_fields`. More or less, now instead of showing separate message in `E0027` we are giving extra hint on `E0026` r? @estebank
2 parents 22cc2ae + 978dc3d commit 155510e

File tree

5 files changed

+56
-20
lines changed

5 files changed

+56
-20
lines changed

src/librustc_typeck/check/_match.rs

+17-7
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use std::cmp;
2424
use syntax::ast;
2525
use syntax::source_map::Spanned;
2626
use syntax::ptr::P;
27+
use syntax::util::lev_distance::find_best_match_for_name;
2728
use syntax_pos::Span;
2829

2930
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
@@ -926,7 +927,11 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
926927

927928
self.check_pat_walk(&field.pat, field_ty, def_bm, true);
928929
}
929-
930+
let mut unmentioned_fields = variant.fields
931+
.iter()
932+
.map(|field| field.ident.modern())
933+
.filter(|ident| !used_fields.contains_key(&ident))
934+
.collect::<Vec<_>>();
930935
if inexistent_fields.len() > 0 {
931936
let (field_names, t, plural) = if inexistent_fields.len() == 1 {
932937
(format!("a field named `{}`", inexistent_fields[0].1), "this", "")
@@ -945,13 +950,23 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
945950
kind_name,
946951
tcx.item_path_str(variant.did),
947952
field_names);
948-
if let Some((span, _)) = inexistent_fields.last() {
953+
if let Some((span, ident)) = inexistent_fields.last() {
949954
err.span_label(*span,
950955
format!("{} `{}` does not have {} field{}",
951956
kind_name,
952957
tcx.item_path_str(variant.did),
953958
t,
954959
plural));
960+
if plural == "" {
961+
let input = unmentioned_fields.iter().map(|field| &field.name);
962+
let suggested_name =
963+
find_best_match_for_name(input, &ident.name.as_str(), None);
964+
if let Some(suggested_name) = suggested_name {
965+
err.span_suggestion(*span, "did you mean", suggested_name.to_string());
966+
// we don't want to throw `E0027` in case we have thrown `E0026` for them
967+
unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str());
968+
}
969+
}
955970
}
956971
if tcx.sess.teach(&err.get_code().unwrap()) {
957972
err.note(
@@ -984,11 +999,6 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
984999
tcx.sess.span_err(span, "`..` cannot be used in union patterns");
9851000
}
9861001
} else if !etc {
987-
let unmentioned_fields = variant.fields
988-
.iter()
989-
.map(|field| field.ident.modern())
990-
.filter(|ident| !used_fields.contains_key(&ident))
991-
.collect::<Vec<_>>();
9921002
if unmentioned_fields.len() > 0 {
9931003
let field_names = if unmentioned_fields.len() == 1 {
9941004
format!("field `{}`", unmentioned_fields[0])

src/test/ui/issue-52717.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
enum A {
11+
A {
12+
foo: usize,
13+
}
14+
}
15+
16+
fn main() {
17+
let x = A::A { foo: 3 };
18+
match x {
19+
A::A { fob } => { println!("{}", fob); }
20+
}
21+
}

src/test/ui/issue-52717.stderr

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0026]: variant `A::A` does not have a field named `fob`
2+
--> $DIR/issue-52717.rs:19:12
3+
|
4+
LL | A::A { fob } => { println!("{}", fob); }
5+
| ^^^
6+
| |
7+
| variant `A::A` does not have this field
8+
| help: did you mean: `foo`
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0026`.

src/test/ui/issues/issue-17800.rs

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ fn main() {
1717
match MyOption::MySome(42) {
1818
MyOption::MySome { x: 42 } => (),
1919
//~^ ERROR variant `MyOption::MySome` does not have a field named `x`
20-
//~| ERROR pattern does not mention field `0`
2120
_ => (),
2221
}
2322
}

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

+6-12
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,11 @@ error[E0026]: variant `MyOption::MySome` does not have a field named `x`
22
--> $DIR/issue-17800.rs:18:28
33
|
44
LL | MyOption::MySome { x: 42 } => (),
5-
| ^^^^^ variant `MyOption::MySome` does not have this field
5+
| ^^^^^
6+
| |
7+
| variant `MyOption::MySome` does not have this field
8+
| help: did you mean: `0`
69

7-
error[E0027]: pattern does not mention field `0`
8-
--> $DIR/issue-17800.rs:18:9
9-
|
10-
LL | MyOption::MySome { x: 42 } => (),
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `0`
12-
|
13-
= note: trying to match a tuple variant with a struct variant pattern
14-
15-
error: aborting due to 2 previous errors
10+
error: aborting due to previous error
1611

17-
Some errors occurred: E0026, E0027.
18-
For more information about an error, try `rustc --explain E0026`.
12+
For more information about this error, try `rustc --explain E0026`.

0 commit comments

Comments
 (0)