@@ -903,7 +903,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
903903 obligation. cause . code ( )
904904 {
905905 & parent_code
906- } else if let ObligationCauseCode :: ItemObligation ( _) = obligation. cause . code ( ) {
906+ } else if let ObligationCauseCode :: ItemObligation ( _)
907+ | ObligationCauseCode :: ExprItemObligation ( ..) = obligation. cause . code ( )
908+ {
907909 obligation. cause . code ( )
908910 } else if let ExpnKind :: Desugaring ( DesugaringKind :: ForLoop ) =
909911 span. ctxt ( ) . outer_expn_data ( ) . kind
@@ -929,35 +931,36 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
929931 let param_env = obligation. param_env ;
930932
931933 // 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+ } ) ;
950953
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) ;
958961
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 ( )
961964 && let ty:: Ref ( _, ty, mutability) = old_pred. self_ty ( ) . skip_binder ( ) . kind ( )
962965 {
963966 (
@@ -968,74 +971,74 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
968971 ( false , false )
969972 } ;
970973
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 { "" }
10121032 ) ,
1033+ format ! ( "&{}" , if is_mut { "mut " } else { "" } ) ,
1034+ Applicability :: MaybeIncorrect ,
10131035 ) ;
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 ;
10351036 }
1037+ return true ;
10361038 }
1037- return false ;
1038- } ;
1039+ }
1040+ return false ;
1041+ } ;
10391042
10401043 if let ObligationCauseCode :: ImplDerivedObligation ( cause) = & * code {
10411044 try_borrowing ( cause. derived . parent_trait_pred , & [ ] )
0 commit comments