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
This commit is contained in:
commit
bca365e688
@ -13,6 +13,7 @@ use super::{DeferredCallResolution, Expectation, FnCtxt, TupleArgumentsFlag};
|
||||
use CrateCtxt;
|
||||
use hir::def::Def;
|
||||
use hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use hir::print;
|
||||
use rustc::{infer, traits};
|
||||
use rustc::ty::{self, LvaluePreference, Ty};
|
||||
use syntax::parse::token;
|
||||
@ -194,15 +195,28 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
let error_fn_sig;
|
||||
|
||||
let fn_sig = match callee_ty.sty {
|
||||
ty::TyFnDef(.., &ty::BareFnTy { ref sig, .. }) |
|
||||
ty::TyFnPtr(&ty::BareFnTy { ref sig, .. }) => sig,
|
||||
_ => {
|
||||
let mut err = self.type_error_struct(call_expr.span,
|
||||
|actual| {
|
||||
format!("expected function, found `{}`",
|
||||
actual)
|
||||
},
|
||||
callee_ty);
|
||||
ty::TyFnDef(.., &ty::BareFnTy {ref sig, ..}) |
|
||||
ty::TyFnPtr(&ty::BareFnTy {ref sig, ..}) => sig,
|
||||
ref t => {
|
||||
let mut unit_variant = None;
|
||||
if let &ty::TyAdt(adt_def, ..) = t {
|
||||
if adt_def.is_enum() {
|
||||
if let hir::ExprCall(ref expr, _) = call_expr.node {
|
||||
unit_variant = Some(print::expr_to_string(expr))
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut err = if let Some(path) = unit_variant {
|
||||
let mut err = self.type_error_struct(call_expr.span, |_| {
|
||||
format!("`{}` is being called, but it is not a function", path)
|
||||
}, callee_ty);
|
||||
err.help(&format!("did you mean to write `{}`?", path));
|
||||
err
|
||||
} else {
|
||||
self.type_error_struct(call_expr.span, |actual| {
|
||||
format!("expected function, found `{}`", actual)
|
||||
}, callee_ty)
|
||||
};
|
||||
|
||||
if let hir::ExprCall(ref expr, _) = call_expr.node {
|
||||
let tcx = self.tcx;
|
||||
|
@ -23,7 +23,11 @@ enum E {
|
||||
|
||||
fn main() {
|
||||
let e2 = Empty2(); //~ ERROR expected function, found `Empty2`
|
||||
let e4 = E::Empty4(); //~ ERROR expected function, found `E`
|
||||
let e4 = E::Empty4();
|
||||
//~^ ERROR `E::Empty4` is being called, but it is not a function
|
||||
//~| HELP did you mean to write `E::Empty4`?
|
||||
let xe2 = XEmpty2(); //~ ERROR expected function, found `empty_struct::XEmpty2`
|
||||
let xe4 = XE::XEmpty4(); //~ ERROR expected function, found `empty_struct::XE`
|
||||
let xe4 = XE::XEmpty4();
|
||||
//~^ ERROR `XE::XEmpty4` is being called, but it is not a function
|
||||
//~| HELP did you mean to write `XE::XEmpty4`?
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user