Skip to content

Commit

Permalink
Auto merge of #55156 - PramodBisht:issue/52717, r=estebank
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Oct 20, 2018
2 parents 22cc2ae + 978dc3d commit 155510e
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 20 deletions.
24 changes: 17 additions & 7 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use std::cmp;
use syntax::ast;
use syntax::source_map::Spanned;
use syntax::ptr::P;
use syntax::util::lev_distance::find_best_match_for_name;
use syntax_pos::Span;

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

self.check_pat_walk(&field.pat, field_ty, def_bm, true);
}

let mut unmentioned_fields = variant.fields
.iter()
.map(|field| field.ident.modern())
.filter(|ident| !used_fields.contains_key(&ident))
.collect::<Vec<_>>();
if inexistent_fields.len() > 0 {
let (field_names, t, plural) = if inexistent_fields.len() == 1 {
(format!("a field named `{}`", inexistent_fields[0].1), "this", "")
Expand All @@ -945,13 +950,23 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
kind_name,
tcx.item_path_str(variant.did),
field_names);
if let Some((span, _)) = inexistent_fields.last() {
if let Some((span, ident)) = inexistent_fields.last() {
err.span_label(*span,
format!("{} `{}` does not have {} field{}",
kind_name,
tcx.item_path_str(variant.did),
t,
plural));
if plural == "" {
let input = unmentioned_fields.iter().map(|field| &field.name);
let suggested_name =
find_best_match_for_name(input, &ident.name.as_str(), None);
if let Some(suggested_name) = suggested_name {
err.span_suggestion(*span, "did you mean", suggested_name.to_string());
// we don't want to throw `E0027` in case we have thrown `E0026` for them
unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str());
}
}
}
if tcx.sess.teach(&err.get_code().unwrap()) {
err.note(
Expand Down Expand Up @@ -984,11 +999,6 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
tcx.sess.span_err(span, "`..` cannot be used in union patterns");
}
} else if !etc {
let unmentioned_fields = variant.fields
.iter()
.map(|field| field.ident.modern())
.filter(|ident| !used_fields.contains_key(&ident))
.collect::<Vec<_>>();
if unmentioned_fields.len() > 0 {
let field_names = if unmentioned_fields.len() == 1 {
format!("field `{}`", unmentioned_fields[0])
Expand Down
21 changes: 21 additions & 0 deletions src/test/ui/issue-52717.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
enum A {
A {
foo: usize,
}
}

fn main() {
let x = A::A { foo: 3 };
match x {
A::A { fob } => { println!("{}", fob); }
}
}
12 changes: 12 additions & 0 deletions src/test/ui/issue-52717.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0026]: variant `A::A` does not have a field named `fob`
--> $DIR/issue-52717.rs:19:12
|
LL | A::A { fob } => { println!("{}", fob); }
| ^^^
| |
| variant `A::A` does not have this field
| help: did you mean: `foo`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0026`.
1 change: 0 additions & 1 deletion src/test/ui/issues/issue-17800.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ fn main() {
match MyOption::MySome(42) {
MyOption::MySome { x: 42 } => (),
//~^ ERROR variant `MyOption::MySome` does not have a field named `x`
//~| ERROR pattern does not mention field `0`
_ => (),
}
}
18 changes: 6 additions & 12 deletions src/test/ui/issues/issue-17800.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,11 @@ error[E0026]: variant `MyOption::MySome` does not have a field named `x`
--> $DIR/issue-17800.rs:18:28
|
LL | MyOption::MySome { x: 42 } => (),
| ^^^^^ variant `MyOption::MySome` does not have this field
| ^^^^^
| |
| variant `MyOption::MySome` does not have this field
| help: did you mean: `0`

error[E0027]: pattern does not mention field `0`
--> $DIR/issue-17800.rs:18:9
|
LL | MyOption::MySome { x: 42 } => (),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `0`
|
= note: trying to match a tuple variant with a struct variant pattern

error: aborting due to 2 previous errors
error: aborting due to previous error

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

0 comments on commit 155510e

Please sign in to comment.