about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/_match.rs24
-rw-r--r--src/test/ui/issue-52717.rs21
-rw-r--r--src/test/ui/issue-52717.stderr12
-rw-r--r--src/test/ui/issues/issue-17800.rs1
-rw-r--r--src/test/ui/issues/issue-17800.stderr18
5 files changed, 56 insertions, 20 deletions
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index c9158af178f..d623d3662e8 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -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> {
@@ -925,7 +926,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", "")
@@ -944,13 +949,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(
@@ -983,11 +998,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])
diff --git a/src/test/ui/issue-52717.rs b/src/test/ui/issue-52717.rs
new file mode 100644
index 00000000000..d40e2bd3d53
--- /dev/null
+++ b/src/test/ui/issue-52717.rs
@@ -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); }
+  }
+}
diff --git a/src/test/ui/issue-52717.stderr b/src/test/ui/issue-52717.stderr
new file mode 100644
index 00000000000..0ef5a84671d
--- /dev/null
+++ b/src/test/ui/issue-52717.stderr
@@ -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`.
diff --git a/src/test/ui/issues/issue-17800.rs b/src/test/ui/issues/issue-17800.rs
index f7cae91aa93..8ccf34f2456 100644
--- a/src/test/ui/issues/issue-17800.rs
+++ b/src/test/ui/issues/issue-17800.rs
@@ -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`
         _ => (),
     }
 }
diff --git a/src/test/ui/issues/issue-17800.stderr b/src/test/ui/issues/issue-17800.stderr
index 2cc562fbd7a..e1c48e8a0e8 100644
--- a/src/test/ui/issues/issue-17800.stderr
+++ b/src/test/ui/issues/issue-17800.stderr
@@ -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`.