Skip to content

Commit 4f6be46

Browse files
Suggest fn ptr rather than fn item and suggest to use Fn trait bounds rather than the unique closure type in E0121
This is a squash of the titular commit along with these minor commits: - Improve note - Improve note pt2
1 parent 353f3a3 commit 4f6be46

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

compiler/rustc_typeck/src/collect.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,12 +1544,27 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
15441544
let mut diag = bad_placeholder_type(tcx, visitor.0);
15451545
let ret_ty = fn_sig.output();
15461546
if ret_ty != tcx.ty_error() {
1547-
diag.span_suggestion(
1548-
ty.span,
1549-
"replace with the correct return type",
1550-
ret_ty.to_string(),
1551-
Applicability::MaybeIncorrect,
1552-
);
1547+
if !ret_ty.is_closure() {
1548+
let ret_ty_str = match ret_ty.kind() {
1549+
// Suggest a function pointer return type instead of a unique function definition
1550+
// (e.g. `fn() -> i32` instead of `fn() -> i32 { f }`, the latter of which is invalid
1551+
// syntax)
1552+
ty::FnDef(..) => ret_ty.fn_sig(tcx).to_string(),
1553+
_ => ret_ty.to_string(),
1554+
};
1555+
diag.span_suggestion(
1556+
ty.span,
1557+
"replace with the correct return type",
1558+
ret_ty_str,
1559+
Applicability::MaybeIncorrect,
1560+
);
1561+
} else {
1562+
// We're dealing with a closure, so we should suggest using `impl Fn` or trait bounds
1563+
// to prevent the user from getting a papercut while trying to use the unique closure
1564+
// syntax (e.g. `[closure@src/lib.rs:2:5: 2:9]`).
1565+
diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
1566+
diag.note("for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html");
1567+
}
15531568
}
15541569
diag.emit();
15551570
ty::Binder::bind(fn_sig)

0 commit comments

Comments
 (0)