about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/method/suggest.rs17
-rw-r--r--src/test/ui/issue-23217.stderr2
-rw-r--r--src/test/ui/issue-28971.stderr2
3 files changed, 19 insertions, 2 deletions
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 61afac97d64..06bec8f6ff6 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -22,12 +22,14 @@ use rustc::traits::{Obligation, SelectionContext};
 use util::nodemap::FxHashSet;
 
 use syntax::ast;
+use syntax::util::lev_distance::find_best_match_for_name;
 use errors::DiagnosticBuilder;
 use syntax_pos::Span;
 
 use rustc::hir;
 use rustc::hir::print;
 use rustc::infer::type_variable::TypeVariableOrigin;
+use rustc::ty::TyAdt;
 
 use std::cell;
 use std::cmp::Ordering;
@@ -179,9 +181,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 let actual = self.resolve_type_vars_if_possible(&rcvr_ty);
                 let ty_string = self.ty_to_string(actual);
                 let is_method = mode == Mode::MethodCall;
+                let mut suggestion = None;
                 let type_str = if is_method {
                     "method"
                 } else if actual.is_enum() {
+                    if let TyAdt(ref adt_def, _) = actual.sty {
+                        let names = adt_def.variants.iter().map(|s| &s.name);
+                        suggestion = find_best_match_for_name(names,
+                                                              &item_name.as_str(),
+                                                              None);
+                    }
                     "variant"
                 } else {
                     match (item_name.as_str().chars().next(), actual.is_fresh_ty()) {
@@ -256,7 +265,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         err.emit();
                         return;
                     } else {
-                        struct_span_err!(
+                        let mut err = struct_span_err!(
                             tcx.sess,
                             span,
                             E0599,
@@ -264,7 +273,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                             type_str,
                             item_name,
                             ty_string
-                        )
+                        );
+                        if let Some(suggestion) = suggestion {
+                            err.note(&format!("did you mean `{}::{}`?", type_str, suggestion));
+                        }
+                        err
                     }
                 } else {
                     tcx.sess.diagnostic().struct_dummy()
diff --git a/src/test/ui/issue-23217.stderr b/src/test/ui/issue-23217.stderr
index be9ec9d73c2..d542a10e9b6 100644
--- a/src/test/ui/issue-23217.stderr
+++ b/src/test/ui/issue-23217.stderr
@@ -5,6 +5,8 @@ LL | pub enum SomeEnum {
    | ----------------- variant `A` not found here
 LL |     B = SomeEnum::A,
    |         ^^^^^^^^^^^ variant not found in `SomeEnum`
+   |
+   = note: did you mean `variant::B`?
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-28971.stderr b/src/test/ui/issue-28971.stderr
index 81d8d97963b..df114351ff5 100644
--- a/src/test/ui/issue-28971.stderr
+++ b/src/test/ui/issue-28971.stderr
@@ -6,6 +6,8 @@ LL | enum Foo {
 ...
 LL |             Foo::Baz(..) => (),
    |             ^^^^^^^^^^^^ variant not found in `Foo`
+   |
+   = note: did you mean `variant::Bar`?
 
 error: aborting due to previous error