Skip to content

Commit bca365e

Browse files
authored
Auto merge of #36520 - estebank:dataless-enum, r=brson
Reword error when data-less enum variant called as function Given a file like: ``` rust enum Test { Variant, Variant2 {a: u32}, } fn main(){ let x = Test::Variant("Hello"); let y = Test::Variant2("World"); } ``` Both errors now look similar: ``` bash error[E0423]: `Test::Variant2` is the name of a struct or struct variant, but this expression uses it like a function name --> file3.rs:10:13 | 10 | let y = Test::Variant2("Hello"); | ^^^^^^^^^^^^^^ struct called like a function | = help: did you mean to write: `Test::Variant2 { /* fields */ }`? error: `Test::Variant` is the name of a data-less enum, but this expression uses it like a function name --> file3.rs:9:13 | 9 | let x = Test::Variant("World"); | ^^^^^^^^^^^^^^^^^^^^^^ data-less enum called like a function | = help: did you mean to write: `Test::Variant`? note: defined here --> file3.rs:2:5 | 2 | Variant, | ^^^^^^^ error: aborting due to previous error ``` Re: #28533
2 parents 02aa428 + a449bdb commit bca365e

File tree

2 files changed

+29
-11
lines changed

2 files changed

+29
-11
lines changed

src/librustc_typeck/check/callee.rs

+23-9
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use super::{DeferredCallResolution, Expectation, FnCtxt, TupleArgumentsFlag};
1313
use CrateCtxt;
1414
use hir::def::Def;
1515
use hir::def_id::{DefId, LOCAL_CRATE};
16+
use hir::print;
1617
use rustc::{infer, traits};
1718
use rustc::ty::{self, LvaluePreference, Ty};
1819
use syntax::parse::token;
@@ -194,15 +195,28 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
194195
let error_fn_sig;
195196

196197
let fn_sig = match callee_ty.sty {
197-
ty::TyFnDef(.., &ty::BareFnTy { ref sig, .. }) |
198-
ty::TyFnPtr(&ty::BareFnTy { ref sig, .. }) => sig,
199-
_ => {
200-
let mut err = self.type_error_struct(call_expr.span,
201-
|actual| {
202-
format!("expected function, found `{}`",
203-
actual)
204-
},
205-
callee_ty);
198+
ty::TyFnDef(.., &ty::BareFnTy {ref sig, ..}) |
199+
ty::TyFnPtr(&ty::BareFnTy {ref sig, ..}) => sig,
200+
ref t => {
201+
let mut unit_variant = None;
202+
if let &ty::TyAdt(adt_def, ..) = t {
203+
if adt_def.is_enum() {
204+
if let hir::ExprCall(ref expr, _) = call_expr.node {
205+
unit_variant = Some(print::expr_to_string(expr))
206+
}
207+
}
208+
}
209+
let mut err = if let Some(path) = unit_variant {
210+
let mut err = self.type_error_struct(call_expr.span, |_| {
211+
format!("`{}` is being called, but it is not a function", path)
212+
}, callee_ty);
213+
err.help(&format!("did you mean to write `{}`?", path));
214+
err
215+
} else {
216+
self.type_error_struct(call_expr.span, |actual| {
217+
format!("expected function, found `{}`", actual)
218+
}, callee_ty)
219+
};
206220

207221
if let hir::ExprCall(ref expr, _) = call_expr.node {
208222
let tcx = self.tcx;

src/test/compile-fail/empty-struct-unit-expr.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ enum E {
2323

2424
fn main() {
2525
let e2 = Empty2(); //~ ERROR expected function, found `Empty2`
26-
let e4 = E::Empty4(); //~ ERROR expected function, found `E`
26+
let e4 = E::Empty4();
27+
//~^ ERROR `E::Empty4` is being called, but it is not a function
28+
//~| HELP did you mean to write `E::Empty4`?
2729
let xe2 = XEmpty2(); //~ ERROR expected function, found `empty_struct::XEmpty2`
28-
let xe4 = XE::XEmpty4(); //~ ERROR expected function, found `empty_struct::XE`
30+
let xe4 = XE::XEmpty4();
31+
//~^ ERROR `XE::XEmpty4` is being called, but it is not a function
32+
//~| HELP did you mean to write `XE::XEmpty4`?
2933
}

0 commit comments

Comments
 (0)