diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 61afac97d6409..06bec8f6ff659 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 be9ec9d73c21c..d542a10e9b605 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 81d8d97963bd0..df114351ff571 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