@@ -1544,12 +1544,27 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
1544
1544
let mut diag = bad_placeholder_type ( tcx, visitor. 0 ) ;
1545
1545
let ret_ty = fn_sig. output ( ) ;
1546
1546
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
+ }
1553
1568
}
1554
1569
diag. emit ( ) ;
1555
1570
ty:: Binder :: bind ( fn_sig)
0 commit comments