Skip to content

Commit 24ee611

Browse files
authored
Rollup merge of rust-lang#59821 - euclio:unknown-enum-variants, r=davidtwco
improve unknown enum variant errors Fixes rust-lang#56517.
2 parents 484e703 + 757ef38 commit 24ee611

24 files changed

+216
-99
lines changed

src/librustc_typeck/astconv.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,27 +1362,32 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
13621362
let msg = format!("expected type, found variant `{}`", assoc_ident);
13631363
tcx.sess.span_err(span, &msg);
13641364
} else if qself_ty.is_enum() {
1365-
// Report as incorrect enum variant rather than ambiguous type.
13661365
let mut err = tcx.sess.struct_span_err(
1367-
span,
1368-
&format!("no variant `{}` on enum `{}`", &assoc_ident.as_str(), qself_ty),
1366+
assoc_ident.span,
1367+
&format!("no variant `{}` in enum `{}`", assoc_ident, qself_ty),
13691368
);
1370-
// Check if it was a typo.
1369+
13711370
let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT");
13721371
if let Some(suggested_name) = find_best_match_for_name(
13731372
adt_def.variants.iter().map(|variant| &variant.ident.name),
13741373
&assoc_ident.as_str(),
13751374
None,
13761375
) {
13771376
err.span_suggestion(
1378-
span,
1379-
"did you mean",
1380-
format!("{}::{}", qself_ty, suggested_name),
1377+
assoc_ident.span,
1378+
"there is a variant with a similar name",
1379+
suggested_name.to_string(),
13811380
Applicability::MaybeIncorrect,
13821381
);
13831382
} else {
1384-
err.span_label(span, "unknown variant");
1383+
err.span_label(span, format!("variant not found in `{}`", qself_ty));
13851384
}
1385+
1386+
if let Some(sp) = tcx.hir().span_if_local(adt_def.did) {
1387+
let sp = tcx.sess.source_map().def_span(sp);
1388+
err.span_label(sp, format!("variant `{}` not found here", assoc_ident));
1389+
}
1390+
13861391
err.emit();
13871392
} else if !qself_ty.references_error() {
13881393
// Don't print `TyErr` to the user.

src/librustc_typeck/check/method/suggest.rs

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ use rustc::hir::map as hir_map;
1414
use rustc::hir::print;
1515
use rustc::infer::type_variable::TypeVariableOrigin;
1616
use rustc::traits::Obligation;
17-
use rustc::ty::{self, Adt, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable};
17+
use rustc::ty::{self, Ty, TyCtxt, ToPolyTraitRef, ToPredicate, TypeFoldable};
1818
use rustc::ty::print::with_crate_prefix;
1919
use syntax_pos::{Span, FileName};
2020
use syntax::ast;
21-
use syntax::util::lev_distance::find_best_match_for_name;
21+
use syntax::util::lev_distance;
2222

2323
use std::cmp::Ordering;
2424

@@ -188,17 +188,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
188188
let actual = self.resolve_type_vars_if_possible(&rcvr_ty);
189189
let ty_str = self.ty_to_string(actual);
190190
let is_method = mode == Mode::MethodCall;
191-
let mut suggestion = None;
192191
let item_kind = if is_method {
193192
"method"
194193
} else if actual.is_enum() {
195-
if let Adt(ref adt_def, _) = actual.sty {
196-
let names = adt_def.variants.iter().map(|s| &s.ident.name);
197-
suggestion = find_best_match_for_name(names,
198-
&item_name.as_str(),
199-
None);
200-
}
201-
"variant"
194+
"variant or associated item"
202195
} else {
203196
match (item_name.as_str().chars().next(), actual.is_fresh_ty()) {
204197
(Some(name), false) if name.is_lowercase() => {
@@ -299,25 +292,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
299292
return;
300293
} else {
301294
span = item_name.span;
302-
let mut err = struct_span_err!(
295+
struct_span_err!(
303296
tcx.sess,
304297
span,
305298
E0599,
306299
"no {} named `{}` found for type `{}` in the current scope",
307300
item_kind,
308301
item_name,
309302
ty_str
310-
);
311-
if let Some(suggestion) = suggestion {
312-
// enum variant
313-
err.span_suggestion(
314-
span,
315-
"did you mean",
316-
suggestion.to_string(),
317-
Applicability::MaybeIncorrect,
318-
);
319-
}
320-
err
303+
)
321304
}
322305
} else {
323306
tcx.sess.diagnostic().struct_dummy()
@@ -469,14 +452,36 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
469452
out_of_scope_traits);
470453
}
471454

455+
if actual.is_enum() {
456+
let adt_def = actual.ty_adt_def().expect("enum is not an ADT");
457+
if let Some(suggestion) = lev_distance::find_best_match_for_name(
458+
adt_def.variants.iter().map(|s| &s.ident.name),
459+
&item_name.as_str(),
460+
None,
461+
) {
462+
err.span_suggestion(
463+
span,
464+
"there is a variant with a similar name",
465+
suggestion.to_string(),
466+
Applicability::MaybeIncorrect,
467+
);
468+
}
469+
}
470+
472471
if let Some(lev_candidate) = lev_candidate {
472+
let def = lev_candidate.def();
473473
err.span_suggestion(
474474
span,
475-
"did you mean",
475+
&format!(
476+
"there is {} {} with a similar name",
477+
def.article(),
478+
def.kind_name(),
479+
),
476480
lev_candidate.ident.to_string(),
477481
Applicability::MaybeIncorrect,
478482
);
479483
}
484+
480485
err.emit();
481486
}
482487

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
enum Enum { Variant }
2+
3+
impl Enum {
4+
const MISSPELLABLE: i32 = 0;
5+
fn misspellable() {}
6+
}
7+
8+
trait Trait {
9+
fn misspellable_trait() {}
10+
}
11+
12+
impl Trait for Enum {
13+
fn misspellable_trait() {}
14+
}
15+
16+
fn main() {
17+
Enum::mispellable(); //~ ERROR no variant or associated item
18+
Enum::mispellable_trait(); //~ ERROR no variant or associated item
19+
Enum::MISPELLABLE; //~ ERROR no variant or associated item
20+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
error[E0599]: no variant or associated item named `mispellable` found for type `Enum` in the current scope
2+
--> $DIR/associated-item-enum.rs:17:11
3+
|
4+
LL | enum Enum { Variant }
5+
| --------- variant or associated item `mispellable` not found here
6+
...
7+
LL | Enum::mispellable();
8+
| ^^^^^^^^^^^
9+
| |
10+
| variant or associated item not found in `Enum`
11+
| help: there is a method with a similar name: `misspellable`
12+
13+
error[E0599]: no variant or associated item named `mispellable_trait` found for type `Enum` in the current scope
14+
--> $DIR/associated-item-enum.rs:18:11
15+
|
16+
LL | enum Enum { Variant }
17+
| --------- variant or associated item `mispellable_trait` not found here
18+
...
19+
LL | Enum::mispellable_trait();
20+
| ^^^^^^^^^^^^^^^^^ variant or associated item not found in `Enum`
21+
22+
error[E0599]: no variant or associated item named `MISPELLABLE` found for type `Enum` in the current scope
23+
--> $DIR/associated-item-enum.rs:19:11
24+
|
25+
LL | enum Enum { Variant }
26+
| --------- variant or associated item `MISPELLABLE` not found here
27+
...
28+
LL | Enum::MISPELLABLE;
29+
| ^^^^^^^^^^^
30+
| |
31+
| variant or associated item not found in `Enum`
32+
| help: there is an associated constant with a similar name: `MISSPELLABLE`
33+
34+
error: aborting due to 3 previous errors
35+
36+
For more information about this error, try `rustc --explain E0599`.

src/test/ui/auto-ref-slice-plus-ref.stderr

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

src/test/ui/block-result/issue-3563.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0599]: no method named `b` found for type `&Self` in the current scope
22
--> $DIR/issue-3563.rs:3:17
33
|
44
LL | || self.b()
5-
| ^ help: did you mean: `a`
5+
| ^ help: there is a method with a similar name: `a`
66

77
error: aborting due to previous error
88

src/test/ui/bogus-tag.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
error[E0599]: no variant named `Hsl` found for type `Color` in the current scope
1+
error[E0599]: no variant or associated item named `Hsl` found for type `Color` in the current scope
22
--> $DIR/bogus-tag.rs:7:16
33
|
44
LL | enum Color { Rgb(isize, isize, isize), Rgba(isize, isize, isize, isize), }
5-
| ---------- variant `Hsl` not found here
5+
| ---------- variant or associated item `Hsl` not found here
66
...
77
LL | Color::Hsl(h, s, l) => { println!("hsl"); }
8-
| ^^^ variant not found in `Color`
8+
| ^^^ variant or associated item not found in `Color`
99

1010
error: aborting due to previous error
1111

src/test/ui/empty/empty-struct-braces-expr.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ fn main() {
1919

2020
let xe1 = XEmpty1; //~ ERROR expected value, found struct `XEmpty1`
2121
let xe1 = XEmpty1(); //~ ERROR expected function, found struct `XEmpty1`
22-
let xe3 = XE::Empty3; //~ ERROR no variant named `Empty3` found for type
23-
let xe3 = XE::Empty3(); //~ ERROR no variant named `Empty3` found for type
22+
let xe3 = XE::Empty3; //~ ERROR no variant or associated item named `Empty3` found for type
23+
let xe3 = XE::Empty3(); //~ ERROR no variant or associated item named `Empty3` found for type
24+
25+
XE::Empty1 {}; //~ ERROR no variant `Empty1` in enum `empty_struct::XE`
2426
}

src/test/ui/empty/empty-struct-braces-expr.stderr

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,31 @@ LL | let xe1 = XEmpty1();
4646
| did you mean `XEmpty1 { /* fields */ }`?
4747
| help: a unit struct with a similar name exists: `XEmpty2`
4848

49-
error[E0599]: no variant named `Empty3` found for type `empty_struct::XE` in the current scope
49+
error[E0599]: no variant or associated item named `Empty3` found for type `empty_struct::XE` in the current scope
5050
--> $DIR/empty-struct-braces-expr.rs:22:19
5151
|
5252
LL | let xe3 = XE::Empty3;
5353
| ^^^^^^
5454
| |
55-
| variant not found in `empty_struct::XE`
56-
| help: did you mean: `XEmpty3`
55+
| variant or associated item not found in `empty_struct::XE`
56+
| help: there is a variant with a similar name: `XEmpty3`
5757

58-
error[E0599]: no variant named `Empty3` found for type `empty_struct::XE` in the current scope
58+
error[E0599]: no variant or associated item named `Empty3` found for type `empty_struct::XE` in the current scope
5959
--> $DIR/empty-struct-braces-expr.rs:23:19
6060
|
6161
LL | let xe3 = XE::Empty3();
6262
| ^^^^^^
6363
| |
64-
| variant not found in `empty_struct::XE`
65-
| help: did you mean: `XEmpty3`
64+
| variant or associated item not found in `empty_struct::XE`
65+
| help: there is a variant with a similar name: `XEmpty3`
6666

67-
error: aborting due to 8 previous errors
67+
error: no variant `Empty1` in enum `empty_struct::XE`
68+
--> $DIR/empty-struct-braces-expr.rs:25:9
69+
|
70+
LL | XE::Empty1 {};
71+
| ^^^^^^ help: there is a variant with a similar name: `XEmpty3`
72+
73+
error: aborting due to 9 previous errors
6874

6975
Some errors occurred: E0423, E0599.
7076
For more information about an error, try `rustc --explain E0423`.

src/test/ui/issues/issue-22933-2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ enum Delicious {
22
Pie = 0x1,
33
Apple = 0x2,
44
ApplePie = Delicious::Apple as isize | Delicious::PIE as isize,
5-
//~^ ERROR no variant named `PIE` found for type `Delicious`
5+
//~^ ERROR no variant or associated item named `PIE` found for type `Delicious`
66
}
77

88
fn main() {}

src/test/ui/issues/issue-22933-2.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
error[E0599]: no variant named `PIE` found for type `Delicious` in the current scope
1+
error[E0599]: no variant or associated item named `PIE` found for type `Delicious` in the current scope
22
--> $DIR/issue-22933-2.rs:4:55
33
|
44
LL | enum Delicious {
5-
| -------------- variant `PIE` not found here
5+
| -------------- variant or associated item `PIE` not found here
66
...
77
LL | ApplePie = Delicious::Apple as isize | Delicious::PIE as isize,
8-
| ^^^ variant not found in `Delicious`
8+
| ^^^ variant or associated item not found in `Delicious`
99

1010
error: aborting due to previous error
1111

src/test/ui/issues/issue-23173.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,8 @@ struct Struct {
66
fn use_token(token: &Token) { unimplemented!() }
77

88
fn main() {
9-
use_token(&Token::Homura);
10-
//~^ ERROR no variant named `Homura`
11-
Struct::method();
12-
//~^ ERROR no function or associated item named `method` found for type
13-
Struct::method;
14-
//~^ ERROR no function or associated item named `method` found for type
15-
Struct::Assoc;
16-
//~^ ERROR no associated item named `Assoc` found for type `Struct` in
9+
use_token(&Token::Homura); //~ ERROR no variant or associated item named `Homura`
10+
Struct::method(); //~ ERROR no function or associated item named `method` found for type
11+
Struct::method; //~ ERROR no function or associated item named `method` found for type
12+
Struct::Assoc; //~ ERROR no associated item named `Assoc` found for type `Struct` in
1713
}

src/test/ui/issues/issue-23173.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
error[E0599]: no variant named `Homura` found for type `Token` in the current scope
1+
error[E0599]: no variant or associated item named `Homura` found for type `Token` in the current scope
22
--> $DIR/issue-23173.rs:9:23
33
|
44
LL | enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ }
5-
| ---------- variant `Homura` not found here
5+
| ---------- variant or associated item `Homura` not found here
66
...
77
LL | use_token(&Token::Homura);
8-
| ^^^^^^ variant not found in `Token`
8+
| ^^^^^^ variant or associated item not found in `Token`
99

1010
error[E0599]: no function or associated item named `method` found for type `Struct` in the current scope
11-
--> $DIR/issue-23173.rs:11:13
11+
--> $DIR/issue-23173.rs:10:13
1212
|
1313
LL | struct Struct {
1414
| ------------- function or associated item `method` not found for this
@@ -17,7 +17,7 @@ LL | Struct::method();
1717
| ^^^^^^ function or associated item not found in `Struct`
1818

1919
error[E0599]: no function or associated item named `method` found for type `Struct` in the current scope
20-
--> $DIR/issue-23173.rs:13:13
20+
--> $DIR/issue-23173.rs:11:13
2121
|
2222
LL | struct Struct {
2323
| ------------- function or associated item `method` not found for this
@@ -26,7 +26,7 @@ LL | Struct::method;
2626
| ^^^^^^ function or associated item not found in `Struct`
2727

2828
error[E0599]: no associated item named `Assoc` found for type `Struct` in the current scope
29-
--> $DIR/issue-23173.rs:15:13
29+
--> $DIR/issue-23173.rs:12:13
3030
|
3131
LL | struct Struct {
3232
| ------------- associated item `Assoc` not found for this

src/test/ui/issues/issue-23217.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
pub enum SomeEnum {
2-
B = SomeEnum::A,
3-
//~^ ERROR no variant named `A` found for type `SomeEnum`
2+
B = SomeEnum::A, //~ ERROR no variant or associated item named `A` found for type `SomeEnum`
43
}
54

65
fn main() {}

src/test/ui/issues/issue-23217.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
error[E0599]: no variant named `A` found for type `SomeEnum` in the current scope
1+
error[E0599]: no variant or associated item named `A` found for type `SomeEnum` in the current scope
22
--> $DIR/issue-23217.rs:2:19
33
|
44
LL | pub enum SomeEnum {
5-
| ----------------- variant `A` not found here
5+
| ----------------- variant or associated item `A` not found here
66
LL | B = SomeEnum::A,
77
| ^
88
| |
9-
| variant not found in `SomeEnum`
10-
| help: did you mean: `B`
9+
| variant or associated item not found in `SomeEnum`
10+
| help: there is a variant with a similar name: `B`
1111

1212
error: aborting due to previous error
1313

0 commit comments

Comments
 (0)