about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPietro Albini <pietro@pietroalbini.org>2018-11-25 17:05:09 +0100
committerGitHub <noreply@github.com>2018-11-25 17:05:09 +0100
commitdcae83b6a3fd0e48bf28a377761dfba1bfd678ab (patch)
treeeb6e0ca6a605b9b45bc47031078d2dd08c2d1948
parent686257c256803128b651d148219cc5f1a4ebc185 (diff)
parent6b338e034adfc1bffed942c084c892d34f1cd9b5 (diff)
downloadrust-dcae83b6a3fd0e48bf28a377761dfba1bfd678ab.tar.gz
rust-dcae83b6a3fd0e48bf28a377761dfba1bfd678ab.zip
Rollup merge of #56204 - estebank:suggest-variant, r=zackmdavis
Suggest correct enum variant on typo

Fix #37992.
-rw-r--r--src/librustc_typeck/astconv.rs29
-rw-r--r--src/test/ui/issues/issue-34209.rs4
-rw-r--r--src/test/ui/issues/issue-34209.stderr7
-rw-r--r--src/test/ui/suggestions/suggest-variants.rs15
-rw-r--r--src/test/ui/suggestions/suggest-variants.stderr20
5 files changed, 68 insertions, 7 deletions
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: `<S as Trait>::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
+