@@ -112,7 +112,7 @@ pub trait TypeErrCtxtExt<'tcx> {
112
112
obligation : & PredicateObligation < ' tcx > ,
113
113
trait_ref : ty:: TraitRef < ' tcx > ,
114
114
err : & mut Diagnostic ,
115
- ) ;
115
+ ) -> bool ;
116
116
117
117
fn report_const_param_not_wf (
118
118
& self ,
@@ -517,8 +517,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
517
517
518
518
let mut err = struct_span_err ! ( self . tcx. sess, span, E0277 , "{}" , err_msg) ;
519
519
520
+ let mut suggested = false ;
520
521
if is_try_conversion {
521
- self . try_conversion_context ( & obligation, trait_ref. skip_binder ( ) , & mut err) ;
522
+ suggested = self . try_conversion_context ( & obligation, trait_ref. skip_binder ( ) , & mut err) ;
522
523
}
523
524
524
525
if is_try_conversion && let Some ( ret_span) = self . return_type_span ( & obligation) {
@@ -621,8 +622,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
621
622
622
623
self . suggest_floating_point_literal ( & obligation, & mut err, & trait_ref) ;
623
624
self . suggest_dereferencing_index ( & obligation, & mut err, trait_predicate) ;
624
- let mut suggested =
625
- self . suggest_dereferences ( & obligation, & mut err, trait_predicate) ;
625
+ suggested |= self . suggest_dereferences ( & obligation, & mut err, trait_predicate) ;
626
626
suggested |= self . suggest_fn_call ( & obligation, & mut err, trait_predicate) ;
627
627
let impl_candidates = self . find_similar_impl_candidates ( trait_predicate) ;
628
628
suggested = if let & [ cand] = & impl_candidates[ ..] {
@@ -1002,7 +1002,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1002
1002
obligation : & PredicateObligation < ' tcx > ,
1003
1003
trait_ref : ty:: TraitRef < ' tcx > ,
1004
1004
err : & mut Diagnostic ,
1005
- ) {
1005
+ ) -> bool {
1006
1006
let span = obligation. cause . span ;
1007
1007
struct V < ' v > {
1008
1008
search_span : Span ,
@@ -1027,22 +1027,22 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1027
1027
Some ( hir:: Node :: Item ( hir:: Item { kind : hir:: ItemKind :: Fn ( _, _, body_id) , .. } ) ) => {
1028
1028
body_id
1029
1029
}
1030
- _ => return ,
1030
+ _ => return false ,
1031
1031
} ;
1032
1032
let mut v = V { search_span : span, found : None } ;
1033
1033
v. visit_body ( self . tcx . hir ( ) . body ( * body_id) ) ;
1034
1034
let Some ( expr) = v. found else {
1035
- return ;
1035
+ return false ;
1036
1036
} ;
1037
1037
let Some ( typeck) = & self . typeck_results else {
1038
- return ;
1038
+ return false ;
1039
1039
} ;
1040
1040
let Some ( ( ObligationCauseCode :: QuestionMark , Some ( y) ) ) = obligation. cause . code ( ) . parent ( )
1041
1041
else {
1042
- return ;
1042
+ return false ;
1043
1043
} ;
1044
1044
if !self . tcx . is_diagnostic_item ( sym:: FromResidual , y. def_id ( ) ) {
1045
- return ;
1045
+ return false ;
1046
1046
}
1047
1047
let self_ty = trait_ref. self_ty ( ) ;
1048
1048
let found_ty = trait_ref. args . get ( 1 ) . and_then ( |a| a. as_type ( ) ) ;
@@ -1067,6 +1067,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1067
1067
Some ( arg. as_type ( ) ?)
1068
1068
} ;
1069
1069
1070
+ let mut suggested = false ;
1070
1071
let mut chain = vec ! [ ] ;
1071
1072
1072
1073
// The following logic is simlar to `point_at_chain`, but that's focused on associated types
@@ -1135,6 +1136,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1135
1136
)
1136
1137
. must_apply_modulo_regions ( )
1137
1138
{
1139
+ suggested = true ;
1138
1140
err. span_suggestion_short (
1139
1141
stmt. span . with_lo ( expr. span . hi ( ) ) ,
1140
1142
"remove this semicolon" ,
@@ -1193,17 +1195,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1193
1195
)
1194
1196
. must_apply_modulo_regions ( )
1195
1197
{
1196
- err. span_label ( span, format ! ( "this has type `Result<_, {err_ty}>`" ) ) ;
1198
+ if !suggested {
1199
+ err. span_label ( span, format ! ( "this has type `Result<_, {err_ty}>`" ) ) ;
1200
+ }
1197
1201
} else {
1198
1202
err. span_label (
1199
- span,
1200
- format ! (
1201
- "this can't be annotated with `?` because it has type `Result<_, {err_ty}>`" ,
1202
- ) ,
1203
- ) ;
1203
+ span,
1204
+ format ! (
1205
+ "this can't be annotated with `?` because it has type `Result<_, {err_ty}>`" ,
1206
+ ) ,
1207
+ ) ;
1204
1208
}
1205
1209
prev = Some ( err_ty) ;
1206
1210
}
1211
+ suggested
1207
1212
}
1208
1213
1209
1214
fn report_const_param_not_wf (
0 commit comments