@@ -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
@@ -1131,6 +1132,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1131
1132
)
1132
1133
. must_apply_modulo_regions ( )
1133
1134
{
1135
+ suggested = true ;
1134
1136
err. span_suggestion_short (
1135
1137
stmt. span . with_lo ( expr. span . hi ( ) ) ,
1136
1138
"remove this semicolon" ,
@@ -1189,17 +1191,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1189
1191
)
1190
1192
. must_apply_modulo_regions ( )
1191
1193
{
1192
- err. span_label ( span, format ! ( "this has type `Result<_, {err_ty}>`" ) ) ;
1194
+ if !suggested {
1195
+ err. span_label ( span, format ! ( "this has type `Result<_, {err_ty}>`" ) ) ;
1196
+ }
1193
1197
} else {
1194
1198
err. span_label (
1195
- span,
1196
- format ! (
1197
- "this can't be annotated with `?` because it has type `Result<_, {err_ty}>`" ,
1198
- ) ,
1199
- ) ;
1199
+ span,
1200
+ format ! (
1201
+ "this can't be annotated with `?` because it has type `Result<_, {err_ty}>`" ,
1202
+ ) ,
1203
+ ) ;
1200
1204
}
1201
1205
prev = Some ( err_ty) ;
1202
1206
}
1207
+ suggested
1203
1208
}
1204
1209
1205
1210
fn report_const_param_not_wf (
0 commit comments