@@ -714,22 +714,28 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
714
714
let mut_substs = self . tcx . mk_substs_trait ( mut_borrowed_found_ty, & [ ] ) ;
715
715
716
716
// Try to apply the original trait binding obligation by borrowing.
717
- let mut try_borrowing = |new_trait_ref : ty:: TraitRef < ' tcx > ,
717
+ let mut try_borrowing = |new_imm_trait_ref : ty:: TraitRef < ' tcx > ,
718
+ new_mut_trait_ref : ty:: TraitRef < ' tcx > ,
718
719
expected_trait_ref : ty:: TraitRef < ' tcx > ,
719
- mtbl : bool ,
720
720
blacklist : & [ DefId ] |
721
721
-> bool {
722
722
if blacklist. contains ( & expected_trait_ref. def_id ) {
723
723
return false ;
724
724
}
725
725
726
- let new_obligation = Obligation :: new (
726
+ let imm_result = self . predicate_must_hold_modulo_regions ( & Obligation :: new (
727
727
ObligationCause :: dummy ( ) ,
728
728
param_env,
729
- ty:: Binder :: dummy ( new_trait_ref ) . without_const ( ) . to_predicate ( self . tcx ) ,
730
- ) ;
729
+ ty:: Binder :: dummy ( new_imm_trait_ref ) . without_const ( ) . to_predicate ( self . tcx ) ,
730
+ ) ) ;
731
731
732
- if self . predicate_must_hold_modulo_regions ( & new_obligation) {
732
+ let mut_result = self . predicate_must_hold_modulo_regions ( & Obligation :: new (
733
+ ObligationCause :: dummy ( ) ,
734
+ param_env,
735
+ ty:: Binder :: dummy ( new_mut_trait_ref) . without_const ( ) . to_predicate ( self . tcx ) ,
736
+ ) ) ;
737
+
738
+ if imm_result || mut_result {
733
739
if let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span) {
734
740
// We have a very specific type of error, where just borrowing this argument
735
741
// might solve the problem. In cases like this, the important part is the
@@ -773,15 +779,24 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
773
779
// }
774
780
// ```
775
781
776
- err. span_suggestion (
777
- span,
778
- & format ! (
779
- "consider{} borrowing here" ,
780
- if mtbl { " mutably" } else { "" }
781
- ) ,
782
- format ! ( "&{}{}" , if mtbl { "mut " } else { "" } , snippet) ,
783
- Applicability :: MaybeIncorrect ,
784
- ) ;
782
+ if imm_result && mut_result {
783
+ err. span_suggestions (
784
+ span. shrink_to_lo ( ) ,
785
+ "consider borrowing here" ,
786
+ [ "&" . to_string ( ) , "&mut " . to_string ( ) ] . into_iter ( ) ,
787
+ Applicability :: MaybeIncorrect ,
788
+ ) ;
789
+ } else {
790
+ err. span_suggestion_verbose (
791
+ span. shrink_to_lo ( ) ,
792
+ & format ! (
793
+ "consider{} borrowing here" ,
794
+ if mut_result { " mutably" } else { "" }
795
+ ) ,
796
+ format ! ( "&{}" , if mut_result { "mut " } else { "" } ) ,
797
+ Applicability :: MaybeIncorrect ,
798
+ ) ;
799
+ }
785
800
}
786
801
return true ;
787
802
}
@@ -795,29 +810,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
795
810
ty:: TraitRef :: new ( obligation. parent_trait_ref . def_id ( ) , imm_substs) ;
796
811
let new_mut_trait_ref =
797
812
ty:: TraitRef :: new ( obligation. parent_trait_ref . def_id ( ) , mut_substs) ;
798
- if try_borrowing ( new_imm_trait_ref, expected_trait_ref, false , & [ ] ) {
799
- return true ;
800
- } else {
801
- return try_borrowing ( new_mut_trait_ref, expected_trait_ref, true , & [ ] ) ;
802
- }
813
+ return try_borrowing ( new_imm_trait_ref, new_mut_trait_ref, expected_trait_ref, & [ ] ) ;
803
814
} else if let ObligationCauseCode :: BindingObligation ( _, _)
804
815
| ObligationCauseCode :: ItemObligation ( _) = & * code
805
816
{
806
- if try_borrowing (
817
+ return try_borrowing (
807
818
ty:: TraitRef :: new ( trait_ref. def_id , imm_substs) ,
819
+ ty:: TraitRef :: new ( trait_ref. def_id , mut_substs) ,
808
820
trait_ref,
809
- false ,
810
821
& never_suggest_borrow[ ..] ,
811
- ) {
812
- return true ;
813
- } else {
814
- return try_borrowing (
815
- ty:: TraitRef :: new ( trait_ref. def_id , mut_substs) ,
816
- trait_ref,
817
- true ,
818
- & never_suggest_borrow[ ..] ,
819
- ) ;
820
- }
822
+ ) ;
821
823
} else {
822
824
false
823
825
}
0 commit comments