@@ -59,7 +59,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5959            || self . suggest_copied_or_cloned ( err,  expr,  expr_ty,  expected) 
6060            || self . suggest_clone_for_ref ( err,  expr,  expr_ty,  expected) 
6161            || self . suggest_into ( err,  expr,  expr_ty,  expected) 
62-             || self . suggest_floating_point_literal ( err,  expr,  expected) ; 
62+             || self . suggest_floating_point_literal ( err,  expr,  expected) 
63+             || self . note_result_coercion ( err,  expr,  expected,  expr_ty) ; 
6364        if  !suggested { 
6465            self . point_at_expr_source_of_inferred_type ( err,  expr,  expr_ty,  expected) ; 
6566        } 
@@ -81,7 +82,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8182        self . annotate_expected_due_to_let_ty ( err,  expr,  error) ; 
8283        self . emit_type_mismatch_suggestions ( err,  expr,  expr_ty,  expected,  expected_ty_expr,  error) ; 
8384        self . note_type_is_not_clone ( err,  expected,  expr_ty,  expr) ; 
84-         self . note_need_for_fn_pointer ( err,  expected,  expr_ty) ; 
8585        self . note_internal_mutation_in_method ( err,  expr,  expected,  expr_ty) ; 
8686        self . check_for_range_as_method_call ( err,  expr,  expr_ty,  expected) ; 
8787        self . check_for_binding_assigned_block_without_tail_expression ( err,  expr,  expr_ty,  expected) ; 
@@ -697,6 +697,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
697697        ) ; 
698698    } 
699699
700+     pub ( crate )  fn  note_result_coercion ( 
701+         & self , 
702+         err :  & mut  Diagnostic , 
703+         expr :  & hir:: Expr < ' tcx > , 
704+         expected :  Ty < ' tcx > , 
705+         found :  Ty < ' tcx > , 
706+     )  -> bool  { 
707+         let  ty:: Adt ( e,  substs_e)  = expected. kind ( )  else  {  return  false ;  } ; 
708+         let  ty:: Adt ( f,  substs_f)  = found. kind ( )  else  {  return  false ;  } ; 
709+         if  e. did ( )  != f. did ( )  { 
710+             return  false ; 
711+         } 
712+         if  Some ( e. did ( ) )  != self . tcx . get_diagnostic_item ( sym:: Result )  { 
713+             return  false ; 
714+         } 
715+         let  map = self . tcx . hir ( ) ; 
716+         if  let  Some ( hir:: Node :: Expr ( expr) )  = map. find_parent ( expr. hir_id ) 
717+             && let  hir:: ExprKind :: Ret ( _)  = expr. kind 
718+         { 
719+             // `return foo;` 
720+         }  else  if  map. get_return_block ( expr. hir_id ) . is_some ( )  { 
721+             // Function's tail expression. 
722+         }  else  { 
723+             return  false ; 
724+         } 
725+         let  e = substs_e. type_at ( 1 ) ; 
726+         let  f = substs_f. type_at ( 1 ) ; 
727+         if  self 
728+             . infcx 
729+             . type_implements_trait ( 
730+                 self . tcx . get_diagnostic_item ( sym:: Into ) . unwrap ( ) , 
731+                 [ f,  e] , 
732+                 self . param_env , 
733+             ) 
734+             . must_apply_modulo_regions ( ) 
735+         { 
736+             err. multipart_suggestion ( 
737+                 "use `?` to coerce and return an appropriate `Err`, and wrap the resulting value \  
738+                   in `Ok` so the expression remains of type `Result`", 
739+                 vec ! [ 
740+                     ( expr. span. shrink_to_lo( ) ,  "Ok(" . to_string( ) ) , 
741+                     ( expr. span. shrink_to_hi( ) ,  "?)" . to_string( ) ) , 
742+                 ] , 
743+                 Applicability :: MaybeIncorrect , 
744+             ) ; 
745+             return  true ; 
746+         } 
747+         false 
748+     } 
749+ 
700750    /// If the expected type is an enum (Issue #55250) with any variants whose 
701751     /// sole field is of the found type, suggest such variants. (Issue #42764) 
702752     fn  suggest_compatible_variants ( 
0 commit comments