improve unknown enum variant errors

This commit is contained in:
Andy Russell 2019-04-08 17:58:18 -04:00
parent 3750348daf
commit 757ef38431
No known key found for this signature in database
GPG key ID: BE2221033EDBC374
24 changed files with 216 additions and 99 deletions

View file

@ -1362,12 +1362,11 @@ pub fn associated_path_to_ty(
let msg = format!("expected type, found variant `{}`", assoc_ident);
tcx.sess.span_err(span, &msg);
} else if qself_ty.is_enum() {
// Report as incorrect enum variant rather than ambiguous type.
let mut err = tcx.sess.struct_span_err(
span,
&format!("no variant `{}` on enum `{}`", &assoc_ident.as_str(), qself_ty),
assoc_ident.span,
&format!("no variant `{}` in enum `{}`", assoc_ident, qself_ty),
);
// Check if it was a typo.
let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT");
if let Some(suggested_name) = find_best_match_for_name(
adt_def.variants.iter().map(|variant| &variant.ident.name),
@ -1375,14 +1374,20 @@ pub fn associated_path_to_ty(
None,
) {
err.span_suggestion(
span,
"did you mean",
format!("{}::{}", qself_ty, suggested_name),
assoc_ident.span,
"there is a variant with a similar name",
suggested_name.to_string(),
Applicability::MaybeIncorrect,
);
} else {
err.span_label(span, "unknown variant");
err.span_label(span, format!("variant not found in `{}`", qself_ty));
}
if let Some(sp) = tcx.hir().span_if_local(adt_def.did) {
let sp = tcx.sess.source_map().def_span(sp);
err.span_label(sp, format!("variant `{}` not found here", assoc_ident));
}
err.emit();
} else if !qself_ty.references_error() {
// Don't print `TyErr` to the user.

View file

@ -14,11 +14,11 @@
use rustc::hir::print;
use rustc::infer::type_variable::TypeVariableOrigin;
use rustc::traits::Obligation;
use rustc::ty::{self, Adt, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable};
use rustc::ty::{self, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable};
use rustc::ty::print::with_crate_prefix;
use syntax_pos::{Span, FileName};
use syntax::ast;
use syntax::util::lev_distance::find_best_match_for_name;
use syntax::util::lev_distance;
use std::cmp::Ordering;
@ -188,17 +188,10 @@ pub fn report_method_error<'b>(
let actual = self.resolve_type_vars_if_possible(&rcvr_ty);
let ty_str = self.ty_to_string(actual);
let is_method = mode == Mode::MethodCall;
let mut suggestion = None;
let item_kind = if is_method {
"method"
} else if actual.is_enum() {
if let Adt(ref adt_def, _) = actual.sty {
let names = adt_def.variants.iter().map(|s| &s.ident.name);
suggestion = find_best_match_for_name(names,
&item_name.as_str(),
None);
}
"variant"
"variant or associated item"
} else {
match (item_name.as_str().chars().next(), actual.is_fresh_ty()) {
(Some(name), false) if name.is_lowercase() => {
@ -299,7 +292,7 @@ pub fn report_method_error<'b>(
return;
} else {
span = item_name.span;
let mut err = struct_span_err!(
struct_span_err!(
tcx.sess,
span,
E0599,
@ -307,17 +300,7 @@ pub fn report_method_error<'b>(
item_kind,
item_name,
ty_str
);
if let Some(suggestion) = suggestion {
// enum variant
err.span_suggestion(
span,
"did you mean",
suggestion.to_string(),
Applicability::MaybeIncorrect,
);
}
err
)
}
} else {
tcx.sess.diagnostic().struct_dummy()
@ -469,14 +452,36 @@ macro_rules! report_function {
out_of_scope_traits);
}
if actual.is_enum() {
let adt_def = actual.ty_adt_def().expect("enum is not an ADT");
if let Some(suggestion) = lev_distance::find_best_match_for_name(
adt_def.variants.iter().map(|s| &s.ident.name),
&item_name.as_str(),
None,
) {
err.span_suggestion(
span,
"there is a variant with a similar name",
suggestion.to_string(),
Applicability::MaybeIncorrect,
);
}
}
if let Some(lev_candidate) = lev_candidate {
let def = lev_candidate.def();
err.span_suggestion(
span,
"did you mean",
&format!(
"there is {} {} with a similar name",
def.article(),
def.kind_name(),
),
lev_candidate.ident.to_string(),
Applicability::MaybeIncorrect,
);
}
err.emit();
}

View file

@ -0,0 +1,20 @@
enum Enum { Variant }
impl Enum {
const MISSPELLABLE: i32 = 0;
fn misspellable() {}
}
trait Trait {
fn misspellable_trait() {}
}
impl Trait for Enum {
fn misspellable_trait() {}
}
fn main() {
Enum::mispellable(); //~ ERROR no variant or associated item
Enum::mispellable_trait(); //~ ERROR no variant or associated item
Enum::MISPELLABLE; //~ ERROR no variant or associated item
}

View file

@ -0,0 +1,36 @@
error[E0599]: no variant or associated item named `mispellable` found for type `Enum` in the current scope
--> $DIR/associated-item-enum.rs:17:11
|
LL | enum Enum { Variant }
| --------- variant or associated item `mispellable` not found here
...
LL | Enum::mispellable();
| ^^^^^^^^^^^
| |
| variant or associated item not found in `Enum`
| help: there is a method with a similar name: `misspellable`
error[E0599]: no variant or associated item named `mispellable_trait` found for type `Enum` in the current scope
--> $DIR/associated-item-enum.rs:18:11
|
LL | enum Enum { Variant }
| --------- variant or associated item `mispellable_trait` not found here
...
LL | Enum::mispellable_trait();
| ^^^^^^^^^^^^^^^^^ variant or associated item not found in `Enum`
error[E0599]: no variant or associated item named `MISPELLABLE` found for type `Enum` in the current scope
--> $DIR/associated-item-enum.rs:19:11
|
LL | enum Enum { Variant }
| --------- variant or associated item `MISPELLABLE` not found here
...
LL | Enum::MISPELLABLE;
| ^^^^^^^^^^^
| |
| variant or associated item not found in `Enum`
| help: there is an associated constant with a similar name: `MISSPELLABLE`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0599`.

View file

@ -2,7 +2,7 @@ error[E0599]: no method named `test_mut` found for type `std::vec::Vec<{integer}
--> $DIR/auto-ref-slice-plus-ref.rs:7:7
|
LL | a.test_mut();
| ^^^^^^^^ help: did you mean: `get_mut`
| ^^^^^^^^ help: there is a method with a similar name: `get_mut`
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `test_mut`, perhaps you need to implement it:

View file

@ -2,7 +2,7 @@ error[E0599]: no method named `b` found for type `&Self` in the current scope
--> $DIR/issue-3563.rs:3:17
|
LL | || self.b()
| ^ help: did you mean: `a`
| ^ help: there is a method with a similar name: `a`
error: aborting due to previous error

View file

@ -1,11 +1,11 @@
error[E0599]: no variant named `Hsl` found for type `Color` in the current scope
error[E0599]: no variant or associated item named `Hsl` found for type `Color` in the current scope
--> $DIR/bogus-tag.rs:7:16
|
LL | enum Color { Rgb(isize, isize, isize), Rgba(isize, isize, isize, isize), }
| ---------- variant `Hsl` not found here
| ---------- variant or associated item `Hsl` not found here
...
LL | Color::Hsl(h, s, l) => { println!("hsl"); }
| ^^^ variant not found in `Color`
| ^^^ variant or associated item not found in `Color`
error: aborting due to previous error

View file

@ -19,6 +19,8 @@ fn main() {
let xe1 = XEmpty1; //~ ERROR expected value, found struct `XEmpty1`
let xe1 = XEmpty1(); //~ ERROR expected function, found struct `XEmpty1`
let xe3 = XE::Empty3; //~ ERROR no variant named `Empty3` found for type
let xe3 = XE::Empty3(); //~ ERROR no variant named `Empty3` found for type
let xe3 = XE::Empty3; //~ ERROR no variant or associated item named `Empty3` found for type
let xe3 = XE::Empty3(); //~ ERROR no variant or associated item named `Empty3` found for type
XE::Empty1 {}; //~ ERROR no variant `Empty1` in enum `empty_struct::XE`
}

View file

@ -46,25 +46,31 @@ LL | let xe1 = XEmpty1();
| did you mean `XEmpty1 { /* fields */ }`?
| help: a unit struct with a similar name exists: `XEmpty2`
error[E0599]: no variant named `Empty3` found for type `empty_struct::XE` in the current scope
error[E0599]: no variant or associated item named `Empty3` found for type `empty_struct::XE` in the current scope
--> $DIR/empty-struct-braces-expr.rs:22:19
|
LL | let xe3 = XE::Empty3;
| ^^^^^^
| |
| variant not found in `empty_struct::XE`
| help: did you mean: `XEmpty3`
| variant or associated item not found in `empty_struct::XE`
| help: there is a variant with a similar name: `XEmpty3`
error[E0599]: no variant named `Empty3` found for type `empty_struct::XE` in the current scope
error[E0599]: no variant or associated item named `Empty3` found for type `empty_struct::XE` in the current scope
--> $DIR/empty-struct-braces-expr.rs:23:19
|
LL | let xe3 = XE::Empty3();
| ^^^^^^
| |
| variant not found in `empty_struct::XE`
| help: did you mean: `XEmpty3`
| variant or associated item not found in `empty_struct::XE`
| help: there is a variant with a similar name: `XEmpty3`
error: aborting due to 8 previous errors
error: no variant `Empty1` in enum `empty_struct::XE`
--> $DIR/empty-struct-braces-expr.rs:25:9
|
LL | XE::Empty1 {};
| ^^^^^^ help: there is a variant with a similar name: `XEmpty3`
error: aborting due to 9 previous errors
Some errors occurred: E0423, E0599.
For more information about an error, try `rustc --explain E0423`.

View file

@ -2,7 +2,7 @@ enum Delicious {
Pie = 0x1,
Apple = 0x2,
ApplePie = Delicious::Apple as isize | Delicious::PIE as isize,
//~^ ERROR no variant named `PIE` found for type `Delicious`
//~^ ERROR no variant or associated item named `PIE` found for type `Delicious`
}
fn main() {}

View file

@ -1,11 +1,11 @@
error[E0599]: no variant named `PIE` found for type `Delicious` in the current scope
error[E0599]: no variant or associated item named `PIE` found for type `Delicious` in the current scope
--> $DIR/issue-22933-2.rs:4:55
|
LL | enum Delicious {
| -------------- variant `PIE` not found here
| -------------- variant or associated item `PIE` not found here
...
LL | ApplePie = Delicious::Apple as isize | Delicious::PIE as isize,
| ^^^ variant not found in `Delicious`
| ^^^ variant or associated item not found in `Delicious`
error: aborting due to previous error

View file

@ -6,12 +6,8 @@ struct Struct {
fn use_token(token: &Token) { unimplemented!() }
fn main() {
use_token(&Token::Homura);
//~^ ERROR no variant named `Homura`
Struct::method();
//~^ ERROR no function or associated item named `method` found for type
Struct::method;
//~^ ERROR no function or associated item named `method` found for type
Struct::Assoc;
//~^ ERROR no associated item named `Assoc` found for type `Struct` in
use_token(&Token::Homura); //~ ERROR no variant or associated item named `Homura`
Struct::method(); //~ ERROR no function or associated item named `method` found for type
Struct::method; //~ ERROR no function or associated item named `method` found for type
Struct::Assoc; //~ ERROR no associated item named `Assoc` found for type `Struct` in
}

View file

@ -1,14 +1,14 @@
error[E0599]: no variant named `Homura` found for type `Token` in the current scope
error[E0599]: no variant or associated item named `Homura` found for type `Token` in the current scope
--> $DIR/issue-23173.rs:9:23
|
LL | enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ }
| ---------- variant `Homura` not found here
| ---------- variant or associated item `Homura` not found here
...
LL | use_token(&Token::Homura);
| ^^^^^^ variant not found in `Token`
| ^^^^^^ variant or associated item not found in `Token`
error[E0599]: no function or associated item named `method` found for type `Struct` in the current scope
--> $DIR/issue-23173.rs:11:13
--> $DIR/issue-23173.rs:10:13
|
LL | struct Struct {
| ------------- function or associated item `method` not found for this
@ -17,7 +17,7 @@ LL | Struct::method();
| ^^^^^^ function or associated item not found in `Struct`
error[E0599]: no function or associated item named `method` found for type `Struct` in the current scope
--> $DIR/issue-23173.rs:13:13
--> $DIR/issue-23173.rs:11:13
|
LL | struct Struct {
| ------------- function or associated item `method` not found for this
@ -26,7 +26,7 @@ LL | Struct::method;
| ^^^^^^ function or associated item not found in `Struct`
error[E0599]: no associated item named `Assoc` found for type `Struct` in the current scope
--> $DIR/issue-23173.rs:15:13
--> $DIR/issue-23173.rs:12:13
|
LL | struct Struct {
| ------------- associated item `Assoc` not found for this

View file

@ -1,6 +1,5 @@
pub enum SomeEnum {
B = SomeEnum::A,
//~^ ERROR no variant named `A` found for type `SomeEnum`
B = SomeEnum::A, //~ ERROR no variant or associated item named `A` found for type `SomeEnum`
}
fn main() {}

View file

@ -1,13 +1,13 @@
error[E0599]: no variant named `A` found for type `SomeEnum` in the current scope
error[E0599]: no variant or associated item named `A` found for type `SomeEnum` in the current scope
--> $DIR/issue-23217.rs:2:19
|
LL | pub enum SomeEnum {
| ----------------- variant `A` not found here
| ----------------- variant or associated item `A` not found here
LL | B = SomeEnum::A,
| ^
| |
| variant not found in `SomeEnum`
| help: did you mean: `B`
| variant or associated item not found in `SomeEnum`
| help: there is a variant with a similar name: `B`
error: aborting due to previous error

View file

@ -11,7 +11,7 @@ LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
| ^^^^^
| |
| function or associated item not found in `dyn std::ops::BitXor<_>`
| help: did you mean: `bitxor`
| help: there is a method with a similar name: `bitxor`
error[E0191]: the value of the associated type `Output` (from the trait `std::ops::BitXor`) must be specified
--> $DIR/issue-28344.rs:8:13
@ -26,7 +26,7 @@ LL | let g = BitXor::bitor;
| ^^^^^
| |
| function or associated item not found in `dyn std::ops::BitXor<_>`
| help: did you mean: `bitxor`
| help: there is a method with a similar name: `bitxor`
error: aborting due to 4 previous errors

View file

@ -1,5 +1,3 @@
// This should not cause an ICE
enum Foo {
Bar(u8)
}
@ -7,7 +5,7 @@ fn main(){
foo(|| {
match Foo::Bar(1) {
Foo::Baz(..) => (),
//~^ ERROR no variant named `Baz` found for type `Foo`
//~^ ERROR no variant or associated item named `Baz` found for type `Foo`
_ => (),
}
});

View file

@ -1,14 +1,14 @@
error[E0599]: no variant named `Baz` found for type `Foo` in the current scope
--> $DIR/issue-28971.rs:9:18
error[E0599]: no variant or associated item named `Baz` found for type `Foo` in the current scope
--> $DIR/issue-28971.rs:7:18
|
LL | enum Foo {
| -------- variant `Baz` not found here
| -------- variant or associated item `Baz` not found here
...
LL | Foo::Baz(..) => (),
| ^^^
| |
| variant not found in `Foo`
| help: did you mean: `Bar`
| variant or associated item not found in `Foo`
| help: there is a variant with a similar name: `Bar`
error: aborting due to previous error

View file

@ -4,8 +4,7 @@ enum S {
fn bug(l: S) {
match l {
S::B { } => { },
//~^ ERROR no variant `B` on enum `S`
S::B {} => {}, //~ ERROR no variant `B` in enum `S`
}
}

View file

@ -1,8 +1,11 @@
error: no variant `B` on enum `S`
--> $DIR/issue-34209.rs:7:9
error: no variant `B` in enum `S`
--> $DIR/issue-34209.rs:7:12
|
LL | S::B { } => { },
| ^^^^ help: did you mean: `S::A`
LL | enum S {
| ------ variant `B` not found here
...
LL | S::B {} => {},
| ^ help: there is a variant with a similar name: `A`
error: aborting due to previous error

View file

@ -2,7 +2,7 @@ error[E0599]: no method named `deref_err` found for type `std::result::Result<_,
--> $DIR/result-deref-err.rs:4:28
|
LL | let _result = &Err(41).deref_err();
| ^^^^^^^^^ help: did you mean: `deref_ok`
| ^^^^^^^^^ help: there is a method with a similar name: `deref_ok`
|
= note: the method `deref_err` exists but the following trait bounds were not satisfied:
`{integer} : std::ops::Deref`

View file

@ -5,19 +5,19 @@ LL | struct Foo;
| ----------- method `bat` not found for this
...
LL | f.bat(1.0);
| ^^^ help: did you mean: `bar`
| ^^^ help: there is a method with a similar name: `bar`
error[E0599]: no method named `is_emtpy` found for type `std::string::String` in the current scope
--> $DIR/suggest-methods.rs:21:15
|
LL | let _ = s.is_emtpy();
| ^^^^^^^^ help: did you mean: `is_empty`
| ^^^^^^^^ help: there is a method with a similar name: `is_empty`
error[E0599]: no method named `count_eos` found for type `u32` in the current scope
--> $DIR/suggest-methods.rs:25:19
|
LL | let _ = 63u32.count_eos();
| ^^^^^^^^^ help: did you mean: `count_zeros`
| ^^^^^^^^^ help: there is a method with a similar name: `count_zeros`
error[E0599]: no method named `count_o` found for type `u32` in the current scope
--> $DIR/suggest-methods.rs:28:19

View file

@ -12,4 +12,7 @@ fn main() {
println!("My shape is {:?}", Shape::Squareee { size: 5}); //~ ERROR no variant `Squareee`
println!("My shape is {:?}", Shape::Circl { size: 5}); //~ ERROR no variant `Circl`
println!("My shape is {:?}", Shape::Rombus{ size: 5}); //~ ERROR no variant `Rombus`
Shape::Squareee; //~ ERROR no variant
Shape::Circl; //~ ERROR no variant
Shape::Rombus; //~ ERROR no variant
}

View file

@ -1,20 +1,65 @@
error: no variant `Squareee` on enum `Shape`
--> $DIR/suggest-variants.rs:12:34
error: no variant `Squareee` in enum `Shape`
--> $DIR/suggest-variants.rs:12:41
|
LL | enum Shape {
| ---------- variant `Squareee` not found here
...
LL | println!("My shape is {:?}", Shape::Squareee { size: 5});
| ^^^^^^^^^^^^^^^ help: did you mean: `Shape::Square`
| ^^^^^^^^ help: there is a variant with a similar name: `Square`
error: no variant `Circl` on enum `Shape`
--> $DIR/suggest-variants.rs:13:34
error: no variant `Circl` in enum `Shape`
--> $DIR/suggest-variants.rs:13:41
|
LL | enum Shape {
| ---------- variant `Circl` not found here
...
LL | println!("My shape is {:?}", Shape::Circl { size: 5});
| ^^^^^^^^^^^^ help: did you mean: `Shape::Circle`
| ^^^^^ help: there is a variant with a similar name: `Circle`
error: no variant `Rombus` on enum `Shape`
--> $DIR/suggest-variants.rs:14:34
error: no variant `Rombus` in enum `Shape`
--> $DIR/suggest-variants.rs:14:41
|
LL | enum Shape {
| ---------- variant `Rombus` not found here
...
LL | println!("My shape is {:?}", Shape::Rombus{ size: 5});
| ^^^^^^^^^^^^^ unknown variant
| -------^^^^^^
| |
| variant not found in `Shape`
error: aborting due to 3 previous errors
error[E0599]: no variant or associated item named `Squareee` found for type `Shape` in the current scope
--> $DIR/suggest-variants.rs:15:12
|
LL | enum Shape {
| ---------- variant or associated item `Squareee` not found here
...
LL | Shape::Squareee;
| ^^^^^^^^
| |
| variant or associated item not found in `Shape`
| help: there is a variant with a similar name: `Square`
error[E0599]: no variant or associated item named `Circl` found for type `Shape` in the current scope
--> $DIR/suggest-variants.rs:16:12
|
LL | enum Shape {
| ---------- variant or associated item `Circl` not found here
...
LL | Shape::Circl;
| ^^^^^
| |
| variant or associated item not found in `Shape`
| help: there is a variant with a similar name: `Circle`
error[E0599]: no variant or associated item named `Rombus` found for type `Shape` in the current scope
--> $DIR/suggest-variants.rs:17:12
|
LL | enum Shape {
| ---------- variant or associated item `Rombus` not found here
...
LL | Shape::Rombus;
| ^^^^^^ variant or associated item not found in `Shape`
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0599`.