@@ -743,6 +743,35 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
743743 ObligationCauseCode :: Pattern { origin_expr : false , span : Some ( span) , .. } => {
744744 err. span_label ( span, "expected due to this" ) ;
745745 }
746+ ObligationCauseCode :: BlockTailExpression (
747+ _,
748+ hir:: MatchSource :: TryDesugar ( scrut_hir_id) ,
749+ ) => {
750+ if let Some ( ty:: error:: ExpectedFound { expected, .. } ) = exp_found {
751+ let scrut_expr = self . tcx . hir ( ) . expect_expr ( scrut_hir_id) ;
752+ let scrut_ty = if let hir:: ExprKind :: Call ( _, args) = & scrut_expr. kind {
753+ let arg_expr = args. first ( ) . expect ( "try desugaring call w/out arg" ) ;
754+ self . typeck_results . as_ref ( ) . and_then ( |typeck_results| {
755+ typeck_results. expr_ty_opt ( arg_expr)
756+ } )
757+ } else {
758+ bug ! ( "try desugaring w/out call expr as scrutinee" ) ;
759+ } ;
760+
761+ match scrut_ty {
762+ Some ( ty) if expected == ty => {
763+ let source_map = self . tcx . sess . source_map ( ) ;
764+ err. span_suggestion (
765+ source_map. end_point ( cause. span ( ) ) ,
766+ "try removing this `?`" ,
767+ "" ,
768+ Applicability :: MachineApplicable ,
769+ ) ;
770+ }
771+ _ => { }
772+ }
773+ }
774+ } ,
746775 ObligationCauseCode :: MatchExpressionArm ( box MatchExpressionArmCause {
747776 arm_block_id,
748777 arm_span,
@@ -752,12 +781,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
752781 prior_arm_ty,
753782 source,
754783 ref prior_arms,
755- scrut_hir_id,
756784 opt_suggest_box_span,
757785 scrut_span,
758786 ..
759787 } ) => match source {
760- hir:: MatchSource :: TryDesugar => {
788+ hir:: MatchSource :: TryDesugar ( scrut_hir_id ) => {
761789 if let Some ( ty:: error:: ExpectedFound { expected, .. } ) = exp_found {
762790 let scrut_expr = self . tcx . hir ( ) . expect_expr ( scrut_hir_id) ;
763791 let scrut_ty = if let hir:: ExprKind :: Call ( _, args) = & scrut_expr. kind {
@@ -1927,7 +1955,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
19271955 true
19281956 } ;
19291957
1930- if should_suggest_fixes {
1958+ // FIXME(#73154): For now, we do leak check when coercing function
1959+ // pointers in typeck, instead of only during borrowck. This can lead
1960+ // to these `RegionsInsufficientlyPolymorphic` errors that aren't helpful.
1961+ if should_suggest_fixes
1962+ && !matches ! ( terr, TypeError :: RegionsInsufficientlyPolymorphic ( ..) )
1963+ {
19311964 self . suggest_tuple_pattern ( cause, & exp_found, diag) ;
19321965 self . suggest_accessing_field_where_appropriate ( cause, & exp_found, diag) ;
19331966 self . suggest_await_on_expect_found ( cause, span, & exp_found, diag) ;
@@ -1973,7 +2006,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
19732006 trace : & TypeTrace < ' tcx > ,
19742007 terr : TypeError < ' tcx > ,
19752008 ) -> Vec < TypeErrorAdditionalDiags > {
1976- use crate :: traits:: ObligationCauseCode :: MatchExpressionArm ;
2009+ use crate :: traits:: ObligationCauseCode :: { BlockTailExpression , MatchExpressionArm } ;
19772010 let mut suggestions = Vec :: new ( ) ;
19782011 let span = trace. cause . span ( ) ;
19792012 let values = self . resolve_vars_if_possible ( trace. values ) ;
@@ -1991,11 +2024,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
19912024 // specify a byte literal
19922025 ( ty:: Uint ( ty:: UintTy :: U8 ) , ty:: Char ) => {
19932026 if let Ok ( code) = self . tcx . sess ( ) . source_map ( ) . span_to_snippet ( span)
1994- && let Some ( code) = code. strip_prefix ( '\'' ) . and_then ( |s| s. strip_suffix ( '\'' ) )
1995- && !code. starts_with ( "\\ u" ) // forbid all Unicode escapes
1996- && code. chars ( ) . next ( ) . is_some_and ( |c| c. is_ascii ( ) ) // forbids literal Unicode characters beyond ASCII
2027+ && let Some ( code) =
2028+ code. strip_prefix ( '\'' ) . and_then ( |s| s. strip_suffix ( '\'' ) )
2029+ // forbid all Unicode escapes
2030+ && !code. starts_with ( "\\ u" )
2031+ // forbids literal Unicode characters beyond ASCII
2032+ && code. chars ( ) . next ( ) . is_some_and ( |c| c. is_ascii ( ) )
19972033 {
1998- suggestions. push ( TypeErrorAdditionalDiags :: MeantByteLiteral { span, code : escape_literal ( code) } )
2034+ suggestions. push ( TypeErrorAdditionalDiags :: MeantByteLiteral {
2035+ span,
2036+ code : escape_literal ( code) ,
2037+ } )
19992038 }
20002039 }
20012040 // If a character was expected and the found expression is a string literal
@@ -2006,7 +2045,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
20062045 && let Some ( code) = code. strip_prefix ( '"' ) . and_then ( |s| s. strip_suffix ( '"' ) )
20072046 && code. chars ( ) . count ( ) == 1
20082047 {
2009- suggestions. push ( TypeErrorAdditionalDiags :: MeantCharLiteral { span, code : escape_literal ( code) } )
2048+ suggestions. push ( TypeErrorAdditionalDiags :: MeantCharLiteral {
2049+ span,
2050+ code : escape_literal ( code) ,
2051+ } )
20102052 }
20112053 }
20122054 // If a string was expected and the found expression is a character literal,
@@ -2016,7 +2058,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
20162058 if let Some ( code) =
20172059 code. strip_prefix ( '\'' ) . and_then ( |s| s. strip_suffix ( '\'' ) )
20182060 {
2019- suggestions. push ( TypeErrorAdditionalDiags :: MeantStrLiteral { span, code : escape_literal ( code) } )
2061+ suggestions. push ( TypeErrorAdditionalDiags :: MeantStrLiteral {
2062+ span,
2063+ code : escape_literal ( code) ,
2064+ } )
20202065 }
20212066 }
20222067 }
@@ -2025,17 +2070,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
20252070 ( ty:: Bool , ty:: Tuple ( list) ) => if list. len ( ) == 0 {
20262071 suggestions. extend ( self . suggest_let_for_letchains ( & trace. cause , span) ) ;
20272072 }
2028- ( ty:: Array ( _, _) , ty:: Array ( _, _) ) => suggestions. extend ( self . suggest_specify_actual_length ( terr, trace, span) ) ,
2073+ ( ty:: Array ( _, _) , ty:: Array ( _, _) ) => {
2074+ suggestions. extend ( self . suggest_specify_actual_length ( terr, trace, span) )
2075+ }
20292076 _ => { }
20302077 }
20312078 }
20322079 let code = trace. cause . code ( ) ;
2033- if let & MatchExpressionArm ( box MatchExpressionArmCause { source, .. } ) = code
2034- && let hir:: MatchSource :: TryDesugar = source
2035- && let Some ( ( expected_ty, found_ty, _, _) ) = self . values_str ( trace. values )
2036- {
2037- suggestions. push ( TypeErrorAdditionalDiags :: TryCannotConvert { found : found_ty. content ( ) , expected : expected_ty. content ( ) } ) ;
2038- }
2080+ if let & ( MatchExpressionArm ( box MatchExpressionArmCause { source, .. } )
2081+ | BlockTailExpression ( .., source)
2082+ ) = code
2083+ && let hir:: MatchSource :: TryDesugar ( _) = source
2084+ && let Some ( ( expected_ty, found_ty, _, _) ) = self . values_str ( trace. values )
2085+ {
2086+ suggestions. push ( TypeErrorAdditionalDiags :: TryCannotConvert {
2087+ found : found_ty. content ( ) ,
2088+ expected : expected_ty. content ( ) ,
2089+ } ) ;
2090+ }
20392091 suggestions
20402092 }
20412093
@@ -2905,8 +2957,11 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
29052957 CompareImplItemObligation { kind : ty:: AssocKind :: Const , .. } => {
29062958 ObligationCauseFailureCode :: ConstCompat { span, subdiags }
29072959 }
2960+ BlockTailExpression ( .., hir:: MatchSource :: TryDesugar ( _) ) => {
2961+ ObligationCauseFailureCode :: TryCompat { span, subdiags }
2962+ }
29082963 MatchExpressionArm ( box MatchExpressionArmCause { source, .. } ) => match source {
2909- hir:: MatchSource :: TryDesugar => {
2964+ hir:: MatchSource :: TryDesugar ( _ ) => {
29102965 ObligationCauseFailureCode :: TryCompat { span, subdiags }
29112966 }
29122967 _ => ObligationCauseFailureCode :: MatchCompat { span, subdiags } ,
0 commit comments