@@ -973,6 +973,23 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
973973 || ref_inner_ty_satisfies_pred
974974 {
975975 if let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span) {
976+ // We don't want a borrowing suggestion on the fields in structs,
977+ // ```
978+ // struct Foo {
979+ // the_foos: Vec<Foo>
980+ // }
981+ // ```
982+ if !matches ! (
983+ span. ctxt( ) . outer_expn_data( ) . kind,
984+ ExpnKind :: Root | ExpnKind :: Desugaring ( DesugaringKind :: ForLoop )
985+ ) {
986+ return false ;
987+ }
988+ if snippet. starts_with ( '&' ) {
989+ // This is already a literal borrow and the obligation is failing
990+ // somewhere else in the obligation chain. Do not suggest non-sense.
991+ return false ;
992+ }
976993 // We have a very specific type of error, where just borrowing this argument
977994 // might solve the problem. In cases like this, the important part is the
978995 // original type obligation, not the last one that failed, which is arbitrary.
@@ -986,50 +1003,33 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
9861003 err. message =
9871004 vec ! [ ( rustc_errors:: DiagnosticMessage :: Str ( msg) , Style :: NoStyle ) ] ;
9881005 }
989- if snippet. starts_with ( '&' ) {
990- // This is already a literal borrow and the obligation is failing
991- // somewhere else in the obligation chain. Do not suggest non-sense.
992- return false ;
993- }
9941006 err. span_label (
9951007 span,
996- & format ! (
997- "expected an implementor of trait `{}`" ,
1008+ format ! (
1009+ "the trait `{}` is not implemented for `{}`" ,
9981010 old_pred. print_modifiers_and_trait_path( ) ,
1011+ old_pred. self_ty( ) . skip_binder( ) ,
9991012 ) ,
10001013 ) ;
10011014
1002- // This if is to prevent a special edge-case
1003- if matches ! (
1004- span. ctxt( ) . outer_expn_data( ) . kind,
1005- ExpnKind :: Root | ExpnKind :: Desugaring ( DesugaringKind :: ForLoop )
1006- ) {
1007- // We don't want a borrowing suggestion on the fields in structs,
1008- // ```
1009- // struct Foo {
1010- // the_foos: Vec<Foo>
1011- // }
1012- // ```
1013-
1014- if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred {
1015- err. span_suggestions (
1016- span. shrink_to_lo ( ) ,
1017- "consider borrowing here" ,
1018- [ "&" . to_string ( ) , "&mut " . to_string ( ) ] . into_iter ( ) ,
1019- Applicability :: MaybeIncorrect ,
1020- ) ;
1021- } else {
1022- let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
1023- err. span_suggestion_verbose (
1024- span. shrink_to_lo ( ) ,
1025- & format ! (
1026- "consider{} borrowing here" ,
1027- if is_mut { " mutably" } else { "" }
1028- ) ,
1029- format ! ( "&{}" , if is_mut { "mut " } else { "" } ) ,
1030- Applicability :: MaybeIncorrect ,
1031- ) ;
1032- }
1015+ if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred {
1016+ err. span_suggestions (
1017+ span. shrink_to_lo ( ) ,
1018+ "consider borrowing here" ,
1019+ [ "&" . to_string ( ) , "&mut " . to_string ( ) ] . into_iter ( ) ,
1020+ Applicability :: MaybeIncorrect ,
1021+ ) ;
1022+ } else {
1023+ let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
1024+ err. span_suggestion_verbose (
1025+ span. shrink_to_lo ( ) ,
1026+ & format ! (
1027+ "consider{} borrowing here" ,
1028+ if is_mut { " mutably" } else { "" }
1029+ ) ,
1030+ format ! ( "&{}" , if is_mut { "mut " } else { "" } ) ,
1031+ Applicability :: MaybeIncorrect ,
1032+ ) ;
10331033 }
10341034 return true ;
10351035 }
0 commit comments