about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-08-09 16:56:47 -0700
committerEsteban Küber <esteban@kuber.com.ar>2020-08-09 17:12:57 -0700
commit9149ec74db635751e204b9793e2ad3ffcad6a849 (patch)
tree6e8fc6aa899aec2777ed28adaafffe43bc1c6fe9
parent18f3be7704a4ec7976fcd1272c728974243d29bd (diff)
downloadrust-9149ec74db635751e204b9793e2ad3ffcad6a849.tar.gz
rust-9149ec74db635751e204b9793e2ad3ffcad6a849.zip
Tweak conditions for E0026 and E0769
When we have a tuple struct used with struct we don't want to suggest using
the (valid) struct syntax with numeric field names. Instead we want to
suggest the expected syntax.

Given

```rust
fn main() {
    match MyOption::MySome(42) {
        MyOption::MySome { x: 42 } => (),
        _ => (),
    }
}
```

We now emit E0769 "tuple variant `MyOption::MySome` written as struct variant"
instead of E0026 "variant `MyOption::MySome` does not have a field named `x`".
-rw-r--r--src/librustc_typeck/check/pat.rs11
-rw-r--r--src/test/ui/issues/issue-17800.rs2
-rw-r--r--src/test/ui/issues/issue-17800.stderr11
3 files changed, 14 insertions, 10 deletions
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index f598ada900f..1c78bef9852 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -1229,8 +1229,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         Applicability::MaybeIncorrect,
                     );
 
-                    // we don't want to throw `E0027` in case we have thrown `E0026` for them
-                    unmentioned_fields.retain(|&x| x.name != suggested_name);
+                    // When we have a tuple struct used with struct we don't want to suggest using
+                    // the (valid) struct syntax with numeric field names. Instead we want to
+                    // suggest the expected syntax. We infer that this is the case by parsing the
+                    // `Ident` into an unsized integer. The suggestion will be emitted elsewhere in
+                    // `smart_resolve_context_dependent_help`.
+                    if suggested_name.to_ident_string().parse::<usize>().is_err() {
+                        // We don't want to throw `E0027` in case we have thrown `E0026` for them.
+                        unmentioned_fields.retain(|&x| x.name != suggested_name);
+                    }
                 }
             }
         }
diff --git a/src/test/ui/issues/issue-17800.rs b/src/test/ui/issues/issue-17800.rs
index 45879d68b35..5254f45d7c2 100644
--- a/src/test/ui/issues/issue-17800.rs
+++ b/src/test/ui/issues/issue-17800.rs
@@ -6,7 +6,7 @@ enum MyOption<T> {
 fn main() {
     match MyOption::MySome(42) {
         MyOption::MySome { x: 42 } => (),
-        //~^ ERROR variant `MyOption::MySome` does not have a field named `x`
+        //~^ ERROR tuple variant `MyOption::MySome` written as struct variant
         _ => (),
     }
 }
diff --git a/src/test/ui/issues/issue-17800.stderr b/src/test/ui/issues/issue-17800.stderr
index 6efc7f0c06e..fc034a0cbf3 100644
--- a/src/test/ui/issues/issue-17800.stderr
+++ b/src/test/ui/issues/issue-17800.stderr
@@ -1,12 +1,9 @@
-error[E0026]: variant `MyOption::MySome` does not have a field named `x`
-  --> $DIR/issue-17800.rs:8:28
+error[E0769]: tuple variant `MyOption::MySome` written as struct variant
+  --> $DIR/issue-17800.rs:8:9
    |
 LL |         MyOption::MySome { x: 42 } => (),
-   |                            ^
-   |                            |
-   |                            variant `MyOption::MySome` does not have this field
-   |                            help: a field with a similar name exists: `0`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `MyOption::MySome(42)`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0026`.
+For more information about this error, try `rustc --explain E0769`.