@@ -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