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
2 changed files with 29 additions and 11 deletions
|
|
@ -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…
Add table
Add a link
Reference in a new issue