]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #87960 - hkmatsumoto:suggest-inexisting-field-for-unmentioned-field...
authorYuki Okushi <jtitor@2k36.org>
Sun, 19 Sep 2021 08:31:29 +0000 (17:31 +0900)
committerGitHub <noreply@github.com>
Sun, 19 Sep 2021 08:31:29 +0000 (17:31 +0900)
Suggest replacing an inexisting field for an unmentioned field

Fix #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.

compiler/rustc_typeck/src/check/pat.rs
src/test/ui/issues/issue-51102.stderr
src/test/ui/numeric/numeric-fields.stderr

index a056ab6aef2aec0398476a4b793e0cea99b40c19..829268e3cb527d7b5240a75c4cd454f5b9a95327 100644 (file)
@@ -1452,7 +1452,8 @@ fn error_inexistent_fields(
                     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);
@@ -1473,6 +1474,18 @@ fn error_inexistent_fields(
                         // 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,
+                    );
                 }
             }
         }
index eb9eb680200672da966418f7491ce6a5b9a64422..09c52292dccaff9ba05d44d83dd16faf69881588 100644 (file)
@@ -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
index b328fbe2cfb87a90c625b488bf7bb865bdb838b9..668405ed638c1d18ccbce364da0f940eb518fa36 100644 (file)
@@ -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