@@ -506,30 +506,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
506506 self . resolve_numeric_literals_with_default ( self . resolve_vars_if_possible ( found) ) ;
507507 // Only suggest changing the return type for methods that
508508 // haven't set a return type at all (and aren't `fn main()` or an impl).
509- match (
510- & fn_decl. output ,
511- found. is_suggestable ( self . tcx , false ) ,
512- can_suggest,
513- expected. is_unit ( ) ,
514- ) {
515- ( & hir:: FnRetTy :: DefaultReturn ( span) , true , true , true ) => {
516- err. subdiagnostic ( AddReturnTypeSuggestion :: Add { span, found } ) ;
517- true
518- }
519- ( & hir:: FnRetTy :: DefaultReturn ( span) , false , true , true ) => {
520- // FIXME: if `found` could be `impl Iterator` or `impl Fn*`, we should suggest
521- // that.
522- err. subdiagnostic ( AddReturnTypeSuggestion :: MissingHere { span } ) ;
523- true
524- }
525- ( & hir:: FnRetTy :: DefaultReturn ( span) , _, false , true ) => {
509+ match & fn_decl. output {
510+ & hir:: FnRetTy :: DefaultReturn ( span) if expected. is_unit ( ) && !can_suggest => {
526511 // `fn main()` must return `()`, do not suggest changing return type
527512 err. subdiagnostic ( ExpectedReturnTypeLabel :: Unit { span } ) ;
528- true
513+ return true ;
529514 }
530- // expectation was caused by something else, not the default return
531- ( & hir:: FnRetTy :: DefaultReturn ( _) , _, _, false ) => false ,
532- ( & hir:: FnRetTy :: Return ( ref ty) , _, _, _) => {
515+ & hir:: FnRetTy :: DefaultReturn ( span) if expected. is_unit ( ) => {
516+ if found. is_suggestable ( self . tcx , false ) {
517+ err. subdiagnostic ( AddReturnTypeSuggestion :: Add { span, found : found. to_string ( ) } ) ;
518+ return true ;
519+ } else if let ty:: Closure ( _, substs) = found. kind ( )
520+ // FIXME(compiler-errors): Get better at printing binders...
521+ && let closure = substs. as_closure ( )
522+ && closure. sig ( ) . is_suggestable ( self . tcx , false )
523+ {
524+ err. subdiagnostic ( AddReturnTypeSuggestion :: Add { span, found : closure. print_as_impl_trait ( ) . to_string ( ) } ) ;
525+ return true ;
526+ } else {
527+ // FIXME: if `found` could be `impl Iterator` we should suggest that.
528+ err. subdiagnostic ( AddReturnTypeSuggestion :: MissingHere { span } ) ;
529+ return true
530+ }
531+ }
532+ & hir:: FnRetTy :: Return ( ref ty) => {
533533 // Only point to return type if the expected type is the return type, as if they
534534 // are not, the expectation must have been caused by something else.
535535 debug ! ( "suggest_missing_return_type: return type {:?} node {:?}" , ty, ty. kind) ;
@@ -546,9 +546,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
546546 self . try_suggest_return_impl_trait ( err, expected, ty, fn_id) ;
547547 return true ;
548548 }
549- false
550549 }
550+ _ => { }
551551 }
552+ false
552553 }
553554
554555 /// check whether the return type is a generic type with a trait bound
0 commit comments