1
Fork 0

When suggesting fn call use an appropriate number of placeholder arguments

This commit is contained in:
Esteban Küber 2019-08-08 12:01:22 -07:00
parent 94fe8a3c17
commit 195d837f18
5 changed files with 148 additions and 16 deletions

View file

@ -3833,19 +3833,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.0;
let sig = self.normalize_associated_types_in(expr.span, &sig);
if let Ok(_) = self.try_coerce(expr, sig.output(), expected, AllowTwoPhase::No) {
if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
err.span_suggestion(expr.span, "use parentheses to call this function", format!(
"{}({})",
code,
if sig.inputs().len() > 0 {
"..."
} else {
""
}), if sig.inputs().len() > 0 {
Applicability::MachineApplicable
} else {
Applicability::HasPlaceholders
let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
(String::new(), Applicability::MachineApplicable)
} else {
("...".to_owned(), Applicability::HasPlaceholders)
};
let mut msg = "call this function";
if let ty::FnDef(def_id, ..) = found.sty {
match self.tcx.hir().get_if_local(def_id) {
Some(Node::Item(hir::Item {
node: ItemKind::Fn(.., body_id),
..
})) => {
let body = self.tcx.hir().body(*body_id);
sugg_call = body.arguments.iter()
.map(|arg| hir::print::to_string(
hir::print::NO_ANN,
|s| s.print_pat(&arg.pat),
)).collect::<Vec<_>>().join(", ");
}
Some(Node::Ctor(hir::VariantData::Tuple(field, _))) => {
sugg_call = field.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
msg = "instatiate this tuple struct";
}
_ => {}
}
};
if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
err.span_suggestion(
expr.span,
&format!("use parentheses to {}", msg),
format!("{}({})", code, sugg_call),
applicability,
);
return true;
}

View file

@ -8,7 +8,7 @@ LL | fn test() -> Foo { Foo }
| --- ^^^
| | |
| | expected struct `Foo`, found fn item
| | help: use parentheses to call this function: `Foo(...)`
| | help: use parentheses to instatiate this tuple struct: `Foo(_)`
| expected `Foo` because of return type
|
= note: expected type `Foo`

View file

@ -202,7 +202,7 @@ LL | let _: Z = Z::Fn;
| ^^^^^
| |
| expected enum `m::n::Z`, found fn item
| help: use parentheses to call this function: `Z::Fn(...)`
| help: use parentheses to instatiate this tuple struct: `Z::Fn(_)`
|
= note: expected type `m::n::Z`
found type `fn(u8) -> m::n::Z {m::n::Z::Fn}`
@ -232,7 +232,7 @@ LL | let _: E = m::E::Fn;
| ^^^^^^^^
| |
| expected enum `m::E`, found fn item
| help: use parentheses to call this function: `m::E::Fn(...)`
| help: use parentheses to instatiate this tuple struct: `m::E::Fn(_)`
|
= note: expected type `m::E`
found type `fn(u8) -> m::E {m::E::Fn}`
@ -262,7 +262,7 @@ LL | let _: E = E::Fn;
| ^^^^^
| |
| expected enum `m::E`, found fn item
| help: use parentheses to call this function: `E::Fn(...)`
| help: use parentheses to instatiate this tuple struct: `E::Fn(_)`
|
= note: expected type `m::E`
found type `fn(u8) -> m::E {m::E::Fn}`

View file

@ -0,0 +1,20 @@
fn foo(a: usize, b: usize) -> usize { a }
fn bar() -> usize { 42 }
struct S(usize, usize);
struct V();
trait T {
fn baz(x: usize, y: usize) -> usize { x }
fn bat() -> usize { 42 }
}
fn main() {
let _: usize = foo; //~ ERROR mismatched types
let _: S = S; //~ ERROR mismatched types
let _: usize = bar; //~ ERROR mismatched types
let _: V = V; //~ ERROR mismatched types
let _: usize = T::baz; //~ ERROR mismatched types
let _: usize = T::bat; //~ ERROR mismatched types
}

View file

@ -0,0 +1,93 @@
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:14:20
|
LL | fn foo(a: usize, b: usize) -> usize { a }
| ----------------------------------- fn(usize, usize) -> usize {foo} defined here
...
LL | let _: usize = foo;
| ^^^
| |
| expected usize, found fn item
| help: use parentheses to call this function: `foo(a, b)`
|
= note: expected type `usize`
found type `fn(usize, usize) -> usize {foo}`
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:15:16
|
LL | struct S(usize, usize);
| ----------------------- fn(usize, usize) -> S {S} defined here
...
LL | let _: S = S;
| ^
| |
| expected struct `S`, found fn item
| help: use parentheses to instatiate this tuple struct: `S(_, _)`
|
= note: expected type `S`
found type `fn(usize, usize) -> S {S}`
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:16:20
|
LL | fn bar() -> usize { 42 }
| ----------------- fn() -> usize {bar} defined here
...
LL | let _: usize = bar;
| ^^^
| |
| expected usize, found fn item
| help: use parentheses to call this function: `bar()`
|
= note: expected type `usize`
found type `fn() -> usize {bar}`
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:17:16
|
LL | struct V();
| ----------- fn() -> V {V} defined here
...
LL | let _: V = V;
| ^
| |
| expected struct `V`, found fn item
| help: use parentheses to instatiate this tuple struct: `V()`
|
= note: expected type `V`
found type `fn() -> V {V}`
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:18:20
|
LL | fn baz(x: usize, y: usize) -> usize { x }
| ----------------------------------- fn(usize, usize) -> usize {<_ as T>::baz} defined here
...
LL | let _: usize = T::baz;
| ^^^^^^
| |
| expected usize, found fn item
| help: use parentheses to call this function: `T::baz(...)`
|
= note: expected type `usize`
found type `fn(usize, usize) -> usize {<_ as T>::baz}`
error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:19:20
|
LL | fn bat() -> usize { 42 }
| ----------------- fn() -> usize {<_ as T>::bat} defined here
...
LL | let _: usize = T::bat;
| ^^^^^^
| |
| expected usize, found fn item
| help: use parentheses to call this function: `T::bat()`
|
= note: expected type `usize`
found type `fn() -> usize {<_ as T>::bat}`
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0308`.