@@ -903,7 +903,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
903
903
obligation. cause . code ( )
904
904
{
905
905
& parent_code
906
- } else if let ObligationCauseCode :: ItemObligation ( _) = obligation. cause . code ( ) {
906
+ } else if let ObligationCauseCode :: ItemObligation ( _)
907
+ | ObligationCauseCode :: ExprItemObligation ( ..) = obligation. cause . code ( )
908
+ {
907
909
obligation. cause . code ( )
908
910
} else if let ExpnKind :: Desugaring ( DesugaringKind :: ForLoop ) =
909
911
span. ctxt ( ) . outer_expn_data ( ) . kind
@@ -929,35 +931,36 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
929
931
let param_env = obligation. param_env ;
930
932
931
933
// Try to apply the original trait binding obligation by borrowing.
932
- let mut try_borrowing =
933
- |old_pred : ty:: PolyTraitPredicate < ' tcx > , blacklist : & [ DefId ] | -> bool {
934
- if blacklist. contains ( & old_pred. def_id ( ) ) {
935
- return false ;
936
- }
937
- // We map bounds to `&T` and `&mut T`
938
- let trait_pred_and_imm_ref = old_pred. map_bound ( |trait_pred| {
939
- (
940
- trait_pred,
941
- self . tcx . mk_imm_ref ( self . tcx . lifetimes . re_static , trait_pred. self_ty ( ) ) ,
942
- )
943
- } ) ;
944
- let trait_pred_and_mut_ref = old_pred. map_bound ( |trait_pred| {
945
- (
946
- trait_pred,
947
- self . tcx . mk_mut_ref ( self . tcx . lifetimes . re_static , trait_pred. self_ty ( ) ) ,
948
- )
949
- } ) ;
934
+ let mut try_borrowing = |old_pred : ty:: PolyTraitPredicate < ' tcx > ,
935
+ blacklist : & [ DefId ] |
936
+ -> bool {
937
+ if blacklist. contains ( & old_pred. def_id ( ) ) {
938
+ return false ;
939
+ }
940
+ // We map bounds to `&T` and `&mut T`
941
+ let trait_pred_and_imm_ref = old_pred. map_bound ( |trait_pred| {
942
+ (
943
+ trait_pred,
944
+ self . tcx . mk_imm_ref ( self . tcx . lifetimes . re_static , trait_pred. self_ty ( ) ) ,
945
+ )
946
+ } ) ;
947
+ let trait_pred_and_mut_ref = old_pred. map_bound ( |trait_pred| {
948
+ (
949
+ trait_pred,
950
+ self . tcx . mk_mut_ref ( self . tcx . lifetimes . re_static , trait_pred. self_ty ( ) ) ,
951
+ )
952
+ } ) ;
950
953
951
- let mk_result = |trait_pred_and_new_ty| {
952
- let obligation =
953
- self . mk_trait_obligation_with_new_self_ty ( param_env, trait_pred_and_new_ty) ;
954
- self . predicate_must_hold_modulo_regions ( & obligation)
955
- } ;
956
- let imm_ref_self_ty_satisfies_pred = mk_result ( trait_pred_and_imm_ref) ;
957
- let mut_ref_self_ty_satisfies_pred = mk_result ( trait_pred_and_mut_ref) ;
954
+ let mk_result = |trait_pred_and_new_ty| {
955
+ let obligation =
956
+ self . mk_trait_obligation_with_new_self_ty ( param_env, trait_pred_and_new_ty) ;
957
+ self . predicate_must_hold_modulo_regions ( & obligation)
958
+ } ;
959
+ let imm_ref_self_ty_satisfies_pred = mk_result ( trait_pred_and_imm_ref) ;
960
+ let mut_ref_self_ty_satisfies_pred = mk_result ( trait_pred_and_mut_ref) ;
958
961
959
- let ( ref_inner_ty_satisfies_pred, ref_inner_ty_mut) =
960
- if let ObligationCauseCode :: ItemObligation ( _) = obligation. cause . code ( )
962
+ let ( ref_inner_ty_satisfies_pred, ref_inner_ty_mut) =
963
+ if let ObligationCauseCode :: ItemObligation ( _) | ObligationCauseCode :: ExprItemObligation ( .. ) = obligation. cause . code ( )
961
964
&& let ty:: Ref ( _, ty, mutability) = old_pred. self_ty ( ) . skip_binder ( ) . kind ( )
962
965
{
963
966
(
@@ -968,74 +971,74 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
968
971
( false , false )
969
972
} ;
970
973
971
- if imm_ref_self_ty_satisfies_pred
972
- || mut_ref_self_ty_satisfies_pred
973
- || ref_inner_ty_satisfies_pred
974
- {
975
- 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
- }
993
- // We have a very specific type of error, where just borrowing this argument
994
- // might solve the problem. In cases like this, the important part is the
995
- // original type obligation, not the last one that failed, which is arbitrary.
996
- // Because of this, we modify the error to refer to the original obligation and
997
- // return early in the caller.
998
-
999
- let msg = format ! ( "the trait bound `{}` is not satisfied" , old_pred) ;
1000
- if has_custom_message {
1001
- err. note ( & msg) ;
1002
- } else {
1003
- err. message =
1004
- vec ! [ ( rustc_errors:: DiagnosticMessage :: Str ( msg) , Style :: NoStyle ) ] ;
1005
- }
1006
- err. span_label (
1007
- span,
1008
- format ! (
1009
- "the trait `{}` is not implemented for `{}`" ,
1010
- old_pred. print_modifiers_and_trait_path( ) ,
1011
- old_pred. self_ty( ) . skip_binder( ) ,
974
+ if imm_ref_self_ty_satisfies_pred
975
+ || mut_ref_self_ty_satisfies_pred
976
+ || ref_inner_ty_satisfies_pred
977
+ {
978
+ if let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span) {
979
+ // We don't want a borrowing suggestion on the fields in structs,
980
+ // ```
981
+ // struct Foo {
982
+ // the_foos: Vec<Foo>
983
+ // }
984
+ // ```
985
+ if !matches ! (
986
+ span. ctxt( ) . outer_expn_data( ) . kind,
987
+ ExpnKind :: Root | ExpnKind :: Desugaring ( DesugaringKind :: ForLoop )
988
+ ) {
989
+ return false ;
990
+ }
991
+ if snippet. starts_with ( '&' ) {
992
+ // This is already a literal borrow and the obligation is failing
993
+ // somewhere else in the obligation chain. Do not suggest non-sense.
994
+ return false ;
995
+ }
996
+ // We have a very specific type of error, where just borrowing this argument
997
+ // might solve the problem. In cases like this, the important part is the
998
+ // original type obligation, not the last one that failed, which is arbitrary.
999
+ // Because of this, we modify the error to refer to the original obligation and
1000
+ // return early in the caller.
1001
+
1002
+ let msg = format ! ( "the trait bound `{}` is not satisfied" , old_pred) ;
1003
+ if has_custom_message {
1004
+ err. note ( & msg) ;
1005
+ } else {
1006
+ err. message =
1007
+ vec ! [ ( rustc_errors:: DiagnosticMessage :: Str ( msg) , Style :: NoStyle ) ] ;
1008
+ }
1009
+ err. span_label (
1010
+ span,
1011
+ format ! (
1012
+ "the trait `{}` is not implemented for `{}`" ,
1013
+ old_pred. print_modifiers_and_trait_path( ) ,
1014
+ old_pred. self_ty( ) . skip_binder( ) ,
1015
+ ) ,
1016
+ ) ;
1017
+
1018
+ if imm_ref_self_ty_satisfies_pred && mut_ref_self_ty_satisfies_pred {
1019
+ err. span_suggestions (
1020
+ span. shrink_to_lo ( ) ,
1021
+ "consider borrowing here" ,
1022
+ [ "&" . to_string ( ) , "&mut " . to_string ( ) ] . into_iter ( ) ,
1023
+ Applicability :: MaybeIncorrect ,
1024
+ ) ;
1025
+ } else {
1026
+ let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
1027
+ err. span_suggestion_verbose (
1028
+ span. shrink_to_lo ( ) ,
1029
+ & format ! (
1030
+ "consider{} borrowing here" ,
1031
+ if is_mut { " mutably" } else { "" }
1012
1032
) ,
1033
+ format ! ( "&{}" , if is_mut { "mut " } else { "" } ) ,
1034
+ Applicability :: MaybeIncorrect ,
1013
1035
) ;
1014
-
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
- ) ;
1033
- }
1034
- return true ;
1035
1036
}
1037
+ return true ;
1036
1038
}
1037
- return false ;
1038
- } ;
1039
+ }
1040
+ return false ;
1041
+ } ;
1039
1042
1040
1043
if let ObligationCauseCode :: ImplDerivedObligation ( cause) = & * code {
1041
1044
try_borrowing ( cause. derived . parent_trait_pred , & [ ] )
0 commit comments