in which the E0618 "expected function" diagnostic gets a makeover

Now the main span focuses on the erroneous not-a-function callee,
while showing the entire call expression is relegated to a secondary
span. In the case where the erroneous callee is itself a call, we
point out the definition, and, if the call expression spans multiple
lines, tentatively suggest a semicolon (because we suspect that the
"outer" call is actually supposed to be a tuple).

The new `bug!` assertion is, in fact, safe (`confirm_builtin_call` is
only called by `check_call`, which is only called with a first arg of
kind `ExprKind::Call` in `check_expr_kind`).

Resolves #51055.
This commit is contained in:
Zack M. Davis 2018-11-10 20:46:05 -08:00
parent 6408162ea1
commit f3e9b1a703
18 changed files with 160 additions and 60 deletions

View file

@ -12,8 +12,16 @@ LL | |y| x + y
error[E0618]: expected function, found `()`
--> $DIR/issue-20862.rs:17:13
|
LL | let x = foo(5)(2);
| ^^^^^^^^^ not a function
LL | / fn foo(x: i32) {
LL | | |y| x + y
LL | | //~^ ERROR: mismatched types
LL | | }
| |_- `foo` defined here returns `()`
...
LL | let x = foo(5)(2);
| ^^^^^^---
| |
| call expression requires function
error: aborting due to 2 previous errors

View file

@ -5,7 +5,9 @@ LL | struct Empty2;
| -------------- `Empty2` defined here
...
LL | let e2 = Empty2(); //~ ERROR expected function, found `Empty2`
| ^^^^^^^^ not a function
| ^^^^^^--
| |
| call expression requires function
error[E0618]: expected function, found enum variant `E::Empty4`
--> $DIR/empty-struct-unit-expr.rs:26:14
@ -14,7 +16,9 @@ LL | Empty4
| ------ `E::Empty4` defined here
...
LL | let e4 = E::Empty4();
| ^^^^^^^^^^^ not a function
| ^^^^^^^^^--
| |
| call expression requires function
help: `E::Empty4` is a unit variant, you need to write it without the parenthesis
|
LL | let e4 = E::Empty4;
@ -24,13 +28,17 @@ error[E0618]: expected function, found `empty_struct::XEmpty2`
--> $DIR/empty-struct-unit-expr.rs:28:15
|
LL | let xe2 = XEmpty2(); //~ ERROR expected function, found `empty_struct::XEmpty2`
| ^^^^^^^^^ not a function
| ^^^^^^^--
| |
| call expression requires function
error[E0618]: expected function, found enum variant `XE::XEmpty4`
--> $DIR/empty-struct-unit-expr.rs:29:15
|
LL | let xe4 = XE::XEmpty4();
| ^^^^^^^^^^^^^ not a function
| ^^^^^^^^^^^--
| |
| call expression requires function
help: `XE::XEmpty4` is a unit variant, you need to write it without the parenthesis
|
LL | let xe4 = XE::XEmpty4;

View file

@ -5,7 +5,9 @@ LL | Entry,
| ----- `X::Entry` defined here
...
LL | X::Entry();
| ^^^^^^^^^^ not a function
| ^^^^^^^^--
| |
| call expression requires function
help: `X::Entry` is a unit variant, you need to write it without the parenthesis
|
LL | X::Entry;
@ -17,7 +19,9 @@ error[E0618]: expected function, found `i32`
LL | let x = 0i32;
| - `i32` defined here
LL | x();
| ^^^ not a function
| ^--
| |
| call expression requires function
error: aborting due to 2 previous errors

View file

@ -4,7 +4,9 @@ error[E0618]: expected function, found `i32`
LL | fn func(i: i32) {
| - `i32` defined here
LL | i(); //~ERROR expected function, found `i32`
| ^^^ not a function
| ^--
| |
| call expression requires function
error[E0618]: expected function, found `i32`
--> $DIR/issue-10969.rs:16:5
@ -12,7 +14,9 @@ error[E0618]: expected function, found `i32`
LL | let i = 0i32;
| - `i32` defined here
LL | i(); //~ERROR expected function, found `i32`
| ^^^ not a function
| ^--
| |
| call expression requires function
error: aborting due to 2 previous errors

View file

@ -2,7 +2,9 @@ error[E0618]: expected function, found `!`
--> $DIR/issue-18532.rs:16:5
|
LL | (return)((),()); //~ ERROR expected function, found `!`
| ^^^^^^^^^^^^^^^ not a function
| ^^^^^^^^-------
| |
| call expression requires function
error: aborting due to previous error

View file

@ -5,7 +5,9 @@ LL | struct G;
| --------- `G` defined here
...
LL | let g = G(); //~ ERROR: expected function, found `G`
| ^^^ not a function
| ^--
| |
| call expression requires function
error: aborting due to previous error

View file

@ -4,7 +4,9 @@ error[E0618]: expected function, found `U`
LL | fn foo<U>(t: U) {
| - `U` defined here
LL | let y = t();
| ^^^ not a function
| ^--
| |
| call expression requires function
error[E0618]: expected function, found `Bar`
--> $DIR/issue-21701.rs:19:13
@ -13,7 +15,9 @@ LL | struct Bar;
| ----------- `Bar` defined here
...
LL | let f = Bar();
| ^^^^^ not a function
| ^^^--
| |
| call expression requires function
error: aborting due to 2 previous errors

View file

@ -4,7 +4,9 @@ error[E0618]: expected function, found `&str`
LL | let foo = "bar";
| --- `&str` defined here
LL | let x = foo("baz");
| ^^^^^^^^^^ not a function
| ^^^-------
| |
| call expression requires function
error: aborting due to previous error

View file

@ -11,7 +11,6 @@
macro_rules! macro_panic {
($not_a_function:expr, $some_argument:ident) => {
$not_a_function($some_argument)
//~^ ERROR expected function, found `{integer}`
}
}
@ -19,5 +18,5 @@ fn main() {
let mut value_a = 0;
let mut value_b = 0;
macro_panic!(value_a, value_b);
//~^ in this expansion of macro_panic!
//~^ ERROR expected function, found `{integer}`
}

View file

@ -1,14 +1,14 @@
error[E0618]: expected function, found `{integer}`
--> $DIR/issue-26237.rs:13:9
--> $DIR/issue-26237.rs:20:18
|
LL | $not_a_function($some_argument)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a function
| ------------------------------- call expression requires function
...
LL | let mut value_a = 0;
| ----------- `{integer}` defined here
LL | let mut value_b = 0;
LL | macro_panic!(value_a, value_b);
| ------------------------------- in this macro invocation
| ^^^^^^^
error: aborting due to previous error

View file

@ -2,7 +2,9 @@ error[E0618]: expected function, found `{float}`
--> $DIR/issue-45965.rs:12:30
|
LL | let a = |r: f64| if r != 0.0(r != 0.0) { 1.0 } else { 0.0 };
| ^^^^^^^^^^^^^ not a function
| ^^^----------
| |
| call expression requires function
error: aborting due to previous error

View file

@ -4,7 +4,9 @@ error[E0618]: expected function, found `main::Foo`
LL | struct Foo;
| ----------- `main::Foo` defined here
LL | (1 .. 2).find(|_| Foo(0) == 0); //~ ERROR expected function, found `main::Foo`
| ^^^^^^ not a function
| ^^^---
| |
| call expression requires function
error: aborting due to previous error

View file

@ -47,9 +47,9 @@ error[E0618]: expected function, found `(char, char)`
--> $DIR/issue-5100.rs:58:14
|
LL | let v = [('a', 'b') //~ ERROR expected function, found `(char, char)`
| ______________^
| ______________-^^^^^^^^^
LL | | ('c', 'd'),
| |_______________________^ not a function
| |_______________________- call expression requires function
error[E0308]: mismatched types
--> $DIR/issue-5100.rs:65:19

View file

@ -17,7 +17,9 @@ LL | let y = 42;
| - `{integer}` defined here
LL | let x = y.; //~ ERROR unexpected token
LL | let x = y.(); //~ ERROR unexpected token
| ^^^^ not a function
| ^---
| |
| call expression requires function
error[E0610]: `{integer}` is a primitive type and therefore doesn't have fields
--> $DIR/parse-error-correct.rs:21:15

View file

@ -171,7 +171,9 @@ LL | Unit,
| ---- `Z::Unit` defined here
...
LL | let _ = Z::Unit();
| ^^^^^^^^^ not a function
| ^^^^^^^--
| |
| call expression requires function
help: `Z::Unit` is a unit variant, you need to write it without the parenthesis
|
LL | let _ = Z::Unit;
@ -193,7 +195,9 @@ LL | Unit,
| ---- `m::E::Unit` defined here
...
LL | let _: E = m::E::Unit();
| ^^^^^^^^^^^^ not a function
| ^^^^^^^^^^--
| |
| call expression requires function
help: `m::E::Unit` is a unit variant, you need to write it without the parenthesis
|
LL | let _: E = m::E::Unit;
@ -215,7 +219,9 @@ LL | Unit,
| ---- `E::Unit` defined here
...
LL | let _: E = E::Unit();
| ^^^^^^^^^ not a function
| ^^^^^^^--
| |
| call expression requires function
help: `E::Unit` is a unit variant, you need to write it without the parenthesis
|
LL | let _: E = E::Unit;

View file

@ -0,0 +1,8 @@
fn vindictive() -> bool { true }
fn perfidy() -> (i32, i32) {
vindictive() //~ ERROR expected function, found `bool`
(1, 2)
}
fn main() {}

View file

@ -0,0 +1,16 @@
error[E0618]: expected function, found `bool`
--> $DIR/issue-51055-missing-semicolon-between-call-and-tuple.rs:4:5
|
LL | fn vindictive() -> bool { true }
| -------------------------------- `vindictive` defined here returns `bool`
...
LL | vindictive() //~ ERROR expected function, found `bool`
| -^^^^^^^^^^^- help: try adding a semicolon: `;`
| _____|
| |
LL | | (1, 2)
| |__________- call expression requires function
error: aborting due to previous error
For more information about this error, try `rustc --explain E0618`.