@@ -59,7 +59,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
59
59
|| self . suggest_copied_or_cloned ( err, expr, expr_ty, expected)
60
60
|| self . suggest_clone_for_ref ( err, expr, expr_ty, expected)
61
61
|| 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) ;
63
64
if !suggested {
64
65
self . point_at_expr_source_of_inferred_type ( err, expr, expr_ty, expected) ;
65
66
}
@@ -81,7 +82,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
81
82
self . annotate_expected_due_to_let_ty ( err, expr, error) ;
82
83
self . emit_type_mismatch_suggestions ( err, expr, expr_ty, expected, expected_ty_expr, error) ;
83
84
self . note_type_is_not_clone ( err, expected, expr_ty, expr) ;
84
- self . note_need_for_fn_pointer ( err, expected, expr_ty) ;
85
85
self . note_internal_mutation_in_method ( err, expr, expected, expr_ty) ;
86
86
self . check_for_range_as_method_call ( err, expr, expr_ty, expected) ;
87
87
self . check_for_binding_assigned_block_without_tail_expression ( err, expr, expr_ty, expected) ;
@@ -697,6 +697,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
697
697
) ;
698
698
}
699
699
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
+
700
750
/// If the expected type is an enum (Issue #55250) with any variants whose
701
751
/// sole field is of the found type, suggest such variants. (Issue #42764)
702
752
fn suggest_compatible_variants (
0 commit comments