diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index d5ee66a2f0a..385ed7eb0e3 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -15,7 +15,7 @@ use super::method::MethodCallee; use hir::def::Def; use hir::def_id::{DefId, LOCAL_CRATE}; use rustc::{infer, traits}; -use rustc::ty::{self, TyCtxt, LvaluePreference, Ty}; +use rustc::ty::{self, TyCtxt, TypeFoldable, LvaluePreference, Ty}; use rustc::ty::subst::Subst; use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow}; use syntax::abi; @@ -209,17 +209,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } } - 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); + let mut err = type_error_struct!(self.tcx.sess, call_expr.span, callee_ty, E0618, + "expected function, found `{}`", + if let Some(ref path) = unit_variant { + path.to_string() + } else { + callee_ty.to_string() + }); + if let Some(path) = unit_variant { 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 def = if let hir::ExprPath(ref qpath) = expr.node { diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 76c664d7997..c1240be6d2b 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4173,6 +4173,34 @@ as possible. For better explanations, see The Rust Book: https://doc.rust-lang.org/book/ "##, +E0618: r##" +Attempted to call something which isn't a function nor a method. + +Erroneous code examples: + +```compile_fail,E0618 +enum X { + Entry, +} + +X::Entry(); // error: expected function, found `X::Entry` + +// Or even simpler: +let x = 0i32; +x(); // error: expected function, found `i32` +``` + +Only functions and methods can be called using `()`. Example: + +``` +// We declare a function: +fn i_am_a_function() {} + +// And we call it: +i_am_a_function(); +``` +"##, + } register_diagnostics! { diff --git a/src/test/compile-fail/E0618.rs b/src/test/compile-fail/E0618.rs new file mode 100644 index 00000000000..1ba2e8e2e56 --- /dev/null +++ b/src/test/compile-fail/E0618.rs @@ -0,0 +1,20 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +enum X { + Entry, +} + +fn main() { + X::Entry(); //~ ERROR expected function, found `X::Entry` [E0618] + //~| HELP did you mean to write `X::Entry`? + let x = 0i32; + x(); //~ ERROR expected function, found `i32` [E0618] +} diff --git a/src/test/compile-fail/empty-struct-unit-expr.rs b/src/test/compile-fail/empty-struct-unit-expr.rs index 273ce91a7c5..9655007604d 100644 --- a/src/test/compile-fail/empty-struct-unit-expr.rs +++ b/src/test/compile-fail/empty-struct-unit-expr.rs @@ -24,10 +24,10 @@ enum E { fn main() { let e2 = Empty2(); //~ ERROR expected function, found `Empty2` let e4 = E::Empty4(); - //~^ ERROR `E::Empty4` is being called, but it is not a function + //~^ ERROR expected function, found `E::Empty4` [E0618] //~| HELP did you mean to write `E::Empty4`? let xe2 = XEmpty2(); //~ ERROR expected function, found `empty_struct::XEmpty2` let xe4 = XE::XEmpty4(); - //~^ ERROR `XE::XEmpty4` is being called, but it is not a function + //~^ ERROR expected function, found `XE::XEmpty4` [E0618] //~| HELP did you mean to write `XE::XEmpty4`? }