@@ -882,6 +882,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
882882 obligation. cause . code ( )
883883 {
884884 & parent_code
885+ } else if let ObligationCauseCode :: ItemObligation ( _) = obligation. cause . code ( ) {
886+ obligation. cause . code ( )
885887 } else if let ExpnKind :: Desugaring ( DesugaringKind :: ForLoop ) =
886888 span. ctxt ( ) . outer_expn_data ( ) . kind
887889 {
@@ -930,10 +932,25 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
930932 self . mk_trait_obligation_with_new_self_ty ( param_env, trait_pred_and_new_ty) ;
931933 self . predicate_must_hold_modulo_regions ( & obligation)
932934 } ;
933- let imm_result = mk_result ( trait_pred_and_imm_ref) ;
934- let mut_result = mk_result ( trait_pred_and_mut_ref) ;
935+ let imm_ref_self_ty_satisfies_pred = mk_result ( trait_pred_and_imm_ref) ;
936+ let mut_ref_self_ty_satisfies_pred = mk_result ( trait_pred_and_mut_ref) ;
937+
938+ let ( ref_inner_ty_satisfies_pred, ref_inner_ty_mut) =
939+ if let ObligationCauseCode :: ItemObligation ( _) = obligation. cause . code ( )
940+ && let ty:: Ref ( _, ty, mutability) = old_pred. self_ty ( ) . skip_binder ( ) . kind ( )
941+ {
942+ (
943+ mk_result ( old_pred. map_bound ( |trait_pred| ( trait_pred, * ty) ) ) ,
944+ matches ! ( mutability, hir:: Mutability :: Mut ) ,
945+ )
946+ } else {
947+ ( false , false )
948+ } ;
935949
936- if imm_result || mut_result {
950+ if imm_ref_self_ty_satisfies_pred
951+ || mut_ref_self_ty_satisfies_pred
952+ || ref_inner_ty_satisfies_pred
953+ {
937954 if let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span) {
938955 // We have a very specific type of error, where just borrowing this argument
939956 // might solve the problem. In cases like this, the important part is the
@@ -973,21 +990,22 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
973990 // }
974991 // ```
975992
976- if imm_result && mut_result {
993+ if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred {
977994 err. span_suggestions (
978995 span. shrink_to_lo ( ) ,
979996 "consider borrowing here" ,
980997 [ "&" . to_string ( ) , "&mut " . to_string ( ) ] . into_iter ( ) ,
981998 Applicability :: MaybeIncorrect ,
982999 ) ;
9831000 } else {
1001+ let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
9841002 err. span_suggestion_verbose (
9851003 span. shrink_to_lo ( ) ,
9861004 & format ! (
9871005 "consider{} borrowing here" ,
988- if mut_result { " mutably" } else { "" }
1006+ if is_mut { " mutably" } else { "" }
9891007 ) ,
990- format ! ( "&{}" , if mut_result { "mut " } else { "" } ) ,
1008+ format ! ( "&{}" , if is_mut { "mut " } else { "" } ) ,
9911009 Applicability :: MaybeIncorrect ,
9921010 ) ;
9931011 }
@@ -1001,7 +1019,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
10011019 if let ObligationCauseCode :: ImplDerivedObligation ( cause) = & * code {
10021020 try_borrowing ( cause. derived . parent_trait_pred , & [ ] )
10031021 } else if let ObligationCauseCode :: BindingObligation ( _, _)
1004- | ObligationCauseCode :: ItemObligation ( _ ) = code
1022+ | ObligationCauseCode :: ItemObligation ( .. ) = code
10051023 {
10061024 try_borrowing ( poly_trait_pred, & never_suggest_borrow)
10071025 } else {
0 commit comments