Skip to content

Commit dad230b

Browse files
committed
Suggest calling function on type error when finding bare fn
1 parent 1bd05ef commit dad230b

File tree

5 files changed

+124
-12
lines changed

5 files changed

+124
-12
lines changed

src/librustc_typeck/check/mod.rs

+43
Original file line numberDiff line numberDiff line change
@@ -3819,6 +3819,41 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38193819
pointing_at_return_type
38203820
}
38213821

3822+
fn suggest_fn_call(
3823+
&self,
3824+
err: &mut DiagnosticBuilder<'tcx>,
3825+
expr: &hir::Expr,
3826+
expected: Ty<'tcx>,
3827+
found: Ty<'tcx>,
3828+
) -> bool {
3829+
if let ty::FnDef(..) | ty::FnPtr(_) = &found.sty {
3830+
let sig = found.fn_sig(self.tcx);
3831+
let sig = self
3832+
.replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig)
3833+
.0;
3834+
let sig = self.normalize_associated_types_in(expr.span, &sig);
3835+
if let Ok(_) = self.try_coerce(expr, sig.output(), expected, AllowTwoPhase::No) {
3836+
if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
3837+
err.span_suggestion(expr.span, "use parentheses to call this function", format!(
3838+
"{}({})",
3839+
code,
3840+
if sig.inputs().len() > 0 {
3841+
"..."
3842+
} else {
3843+
""
3844+
}), if sig.inputs().len() > 0 {
3845+
Applicability::MachineApplicable
3846+
} else {
3847+
Applicability::HasPlaceholders
3848+
}
3849+
);
3850+
return true;
3851+
}
3852+
}
3853+
}
3854+
false
3855+
}
3856+
38223857
pub fn suggest_ref_or_into(
38233858
&self,
38243859
err: &mut DiagnosticBuilder<'tcx>,
@@ -3833,6 +3868,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
38333868
suggestion,
38343869
Applicability::MachineApplicable,
38353870
);
3871+
} else if let (ty::FnDef(def_id, ..), true) = (
3872+
&found.sty,
3873+
self.suggest_fn_call(err, expr, expected, found),
3874+
) {
3875+
if let Some(sp) = self.tcx.hir().span_if_local(*def_id) {
3876+
let sp = self.sess().source_map().def_span(sp);
3877+
err.span_label(sp, &format!("{} defined here", found));
3878+
}
38363879
} else if !self.check_for_cast(err, expr, found, expected) {
38373880
let is_struct_pat_shorthand_field = self.is_hir_id_from_struct_pattern_shorthand_field(
38383881
expr.hir_id,

src/test/ui/issues/issue-35241.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
error[E0308]: mismatched types
22
--> $DIR/issue-35241.rs:3:20
33
|
4+
LL | struct Foo(u32);
5+
| ---------------- fn(u32) -> Foo {Foo} defined here
6+
LL |
47
LL | fn test() -> Foo { Foo }
58
| --- ^^^
69
| | |
710
| | expected struct `Foo`, found fn item
8-
| | did you mean `Foo(/* fields */)`?
11+
| | help: use parentheses to call this function: `Foo(...)`
912
| expected `Foo` because of return type
1013
|
1114
= note: expected type `Foo`

src/test/ui/resolve/privacy-enum-ctor.stderr

+21-3
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,14 @@ LL | let _: Z = m::n::Z::Unit {};
195195
error[E0308]: mismatched types
196196
--> $DIR/privacy-enum-ctor.rs:27:20
197197
|
198+
LL | Fn(u8),
199+
| ------ fn(u8) -> m::n::Z {m::n::Z::Fn} defined here
200+
...
198201
LL | let _: Z = Z::Fn;
199-
| ^^^^^ expected enum `m::n::Z`, found fn item
202+
| ^^^^^
203+
| |
204+
| expected enum `m::n::Z`, found fn item
205+
| help: use parentheses to call this function: `Z::Fn(...)`
200206
|
201207
= note: expected type `m::n::Z`
202208
found type `fn(u8) -> m::n::Z {m::n::Z::Fn}`
@@ -219,8 +225,14 @@ LL | let _ = Z::Unit;
219225
error[E0308]: mismatched types
220226
--> $DIR/privacy-enum-ctor.rs:43:16
221227
|
228+
LL | Fn(u8),
229+
| ------ fn(u8) -> m::E {m::E::Fn} defined here
230+
...
222231
LL | let _: E = m::E::Fn;
223-
| ^^^^^^^^ expected enum `m::E`, found fn item
232+
| ^^^^^^^^
233+
| |
234+
| expected enum `m::E`, found fn item
235+
| help: use parentheses to call this function: `m::E::Fn(...)`
224236
|
225237
= note: expected type `m::E`
226238
found type `fn(u8) -> m::E {m::E::Fn}`
@@ -243,8 +255,14 @@ LL | let _: E = m::E::Unit;
243255
error[E0308]: mismatched types
244256
--> $DIR/privacy-enum-ctor.rs:51:16
245257
|
258+
LL | Fn(u8),
259+
| ------ fn(u8) -> m::E {m::E::Fn} defined here
260+
...
246261
LL | let _: E = E::Fn;
247-
| ^^^^^ expected enum `m::E`, found fn item
262+
| ^^^^^
263+
| |
264+
| expected enum `m::E`, found fn item
265+
| help: use parentheses to call this function: `E::Fn(...)`
248266
|
249267
= note: expected type `m::E`
250268
found type `fn(u8) -> m::E {m::E::Fn}`

src/test/ui/substs-ppaux.normal.stderr

+28-4
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,59 @@
11
error[E0308]: mismatched types
22
--> $DIR/substs-ppaux.rs:16:17
33
|
4+
LL | fn bar<'a, T>() where T: 'a {}
5+
| --------------------------- fn() {<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>} defined here
6+
...
47
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9+
| |
10+
| expected (), found fn item
11+
| help: use parentheses to call this function: `<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>()`
612
|
713
= note: expected type `()`
814
found type `fn() {<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>}`
915

1016
error[E0308]: mismatched types
1117
--> $DIR/substs-ppaux.rs:25:17
1218
|
19+
LL | fn bar<'a, T>() where T: 'a {}
20+
| --------------------------- fn() {<i8 as Foo<'static, 'static>>::bar::<'static, char>} defined here
21+
...
1322
LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>;
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24+
| |
25+
| expected (), found fn item
26+
| help: use parentheses to call this function: `<i8 as Foo<'static, 'static, u32>>::bar::<'static, char>()`
1527
|
1628
= note: expected type `()`
1729
found type `fn() {<i8 as Foo<'static, 'static>>::bar::<'static, char>}`
1830

1931
error[E0308]: mismatched types
2032
--> $DIR/substs-ppaux.rs:33:17
2133
|
34+
LL | fn baz() {}
35+
| -------- fn() {<i8 as Foo<'static, 'static, u8>>::baz} defined here
36+
...
2237
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz;
23-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
38+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39+
| |
40+
| expected (), found fn item
41+
| help: use parentheses to call this function: `<i8 as Foo<'static, 'static, u8>>::baz()`
2442
|
2543
= note: expected type `()`
2644
found type `fn() {<i8 as Foo<'static, 'static, u8>>::baz}`
2745

2846
error[E0308]: mismatched types
2947
--> $DIR/substs-ppaux.rs:41:17
3048
|
49+
LL | fn foo<'z>() where &'z (): Sized {
50+
| -------------------------------- fn() {foo::<'static>} defined here
51+
...
3152
LL | let x: () = foo::<'static>;
32-
| ^^^^^^^^^^^^^^ expected (), found fn item
53+
| ^^^^^^^^^^^^^^
54+
| |
55+
| expected (), found fn item
56+
| help: use parentheses to call this function: `foo::<'static>()`
3357
|
3458
= note: expected type `()`
3559
found type `fn() {foo::<'static>}`

src/test/ui/substs-ppaux.verbose.stderr

+28-4
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,59 @@
11
error[E0308]: mismatched types
22
--> $DIR/substs-ppaux.rs:16:17
33
|
4+
LL | fn bar<'a, T>() where T: 'a {}
5+
| --------------------------- fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::bar::<ReStatic, char>} defined here
6+
...
47
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::bar::<'static, char>;
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9+
| |
10+
| expected (), found fn item
11+
| help: use parentheses to call this function: `<i8 as Foo<'static, 'static, u8>>::bar::<'static, char>()`
612
|
713
= note: expected type `()`
814
found type `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::bar::<ReStatic, char>}`
915

1016
error[E0308]: mismatched types
1117
--> $DIR/substs-ppaux.rs:25:17
1218
|
19+
LL | fn bar<'a, T>() where T: 'a {}
20+
| --------------------------- fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>} defined here
21+
...
1322
LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>;
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
24+
| |
25+
| expected (), found fn item
26+
| help: use parentheses to call this function: `<i8 as Foo<'static, 'static, u32>>::bar::<'static, char>()`
1527
|
1628
= note: expected type `()`
1729
found type `fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>}`
1830

1931
error[E0308]: mismatched types
2032
--> $DIR/substs-ppaux.rs:33:17
2133
|
34+
LL | fn baz() {}
35+
| -------- fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::baz} defined here
36+
...
2237
LL | let x: () = <i8 as Foo<'static, 'static, u8>>::baz;
23-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found fn item
38+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39+
| |
40+
| expected (), found fn item
41+
| help: use parentheses to call this function: `<i8 as Foo<'static, 'static, u8>>::baz()`
2442
|
2543
= note: expected type `()`
2644
found type `fn() {<i8 as Foo<ReStatic, ReStatic, u8>>::baz}`
2745

2846
error[E0308]: mismatched types
2947
--> $DIR/substs-ppaux.rs:41:17
3048
|
49+
LL | fn foo<'z>() where &'z (): Sized {
50+
| -------------------------------- fn() {foo::<ReStatic>} defined here
51+
...
3152
LL | let x: () = foo::<'static>;
32-
| ^^^^^^^^^^^^^^ expected (), found fn item
53+
| ^^^^^^^^^^^^^^
54+
| |
55+
| expected (), found fn item
56+
| help: use parentheses to call this function: `foo::<'static>()`
3357
|
3458
= note: expected type `()`
3559
found type `fn() {foo::<ReStatic>}`

0 commit comments

Comments
 (0)