Skip to content

Commit 6b338e0

Browse files
committed
Suggest correct enum variant on typo
1 parent 4632cf2 commit 6b338e0

File tree

5 files changed

+68
-7
lines changed

5 files changed

+68
-7
lines changed

src/librustc_typeck/astconv.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ use lint;
3636

3737
use std::iter;
3838
use syntax::ast;
39-
use syntax::ptr::P;
4039
use syntax::feature_gate::{GateIssue, emit_feature_err};
40+
use syntax::ptr::P;
41+
use syntax::util::lev_distance::find_best_match_for_name;
4142
use syntax_pos::{DUMMY_SP, Span, MultiSpan};
4243

4344
pub trait AstConv<'gcx, 'tcx> {
@@ -1303,6 +1304,32 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
13031304
Err(ErrorReported) => return (tcx.types.err, Def::Err),
13041305
}
13051306
}
1307+
(&ty::Adt(adt_def, _substs), Def::Enum(_did)) => {
1308+
let ty_str = ty.to_string();
1309+
// Incorrect enum variant
1310+
let mut err = tcx.sess.struct_span_err(
1311+
span,
1312+
&format!("no variant `{}` on enum `{}`", &assoc_name.as_str(), ty_str),
1313+
);
1314+
// Check if it was a typo
1315+
let input = adt_def.variants.iter().map(|variant| &variant.name);
1316+
if let Some(suggested_name) = find_best_match_for_name(
1317+
input,
1318+
&assoc_name.as_str(),
1319+
None,
1320+
) {
1321+
err.span_suggestion_with_applicability(
1322+
span,
1323+
"did you mean",
1324+
format!("{}::{}", ty_str, suggested_name.to_string()),
1325+
Applicability::MaybeIncorrect,
1326+
);
1327+
} else {
1328+
err.span_label(span, "unknown variant");
1329+
}
1330+
err.emit();
1331+
return (tcx.types.err, Def::Err);
1332+
}
13061333
_ => {
13071334
// Don't print TyErr to the user.
13081335
if !ty.references_error() {

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ enum S {
1414

1515
fn bug(l: S) {
1616
match l {
17-
S::B{ } => { },
18-
//~^ ERROR ambiguous associated type
17+
S::B { } => { },
18+
//~^ ERROR no variant `B` on enum `S`
1919
}
2020
}
2121

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

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
error[E0223]: ambiguous associated type
1+
error: no variant `B` on enum `S`
22
--> $DIR/issue-34209.rs:17:9
33
|
4-
LL | S::B{ } => { },
5-
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::B`
4+
LL | S::B { } => { },
5+
| ^^^^ help: did you mean: `S::A`
66

77
error: aborting due to previous error
88

9-
For more information about this error, try `rustc --explain E0223`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#[derive(Debug)]
2+
enum Shape {
3+
Square { size: i32 },
4+
Circle { radius: i32 },
5+
}
6+
7+
struct S {
8+
x: usize,
9+
}
10+
11+
fn main() {
12+
println!("My shape is {:?}", Shape::Squareee { size: 5});
13+
println!("My shape is {:?}", Shape::Circl { size: 5});
14+
println!("My shape is {:?}", Shape::Rombus{ size: 5});
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: no variant `Squareee` on enum `Shape`
2+
--> $DIR/suggest-variants.rs:12:34
3+
|
4+
LL | println!("My shape is {:?}", Shape::Squareee { size: 5});
5+
| ^^^^^^^^^^^^^^^ help: did you mean: `Shape::Square`
6+
7+
error: no variant `Circl` on enum `Shape`
8+
--> $DIR/suggest-variants.rs:13:34
9+
|
10+
LL | println!("My shape is {:?}", Shape::Circl { size: 5});
11+
| ^^^^^^^^^^^^ help: did you mean: `Shape::Circle`
12+
13+
error: no variant `Rombus` on enum `Shape`
14+
--> $DIR/suggest-variants.rs:14:34
15+
|
16+
LL | println!("My shape is {:?}", Shape::Rombus{ size: 5});
17+
| ^^^^^^^^^^^^^ unknown variant
18+
19+
error: aborting due to 3 previous errors
20+

0 commit comments

Comments
 (0)