@@ -743,6 +743,35 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
743
743
ObligationCauseCode :: Pattern { origin_expr : false , span : Some ( span) , .. } => {
744
744
err. span_label ( span, "expected due to this" ) ;
745
745
}
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
+ } ,
746
775
ObligationCauseCode :: MatchExpressionArm ( box MatchExpressionArmCause {
747
776
arm_block_id,
748
777
arm_span,
@@ -752,12 +781,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
752
781
prior_arm_ty,
753
782
source,
754
783
ref prior_arms,
755
- scrut_hir_id,
756
784
opt_suggest_box_span,
757
785
scrut_span,
758
786
..
759
787
} ) => match source {
760
- hir:: MatchSource :: TryDesugar => {
788
+ hir:: MatchSource :: TryDesugar ( scrut_hir_id ) => {
761
789
if let Some ( ty:: error:: ExpectedFound { expected, .. } ) = exp_found {
762
790
let scrut_expr = self . tcx . hir ( ) . expect_expr ( scrut_hir_id) ;
763
791
let scrut_ty = if let hir:: ExprKind :: Call ( _, args) = & scrut_expr. kind {
@@ -1927,7 +1955,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1927
1955
true
1928
1956
} ;
1929
1957
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
+ {
1931
1964
self . suggest_tuple_pattern ( cause, & exp_found, diag) ;
1932
1965
self . suggest_accessing_field_where_appropriate ( cause, & exp_found, diag) ;
1933
1966
self . suggest_await_on_expect_found ( cause, span, & exp_found, diag) ;
@@ -1973,7 +2006,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1973
2006
trace : & TypeTrace < ' tcx > ,
1974
2007
terr : TypeError < ' tcx > ,
1975
2008
) -> Vec < TypeErrorAdditionalDiags > {
1976
- use crate :: traits:: ObligationCauseCode :: MatchExpressionArm ;
2009
+ use crate :: traits:: ObligationCauseCode :: { BlockTailExpression , MatchExpressionArm } ;
1977
2010
let mut suggestions = Vec :: new ( ) ;
1978
2011
let span = trace. cause . span ( ) ;
1979
2012
let values = self . resolve_vars_if_possible ( trace. values ) ;
@@ -1991,11 +2024,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1991
2024
// specify a byte literal
1992
2025
( ty:: Uint ( ty:: UintTy :: U8 ) , ty:: Char ) => {
1993
2026
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 ( ) )
1997
2033
{
1998
- suggestions. push ( TypeErrorAdditionalDiags :: MeantByteLiteral { span, code : escape_literal ( code) } )
2034
+ suggestions. push ( TypeErrorAdditionalDiags :: MeantByteLiteral {
2035
+ span,
2036
+ code : escape_literal ( code) ,
2037
+ } )
1999
2038
}
2000
2039
}
2001
2040
// If a character was expected and the found expression is a string literal
@@ -2006,7 +2045,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
2006
2045
&& let Some ( code) = code. strip_prefix ( '"' ) . and_then ( |s| s. strip_suffix ( '"' ) )
2007
2046
&& code. chars ( ) . count ( ) == 1
2008
2047
{
2009
- suggestions. push ( TypeErrorAdditionalDiags :: MeantCharLiteral { span, code : escape_literal ( code) } )
2048
+ suggestions. push ( TypeErrorAdditionalDiags :: MeantCharLiteral {
2049
+ span,
2050
+ code : escape_literal ( code) ,
2051
+ } )
2010
2052
}
2011
2053
}
2012
2054
// If a string was expected and the found expression is a character literal,
@@ -2016,7 +2058,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
2016
2058
if let Some ( code) =
2017
2059
code. strip_prefix ( '\'' ) . and_then ( |s| s. strip_suffix ( '\'' ) )
2018
2060
{
2019
- suggestions. push ( TypeErrorAdditionalDiags :: MeantStrLiteral { span, code : escape_literal ( code) } )
2061
+ suggestions. push ( TypeErrorAdditionalDiags :: MeantStrLiteral {
2062
+ span,
2063
+ code : escape_literal ( code) ,
2064
+ } )
2020
2065
}
2021
2066
}
2022
2067
}
@@ -2025,17 +2070,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
2025
2070
( ty:: Bool , ty:: Tuple ( list) ) => if list. len ( ) == 0 {
2026
2071
suggestions. extend ( self . suggest_let_for_letchains ( & trace. cause , span) ) ;
2027
2072
}
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
+ }
2029
2076
_ => { }
2030
2077
}
2031
2078
}
2032
2079
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
+ }
2039
2091
suggestions
2040
2092
}
2041
2093
@@ -2905,8 +2957,11 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
2905
2957
CompareImplItemObligation { kind : ty:: AssocKind :: Const , .. } => {
2906
2958
ObligationCauseFailureCode :: ConstCompat { span, subdiags }
2907
2959
}
2960
+ BlockTailExpression ( .., hir:: MatchSource :: TryDesugar ( _) ) => {
2961
+ ObligationCauseFailureCode :: TryCompat { span, subdiags }
2962
+ }
2908
2963
MatchExpressionArm ( box MatchExpressionArmCause { source, .. } ) => match source {
2909
- hir:: MatchSource :: TryDesugar => {
2964
+ hir:: MatchSource :: TryDesugar ( _ ) => {
2910
2965
ObligationCauseFailureCode :: TryCompat { span, subdiags }
2911
2966
}
2912
2967
_ => ObligationCauseFailureCode :: MatchCompat { span, subdiags } ,
0 commit comments