@@ -106,7 +106,7 @@ pub trait TypeErrCtxtExt<'tcx> {
106
106
obligation : & PredicateObligation < ' tcx > ,
107
107
trait_ref : ty:: TraitRef < ' tcx > ,
108
108
err : & mut Diagnostic ,
109
- ) ;
109
+ ) -> bool ;
110
110
111
111
fn report_const_param_not_wf (
112
112
& self ,
@@ -503,8 +503,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
503
503
504
504
let mut err = struct_span_err ! ( self . tcx. sess, span, E0277 , "{}" , err_msg) ;
505
505
506
+ let mut suggested = false ;
506
507
if is_try_conversion {
507
- self . try_conversion_context ( & obligation, trait_ref. skip_binder ( ) , & mut err) ;
508
+ suggested = self . try_conversion_context ( & obligation, trait_ref. skip_binder ( ) , & mut err) ;
508
509
}
509
510
510
511
if is_try_conversion && let Some ( ret_span) = self . return_type_span ( & obligation) {
@@ -605,8 +606,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
605
606
606
607
self . suggest_floating_point_literal ( & obligation, & mut err, & trait_ref) ;
607
608
self . suggest_dereferencing_index ( & obligation, & mut err, trait_predicate) ;
608
- let mut suggested =
609
- self . suggest_dereferences ( & obligation, & mut err, trait_predicate) ;
609
+ suggested |= self . suggest_dereferences ( & obligation, & mut err, trait_predicate) ;
610
610
suggested |= self . suggest_fn_call ( & obligation, & mut err, trait_predicate) ;
611
611
let impl_candidates = self . find_similar_impl_candidates ( trait_predicate) ;
612
612
suggested = if let & [ cand] = & impl_candidates[ ..] {
@@ -961,7 +961,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
961
961
obligation : & PredicateObligation < ' tcx > ,
962
962
trait_ref : ty:: TraitRef < ' tcx > ,
963
963
err : & mut Diagnostic ,
964
- ) {
964
+ ) -> bool {
965
965
let span = obligation. cause . span ;
966
966
struct V < ' v > {
967
967
search_span : Span ,
@@ -986,22 +986,22 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
986
986
Some ( hir:: Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Fn ( _, _, body_id) , .. } ) ) => {
987
987
body_id
988
988
}
989
- _ => return ,
989
+ _ => return false ,
990
990
} ;
991
991
let mut v = V { search_span : span, found : None } ;
992
992
v. visit_body ( self . tcx . hir ( ) . body ( * body_id) ) ;
993
993
let Some ( expr) = v. found else {
994
- return ;
994
+ return false ;
995
995
} ;
996
996
let Some ( typeck) = & self . typeck_results else {
997
- return ;
997
+ return false ;
998
998
} ;
999
999
let Some ( ( ObligationCauseCode :: QuestionMark , Some ( y) ) ) = obligation. cause . code ( ) . parent ( )
1000
1000
else {
1001
- return ;
1001
+ return false ;
1002
1002
} ;
1003
1003
if !self . tcx . is_diagnostic_item ( sym:: FromResidual , y. def_id ( ) ) {
1004
- return ;
1004
+ return false ;
1005
1005
}
1006
1006
let self_ty = trait_ref. self_ty ( ) ;
1007
1007
let found_ty = trait_ref. args . get ( 1 ) . and_then ( |a| a. as_type ( ) ) ;
@@ -1026,6 +1026,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1026
1026
Some ( arg. as_type ( ) ?)
1027
1027
} ;
1028
1028
1029
+ let mut suggested = false ;
1029
1030
let mut chain = vec ! [ ] ;
1030
1031
1031
1032
// The following logic is simlar to `point_at_chain`, but that's focused on associated types
@@ -1090,6 +1091,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1090
1091
)
1091
1092
. must_apply_modulo_regions ( )
1092
1093
{
1094
+ suggested = true ;
1093
1095
err. span_suggestion_short (
1094
1096
stmt. span . with_lo ( expr. span . hi ( ) ) ,
1095
1097
"remove this semicolon" ,
@@ -1146,17 +1148,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1146
1148
)
1147
1149
. must_apply_modulo_regions ( )
1148
1150
{
1149
- err. span_label ( span, format ! ( "this has type `Result<_, {err_ty}>`" ) ) ;
1151
+ if !suggested {
1152
+ err. span_label ( span, format ! ( "this has type `Result<_, {err_ty}>`" ) ) ;
1153
+ }
1150
1154
} else {
1151
1155
err. span_label (
1152
- span,
1153
- format ! (
1154
- "this can't be annotated with `?` because it has type `Result<_, {err_ty}>`" ,
1155
- ) ,
1156
- ) ;
1156
+ span,
1157
+ format ! (
1158
+ "this can't be annotated with `?` because it has type `Result<_, {err_ty}>`" ,
1159
+ ) ,
1160
+ ) ;
1157
1161
}
1158
1162
prev = Some ( err_ty) ;
1159
1163
}
1164
+ suggested
1160
1165
}
1161
1166
1162
1167
fn report_const_param_not_wf (
0 commit comments