diff options
| author | Hirochika Matsumoto <git@hkmatsumoto.com> | 2021-08-12 19:10:44 +0900 |
|---|---|---|
| committer | Hirochika Matsumoto <git@hkmatsumoto.com> | 2021-09-13 21:16:05 +0900 |
| commit | 37196e36918536de06e64bd2a08b9e5fcab898fa (patch) | |
| tree | e04c15c2f5d19a0b5ee9ce021d6580496dcb129e | |
| parent | c6f32f3750987640d11a97e503f57b637fd968fd (diff) | |
| download | rust-37196e36918536de06e64bd2a08b9e5fcab898fa.tar.gz rust-37196e36918536de06e64bd2a08b9e5fcab898fa.zip | |
Suggest replacing an inexisting field for an unmentioned field
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.
| -rw-r--r-- | compiler/rustc_typeck/src/check/pat.rs | 15 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-51102.stderr | 5 | ||||
| -rw-r--r-- | src/test/ui/numeric/numeric-fields.stderr | 5 |
3 files changed, 22 insertions, 3 deletions
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 140a9d1126d..800f413e9d8 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -1447,7 +1447,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); @@ -1468,6 +1469,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, + ); } } } diff --git a/src/test/ui/issues/issue-51102.stderr b/src/test/ui/issues/issue-51102.stderr index eb9eb680200..09c52292dcc 100644 --- a/src/test/ui/issues/issue-51102.stderr +++ b/src/test/ui/issues/issue-51102.stderr @@ -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 diff --git a/src/test/ui/numeric/numeric-fields.stderr b/src/test/ui/numeric/numeric-fields.stderr index b328fbe2cfb..668405ed638 100644 --- a/src/test/ui/numeric/numeric-fields.stderr +++ b/src/test/ui/numeric/numeric-fields.stderr @@ -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 |
