When suggesting fn call use an appropriate number of placeholder arguments
This commit is contained in:
parent
94fe8a3c17
commit
195d837f18
5 changed files with 148 additions and 16 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -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}`
|
||||
|
|
20
src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs
Normal file
20
src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs
Normal 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
|
||||
}
|
|
@ -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`.
|
Loading…
Add table
Add a link
Reference in a new issue