From 6b338e034adfc1bffed942c084c892d34f1cd9b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 24 Nov 2018 16:23:11 -0800 Subject: [PATCH] Suggest correct enum variant on typo --- src/librustc_typeck/astconv.rs | 29 ++++++++++++++++++- src/test/ui/issues/issue-34209.rs | 4 +-- src/test/ui/issues/issue-34209.stderr | 7 ++--- src/test/ui/suggestions/suggest-variants.rs | 15 ++++++++++ .../ui/suggestions/suggest-variants.stderr | 20 +++++++++++++ 5 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/suggestions/suggest-variants.rs create mode 100644 src/test/ui/suggestions/suggest-variants.stderr diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index a8164c85e82..4fbbe584452 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 b3cb7d4cc30..86eb624edca 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 0dfdd8b5886..d5a5647422f 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 00000000000..4a131ed837b --- /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 00000000000..08ae68ea713 --- /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 +