@@ -115,7 +115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
115
115
item_name : Ident ,
116
116
source : SelfSource < ' tcx > ,
117
117
error : MethodError < ' tcx > ,
118
- args : Option < ( & ' tcx hir:: Expr < ' tcx > , & ' tcx [ hir:: Expr < ' tcx > ] ) > ,
118
+ args : Option < ( & ' tcx hir:: Expr < ' tcx > , & ' tcx [ hir:: Expr < ' tcx > ] , & ' tcx hir :: Expr < ' tcx > ) > ,
119
119
expected : Expectation < ' tcx > ,
120
120
trait_missing_method : bool ,
121
121
) -> Option < DiagnosticBuilder < ' _ , ErrorGuaranteed > > {
@@ -257,7 +257,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
257
257
fn suggest_missing_writer (
258
258
& self ,
259
259
rcvr_ty : Ty < ' tcx > ,
260
- args : ( & ' tcx hir:: Expr < ' tcx > , & ' tcx [ hir:: Expr < ' tcx > ] ) ,
260
+ args : ( & ' tcx hir:: Expr < ' tcx > , & ' tcx [ hir:: Expr < ' tcx > ] , & ' tcx hir :: Expr < ' tcx > ) ,
261
261
) -> DiagnosticBuilder < ' _ , ErrorGuaranteed > {
262
262
let ( ty_str, _ty_file) = self . tcx . short_ty_string ( rcvr_ty) ;
263
263
let mut err =
@@ -282,7 +282,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
282
282
rcvr_ty : Ty < ' tcx > ,
283
283
item_name : Ident ,
284
284
source : SelfSource < ' tcx > ,
285
- args : Option < ( & ' tcx hir:: Expr < ' tcx > , & ' tcx [ hir:: Expr < ' tcx > ] ) > ,
285
+ args : Option < ( & ' tcx hir:: Expr < ' tcx > , & ' tcx [ hir:: Expr < ' tcx > ] , & ' tcx hir :: Expr < ' tcx > ) > ,
286
286
sugg_span : Span ,
287
287
no_match_data : & mut NoMatchData < ' tcx > ,
288
288
expected : Expectation < ' tcx > ,
@@ -953,6 +953,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
953
953
954
954
unsatisfied_bounds = true ;
955
955
}
956
+ } else if let ty:: Adt ( def, targs) = rcvr_ty. kind ( ) && let Some ( ( rcvr, _, expr) ) = args {
957
+ // This is useful for methods on arbitrary self types that might have a simple
958
+ // mutability difference, like calling a method on `Pin<&mut Self>` that is on
959
+ // `Pin<&Self>`.
960
+ if targs. len ( ) == 1 {
961
+ let mut item_segment = hir:: PathSegment :: invalid ( ) ;
962
+ item_segment. ident = item_name;
963
+ for t in [ Ty :: new_mut_ref, Ty :: new_imm_ref, |_, _, t| t] {
964
+ let new_args = tcx. mk_args_from_iter (
965
+ targs
966
+ . iter ( )
967
+ . map ( |arg| match arg. as_type ( ) {
968
+ Some ( ty) => ty:: GenericArg :: from (
969
+ t ( tcx, tcx. lifetimes . re_erased , ty. peel_refs ( ) ) ,
970
+ ) ,
971
+ _ => arg,
972
+ } )
973
+ ) ;
974
+ let rcvr_ty = Ty :: new_adt ( tcx, * def, new_args) ;
975
+ if let Ok ( method) = self . lookup_method_for_diagnostic ( rcvr_ty, & item_segment, span, expr, rcvr) {
976
+ err. span_note (
977
+ tcx. def_span ( method. def_id ) ,
978
+ format ! ( "{item_kind} is available for `{rcvr_ty}`" ) ,
979
+ ) ;
980
+ }
981
+ }
982
+ }
956
983
}
957
984
958
985
let label_span_not_found = |err : & mut Diagnostic | {
@@ -1111,7 +1138,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1111
1138
span,
1112
1139
rcvr_ty,
1113
1140
item_name,
1114
- args. map ( |( _, args) | args. len ( ) + 1 ) ,
1141
+ args. map ( |( _, args, _ ) | args. len ( ) + 1 ) ,
1115
1142
source,
1116
1143
no_match_data. out_of_scope_traits . clone ( ) ,
1117
1144
& unsatisfied_predicates,
@@ -1192,7 +1219,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1192
1219
& self ,
1193
1220
rcvr_ty : Ty < ' tcx > ,
1194
1221
item_name : Ident ,
1195
- args : Option < ( & ' tcx hir:: Expr < ' tcx > , & ' tcx [ hir:: Expr < ' tcx > ] ) > ,
1222
+ args : Option < ( & ' tcx hir:: Expr < ' tcx > , & ' tcx [ hir:: Expr < ' tcx > ] , & ' tcx hir :: Expr < ' tcx > ) > ,
1196
1223
span : Span ,
1197
1224
err : & mut Diagnostic ,
1198
1225
sources : & mut Vec < CandidateSource > ,
@@ -1343,7 +1370,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1343
1370
rcvr_ty : Ty < ' tcx > ,
1344
1371
source : SelfSource < ' tcx > ,
1345
1372
item_name : Ident ,
1346
- args : Option < ( & hir:: Expr < ' tcx > , & [ hir:: Expr < ' tcx > ] ) > ,
1373
+ args : Option < ( & hir:: Expr < ' tcx > , & [ hir:: Expr < ' tcx > ] , & ' tcx hir :: Expr < ' tcx > ) > ,
1347
1374
sugg_span : Span ,
1348
1375
) {
1349
1376
let mut has_unsuggestable_args = false ;
@@ -1415,7 +1442,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1415
1442
None
1416
1443
} ;
1417
1444
let mut applicability = Applicability :: MachineApplicable ;
1418
- let args = if let Some ( ( receiver, args) ) = args {
1445
+ let args = if let Some ( ( receiver, args, _ ) ) = args {
1419
1446
// The first arg is the same kind as the receiver
1420
1447
let explicit_args = if first_arg. is_some ( ) {
1421
1448
std:: iter:: once ( receiver) . chain ( args. iter ( ) ) . collect :: < Vec < _ > > ( )
@@ -2995,7 +3022,7 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
2995
3022
2996
3023
fn print_disambiguation_help < ' tcx > (
2997
3024
item_name : Ident ,
2998
- args : Option < ( & ' tcx hir:: Expr < ' tcx > , & ' tcx [ hir:: Expr < ' tcx > ] ) > ,
3025
+ args : Option < ( & ' tcx hir:: Expr < ' tcx > , & ' tcx [ hir:: Expr < ' tcx > ] , & ' tcx hir :: Expr < ' tcx > ) > ,
2999
3026
err : & mut Diagnostic ,
3000
3027
trait_name : String ,
3001
3028
rcvr_ty : Ty < ' _ > ,
@@ -3007,7 +3034,7 @@ fn print_disambiguation_help<'tcx>(
3007
3034
fn_has_self_parameter : bool ,
3008
3035
) {
3009
3036
let mut applicability = Applicability :: MachineApplicable ;
3010
- let ( span, sugg) = if let ( ty:: AssocKind :: Fn , Some ( ( receiver, args) ) ) = ( kind, args) {
3037
+ let ( span, sugg) = if let ( ty:: AssocKind :: Fn , Some ( ( receiver, args, _ ) ) ) = ( kind, args) {
3011
3038
let args = format ! (
3012
3039
"({}{})" ,
3013
3040
rcvr_ty. ref_mutability( ) . map_or( "" , |mutbl| mutbl. ref_prefix_str( ) ) ,
0 commit comments