@@ -283,6 +283,7 @@ pub trait TypeErrCtxtExt<'tcx> {
283
283
expected : ty:: PolyTraitRef < ' tcx > ,
284
284
cause : & ObligationCauseCode < ' tcx > ,
285
285
found_node : Option < Node < ' _ > > ,
286
+ param_env : ty:: ParamEnv < ' tcx > ,
286
287
) -> DiagnosticBuilder < ' tcx , ErrorGuaranteed > ;
287
288
288
289
fn note_conflicting_closure_bounds (
@@ -1978,6 +1979,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1978
1979
expected : ty:: PolyTraitRef < ' tcx > ,
1979
1980
cause : & ObligationCauseCode < ' tcx > ,
1980
1981
found_node : Option < Node < ' _ > > ,
1982
+ param_env : ty:: ParamEnv < ' tcx > ,
1981
1983
) -> DiagnosticBuilder < ' tcx , ErrorGuaranteed > {
1982
1984
pub ( crate ) fn build_fn_sig_ty < ' tcx > (
1983
1985
infcx : & InferCtxt < ' tcx > ,
@@ -2040,7 +2042,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2040
2042
self . note_conflicting_closure_bounds ( cause, & mut err) ;
2041
2043
2042
2044
if let Some ( found_node) = found_node {
2043
- hint_missing_borrow ( span, found, expected, found_node, & mut err) ;
2045
+ hint_missing_borrow ( self , param_env , span, found, expected, found_node, & mut err) ;
2044
2046
}
2045
2047
2046
2048
err
@@ -3747,6 +3749,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
3747
3749
3748
3750
/// Add a hint to add a missing borrow or remove an unnecessary one.
3749
3751
fn hint_missing_borrow < ' tcx > (
3752
+ infcx : & InferCtxt < ' tcx > ,
3753
+ param_env : ty:: ParamEnv < ' tcx > ,
3750
3754
span : Span ,
3751
3755
found : Ty < ' tcx > ,
3752
3756
expected : Ty < ' tcx > ,
@@ -3769,7 +3773,7 @@ fn hint_missing_borrow<'tcx>(
3769
3773
// This could be a variant constructor, for example.
3770
3774
let Some ( fn_decl) = found_node. fn_decl ( ) else { return ; } ;
3771
3775
3772
- let arg_spans = fn_decl. inputs . iter ( ) . map ( |ty| ty. span ) ;
3776
+ let args = fn_decl. inputs . iter ( ) . map ( |ty| ty) ;
3773
3777
3774
3778
fn get_deref_type_and_refs ( mut ty : Ty < ' _ > ) -> ( Ty < ' _ > , usize ) {
3775
3779
let mut refs = 0 ;
@@ -3785,29 +3789,42 @@ fn hint_missing_borrow<'tcx>(
3785
3789
let mut to_borrow = Vec :: new ( ) ;
3786
3790
let mut remove_borrow = Vec :: new ( ) ;
3787
3791
3788
- for ( ( found_arg, expected_arg) , arg_span ) in found_args. zip ( expected_args) . zip ( arg_spans ) {
3792
+ for ( ( found_arg, expected_arg) , arg ) in found_args. zip ( expected_args) . zip ( args ) {
3789
3793
let ( found_ty, found_refs) = get_deref_type_and_refs ( * found_arg) ;
3790
3794
let ( expected_ty, expected_refs) = get_deref_type_and_refs ( * expected_arg) ;
3791
3795
3792
- if found_ty == expected_ty {
3796
+ if infcx . can_eq ( param_env , found_ty, expected_ty) . is_ok ( ) {
3793
3797
if found_refs < expected_refs {
3794
- to_borrow. push ( ( arg_span , expected_arg . to_string ( ) ) ) ;
3798
+ to_borrow. push ( ( arg . span . shrink_to_lo ( ) , "&" . repeat ( expected_refs - found_refs ) ) ) ;
3795
3799
} else if found_refs > expected_refs {
3796
- remove_borrow. push ( ( arg_span, expected_arg. to_string ( ) ) ) ;
3800
+ let mut span = arg. span . shrink_to_lo ( ) ;
3801
+ let mut left = found_refs - expected_refs;
3802
+ let mut ty = arg;
3803
+ while let hir:: TyKind :: Ref ( _, mut_ty) = & ty. kind && left > 0 {
3804
+ span = span. with_hi ( mut_ty. ty . span . lo ( ) ) ;
3805
+ ty = mut_ty. ty ;
3806
+ left -= 1 ;
3807
+ }
3808
+ let sugg = if left == 0 {
3809
+ ( span, String :: new ( ) )
3810
+ } else {
3811
+ ( arg. span , expected_arg. to_string ( ) )
3812
+ } ;
3813
+ remove_borrow. push ( sugg) ;
3797
3814
}
3798
3815
}
3799
3816
}
3800
3817
3801
3818
if !to_borrow. is_empty ( ) {
3802
- err. multipart_suggestion (
3819
+ err. multipart_suggestion_verbose (
3803
3820
"consider borrowing the argument" ,
3804
3821
to_borrow,
3805
3822
Applicability :: MaybeIncorrect ,
3806
3823
) ;
3807
3824
}
3808
3825
3809
3826
if !remove_borrow. is_empty ( ) {
3810
- err. multipart_suggestion (
3827
+ err. multipart_suggestion_verbose (
3811
3828
"do not borrow the argument" ,
3812
3829
remove_borrow,
3813
3830
Applicability :: MaybeIncorrect ,
0 commit comments