diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index a8164c85e821d..4fbbe58445254 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -36,8 +36,9 @@ use lint; use std::iter; use syntax::ast; -use syntax::ptr::P; use syntax::feature_gate::{GateIssue, emit_feature_err}; +use syntax::ptr::P; +use syntax::util::lev_distance::find_best_match_for_name; use syntax_pos::{DUMMY_SP, Span, MultiSpan}; pub trait AstConv<'gcx, 'tcx> { @@ -1303,6 +1304,32 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { Err(ErrorReported) => return (tcx.types.err, Def::Err), } } + (&ty::Adt(adt_def, _substs), Def::Enum(_did)) => { + let ty_str = ty.to_string(); + // Incorrect enum variant + let mut err = tcx.sess.struct_span_err( + span, + &format!("no variant `{}` on enum `{}`", &assoc_name.as_str(), ty_str), + ); + // Check if it was a typo + let input = adt_def.variants.iter().map(|variant| &variant.name); + if let Some(suggested_name) = find_best_match_for_name( + input, + &assoc_name.as_str(), + None, + ) { + err.span_suggestion_with_applicability( + span, + "did you mean", + format!("{}::{}", ty_str, suggested_name.to_string()), + Applicability::MaybeIncorrect, + ); + } else { + err.span_label(span, "unknown variant"); + } + err.emit(); + return (tcx.types.err, Def::Err); + } _ => { // Don't print TyErr to the user. if !ty.references_error() { diff --git a/src/test/ui/issues/issue-34209.rs b/src/test/ui/issues/issue-34209.rs index b3cb7d4cc3053..86eb624edcac1 100644 --- a/src/test/ui/issues/issue-34209.rs +++ b/src/test/ui/issues/issue-34209.rs @@ -14,8 +14,8 @@ enum S { fn bug(l: S) { match l { - S::B{ } => { }, - //~^ ERROR ambiguous associated type + S::B { } => { }, + //~^ ERROR no variant `B` on enum `S` } } diff --git a/src/test/ui/issues/issue-34209.stderr b/src/test/ui/issues/issue-34209.stderr index 0dfdd8b588634..d5a5647422f41 100644 --- a/src/test/ui/issues/issue-34209.stderr +++ b/src/test/ui/issues/issue-34209.stderr @@ -1,9 +1,8 @@ -error[E0223]: ambiguous associated type +error: no variant `B` on enum `S` --> $DIR/issue-34209.rs:17:9 | -LL | S::B{ } => { }, - | ^^^^ help: use fully-qualified syntax: `::B` +LL | S::B { } => { }, + | ^^^^ help: did you mean: `S::A` error: aborting due to previous error -For more information about this error, try `rustc --explain E0223`. diff --git a/src/test/ui/suggestions/suggest-variants.rs b/src/test/ui/suggestions/suggest-variants.rs new file mode 100644 index 0000000000000..4a131ed837b87 --- /dev/null +++ b/src/test/ui/suggestions/suggest-variants.rs @@ -0,0 +1,15 @@ +#[derive(Debug)] +enum Shape { + Square { size: i32 }, + Circle { radius: i32 }, +} + +struct S { + x: usize, +} + +fn main() { + println!("My shape is {:?}", Shape::Squareee { size: 5}); + println!("My shape is {:?}", Shape::Circl { size: 5}); + println!("My shape is {:?}", Shape::Rombus{ size: 5}); +} diff --git a/src/test/ui/suggestions/suggest-variants.stderr b/src/test/ui/suggestions/suggest-variants.stderr new file mode 100644 index 0000000000000..08ae68ea71302 --- /dev/null +++ b/src/test/ui/suggestions/suggest-variants.stderr @@ -0,0 +1,20 @@ +error: no variant `Squareee` on enum `Shape` + --> $DIR/suggest-variants.rs:12:34 + | +LL | println!("My shape is {:?}", Shape::Squareee { size: 5}); + | ^^^^^^^^^^^^^^^ help: did you mean: `Shape::Square` + +error: no variant `Circl` on enum `Shape` + --> $DIR/suggest-variants.rs:13:34 + | +LL | println!("My shape is {:?}", Shape::Circl { size: 5}); + | ^^^^^^^^^^^^ help: did you mean: `Shape::Circle` + +error: no variant `Rombus` on enum `Shape` + --> $DIR/suggest-variants.rs:14:34 + | +LL | println!("My shape is {:?}", Shape::Rombus{ size: 5}); + | ^^^^^^^^^^^^^ unknown variant + +error: aborting due to 3 previous errors +