Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. If you cannot produce a minimal reproduction case (something that would work in isolation), please provide the steps or even link to a repository that causes the problematic output to occur. --Given the following code: The current output is: <!-- The following is not always necessary. --Ideally the output should suggest how to specify the return type when a function returns a closure. <!-- If the problem is not self-explanatory, please provide a rationale for the change. --<!-- If dramatically different output is caused by small changes, consider also adding them here. If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. The output might also be different depending on the Edition. --<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
Is some thing like this not ok ?
release-assignment
It's ok but I was wondering if it's possible to make the compiler give some form of a suggestion to the user on how to do this. Cause the current diagnostics does not suggest how to fix it.

Discussion:
} Ok(self) } <ins> fn pretty_closure_as_impl( mut self, closure: ty::ClosureSubsts<'tcx>, ) -> Result<Self::Const, Self::Error> { let sig = closure.sig(); let kind = closure.kind_ty().to_opt_closure_kind().unwrap_or(ty::ClosureKind::Fn); write!(self, "impl ")?; self.wrap_binder(&sig, |sig, mut cx| { define_scoped_cx!(cx); p!(print(kind), "("); for (i, arg) in sig.inputs()[0].tuple_fields().iter().enumerate() { if i > 0 { p!(", "); } p!(print(arg)); } p!(")"); if !sig.output().is_unit() { p!(" -> ", print(sig.output())); } Ok(cx) }) } </ins> } // HACK(eddyb) boxed to avoid moving around a large struct by-value.

} } <ins> #[derive(Debug, Copy, Clone, TypeFoldable, TypeVisitable, Lift)] pub struct PrintClosureAsImpl<'tcx> { pub closure: ty::ClosureSubsts<'tcx>, } </ins> forward_display_to_print! { ty::Region<'tcx>, Ty<'tcx>,

p!(print(self.0.trait_ref.print_only_trait_path())); } <ins> PrintClosureAsImpl<'tcx> { p!(pretty_closure_as_impl(self.closure)) } </ins> ty::ParamTy { p!(write("{}", self.name)) }

_ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind()), } } <ins> pub fn print_as_impl_trait(self) -> ty::print::PrintClosureAsImpl<'tcx> { ty::print::PrintClosureAsImpl { closure: self } } </ins> } /// Similar to `ClosureSubsts`; see the above documentation for more.

self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(found)); // Only suggest changing the return type for methods that // haven't set a return type at all (and aren't `fn main()` or an impl). <del> match ( &fn_decl.output, found.is_suggestable(self.tcx, false), can_suggest, expected.is_unit(), ) { (&hir::FnRetTy::DefaultReturn(span), true, true, true) => { err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found }); true } (&hir::FnRetTy::DefaultReturn(span), false, true, true) => { // FIXME: if `found` could be `impl Iterator` or `impl Fn*`, we should suggest // that. err.subdiagnostic(AddReturnTypeSuggestion::MissingHere { span }); true } (&hir::FnRetTy::DefaultReturn(span), _, false, true) => { </del> <ins> match &fn_decl.output { &hir::FnRetTy::DefaultReturn(span) if expected.is_unit() && !can_suggest => { </ins> // `fn main()` must return `()`, do not suggest changing return type err.subdiagnostic(ExpectedReturnTypeLabel::Unit { span }); <del> true </del> <ins> return true; </ins> } <del> // expectation was caused by something else, not the default return (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false, (&hir::FnRetTy::Return(ref ty), _, _, _) => { </del> <ins> &hir::FnRetTy::DefaultReturn(span) if expected.is_unit() => { if found.is_suggestable(self.tcx, false) { err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found: found.to_string() }); return true; } else if let ty::Closure(_, substs) = found.kind() // FIXME(compiler-errors): Get better at printing binders... && let closure = substs.as_closure() && closure.sig().is_suggestable(self.tcx, false) { err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found: closure.print_as_impl_trait().to_string() }); return true; } else { // FIXME: if `found` could be `impl Iterator` we should suggest that. err.subdiagnostic(AddReturnTypeSuggestion::MissingHere { span }); return true } } &hir::FnRetTy::Return(ref ty) => { </ins> // Only point to return type if the expected type is the return type, as if they // are not, the expectation must have been caused by something else. debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);

self.try_suggest_return_impl_trait(err, expected, ty, fn_id); return true; } <del> false </del> } <ins> _ => {} </ins> } <ins> false </ins> } /// check whether the return type is a generic type with a trait bound

} #[derive(SessionSubdiagnostic)] <del> pub enum AddReturnTypeSuggestion<'tcx> { </del> <ins> pub enum AddReturnTypeSuggestion { </ins> #[suggestion( typeck::add_return_type_add, code = "-> {found} ",

Add { #[primary_span] span: Span, <del> found: Ty<'tcx>, </del> <ins> found: String, </ins> }, #[suggestion( typeck::add_return_type_missing_here,

<ins> fn foo() { //~^ HELP try adding a return type |x: &i32| 1i32 //~^ ERROR mismatched types } fn bar(i: impl Sized) { //~^ HELP a return type might be missing here || i //~^ ERROR mismatched types } fn main() {} </ins>

<ins> error[E0308]: mismatched types --> $DIR/return-closures.rs:3:5 | LL | fn foo() { |          - help: try adding a return type: `-> impl for<'r> Fn(&'r i32) -> i32` LL | LL |     |x: &i32| 1i32 |     ^^^^^^^^^^^^^^ expected `()`, found closure | = note: expected unit type `()` found closure `[closure@$DIR/return-closures.rs:3:5: 3:14]` error[E0308]: mismatched types --> $DIR/return-closures.rs:9:5 | LL | fn bar(i: impl Sized) { |                       - help: a return type might be missing here: `-> _` LL | LL |     || i |     ^^^^ expected `()`, found closure | = note: expected unit type `()` found closure `[closure@$DIR/return-closures.rs:9:5: 9:7]` error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. </ins>