Skip to content

Commit

Permalink
Rollup merge of rust-lang#87960 - hkmatsumoto:suggest-inexisting-fiel…
Browse files Browse the repository at this point in the history
…d-for-unmentioned-field, r=estebank

Suggest replacing an inexisting field for an unmentioned field

Fix rust-lang#87938

This PR adds a suggestion to replace an inexisting field for an
unmentioned field. Given the following code:
```rust
enum Foo {
    Bar { alpha: u8, bravo: u8, charlie: u8 },
}

fn foo(foo: Foo) {
    match foo {
        Foo::Bar {
            alpha,
            beta, // `bravo` miswritten as `beta` here.
            charlie,
        } => todo!(),
    }
}
```
the compiler now emits the error messages below.
```text
error[E0026]: variant `Foo::Bar` does not have a field named `beta`
 --> src/lib.rs:9:13
  |
9 |             beta, // `bravo` miswritten as `beta` here.
  |             ^^^^
  |             |
  |             variant `Foo::Bar` does not have this field
  |             help: `Foo::Bar` has a field named `bravo`: `bravo`
```

Note that this suggestion is available iff the number of inexisting
fields and unmentioned fields are both 1.
  • Loading branch information
JohnTitor authored Sep 19, 2021
2 parents 10967a1 + 37196e3 commit 2f210be
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 3 deletions.
15 changes: 14 additions & 1 deletion compiler/rustc_typeck/src/check/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1452,7 +1452,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
plural
),
);
if plural == "" {

if unmentioned_fields.len() == 1 {
let input =
unmentioned_fields.iter().map(|(_, field)| field.name).collect::<Vec<_>>();
let suggested_name = find_best_match_for_name(&input, ident.name, None);
Expand All @@ -1473,6 +1474,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// We don't want to throw `E0027` in case we have thrown `E0026` for them.
unmentioned_fields.retain(|&(_, x)| x.name != suggested_name);
}
} else if inexistent_fields.len() == 1 {
let unmentioned_field = unmentioned_fields[0].1.name;
err.span_suggestion_short(
ident.span,
&format!(
"`{}` has a field named `{}`",
tcx.def_path_str(variant.def_id),
unmentioned_field
),
unmentioned_field.to_string(),
Applicability::MaybeIncorrect,
);
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/test/ui/issues/issue-51102.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ error[E0026]: struct `SimpleStruct` does not have a field named `state`
--> $DIR/issue-51102.rs:13:17
|
LL | state: 0,
| ^^^^^ struct `SimpleStruct` does not have this field
| ^^^^^
| |
| struct `SimpleStruct` does not have this field
| help: `SimpleStruct` has a field named `no_state_here`

error[E0025]: field `no_state_here` bound multiple times in the pattern
--> $DIR/issue-51102.rs:24:17
Expand Down
5 changes: 4 additions & 1 deletion src/test/ui/numeric/numeric-fields.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ error[E0026]: struct `S` does not have a field named `0x1`
--> $DIR/numeric-fields.rs:7:17
|
LL | S{0: a, 0x1: b, ..} => {}
| ^^^ struct `S` does not have this field
| ^^^
| |
| struct `S` does not have this field
| help: `S` has a field named `1`

error: aborting due to 2 previous errors

Expand Down

0 comments on commit 2f210be

Please sign in to comment.