@@ -882,6 +882,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
882
882
obligation. cause . code ( )
883
883
{
884
884
& parent_code
885
+ } else if let ObligationCauseCode :: ItemObligation ( _) = obligation. cause . code ( ) {
886
+ obligation. cause . code ( )
885
887
} else if let ExpnKind :: Desugaring ( DesugaringKind :: ForLoop ) =
886
888
span. ctxt ( ) . outer_expn_data ( ) . kind
887
889
{
@@ -930,10 +932,25 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
930
932
self . mk_trait_obligation_with_new_self_ty ( param_env, trait_pred_and_new_ty) ;
931
933
self . predicate_must_hold_modulo_regions ( & obligation)
932
934
} ;
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
+ } ;
935
949
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
+ {
937
954
if let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span) {
938
955
// We have a very specific type of error, where just borrowing this argument
939
956
// 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> {
973
990
// }
974
991
// ```
975
992
976
- if imm_result && mut_result {
993
+ if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred {
977
994
err. span_suggestions (
978
995
span. shrink_to_lo ( ) ,
979
996
"consider borrowing here" ,
980
997
[ "&" . to_string ( ) , "&mut " . to_string ( ) ] . into_iter ( ) ,
981
998
Applicability :: MaybeIncorrect ,
982
999
) ;
983
1000
} else {
1001
+ let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
984
1002
err. span_suggestion_verbose (
985
1003
span. shrink_to_lo ( ) ,
986
1004
& format ! (
987
1005
"consider{} borrowing here" ,
988
- if mut_result { " mutably" } else { "" }
1006
+ if is_mut { " mutably" } else { "" }
989
1007
) ,
990
- format ! ( "&{}" , if mut_result { "mut " } else { "" } ) ,
1008
+ format ! ( "&{}" , if is_mut { "mut " } else { "" } ) ,
991
1009
Applicability :: MaybeIncorrect ,
992
1010
) ;
993
1011
}
@@ -1001,7 +1019,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
1001
1019
if let ObligationCauseCode :: ImplDerivedObligation ( cause) = & * code {
1002
1020
try_borrowing ( cause. derived . parent_trait_pred , & [ ] )
1003
1021
} else if let ObligationCauseCode :: BindingObligation ( _, _)
1004
- | ObligationCauseCode :: ItemObligation ( _ ) = code
1022
+ | ObligationCauseCode :: ItemObligation ( .. ) = code
1005
1023
{
1006
1024
try_borrowing ( poly_trait_pred, & never_suggest_borrow)
1007
1025
} else {
0 commit comments