@@ -115,7 +115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
115115 item_name : Ident ,
116116 source : SelfSource < ' tcx > ,
117117 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 > ) > ,
119119 expected : Expectation < ' tcx > ,
120120 trait_missing_method : bool ,
121121 ) -> Option < DiagnosticBuilder < ' _ , ErrorGuaranteed > > {
@@ -257,7 +257,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
257257 fn suggest_missing_writer (
258258 & self ,
259259 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 > ) ,
261261 ) -> DiagnosticBuilder < ' _ , ErrorGuaranteed > {
262262 let ( ty_str, _ty_file) = self . tcx . short_ty_string ( rcvr_ty) ;
263263 let mut err =
@@ -282,7 +282,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
282282 rcvr_ty : Ty < ' tcx > ,
283283 item_name : Ident ,
284284 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 > ) > ,
286286 sugg_span : Span ,
287287 no_match_data : & mut NoMatchData < ' tcx > ,
288288 expected : Expectation < ' tcx > ,
@@ -953,6 +953,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
953953
954954 unsatisfied_bounds = true ;
955955 }
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+ }
956983 }
957984
958985 let label_span_not_found = |err : & mut Diagnostic | {
@@ -1111,7 +1138,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11111138 span,
11121139 rcvr_ty,
11131140 item_name,
1114- args. map ( |( _, args) | args. len ( ) + 1 ) ,
1141+ args. map ( |( _, args, _ ) | args. len ( ) + 1 ) ,
11151142 source,
11161143 no_match_data. out_of_scope_traits . clone ( ) ,
11171144 & unsatisfied_predicates,
@@ -1192,7 +1219,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11921219 & self ,
11931220 rcvr_ty : Ty < ' tcx > ,
11941221 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 > ) > ,
11961223 span : Span ,
11971224 err : & mut Diagnostic ,
11981225 sources : & mut Vec < CandidateSource > ,
@@ -1343,7 +1370,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13431370 rcvr_ty : Ty < ' tcx > ,
13441371 source : SelfSource < ' tcx > ,
13451372 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 > ) > ,
13471374 sugg_span : Span ,
13481375 ) {
13491376 let mut has_unsuggestable_args = false ;
@@ -1415,7 +1442,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14151442 None
14161443 } ;
14171444 let mut applicability = Applicability :: MachineApplicable ;
1418- let args = if let Some ( ( receiver, args) ) = args {
1445+ let args = if let Some ( ( receiver, args, _ ) ) = args {
14191446 // The first arg is the same kind as the receiver
14201447 let explicit_args = if first_arg. is_some ( ) {
14211448 std:: iter:: once ( receiver) . chain ( args. iter ( ) ) . collect :: < Vec < _ > > ( )
@@ -2995,7 +3022,7 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
29953022
29963023fn print_disambiguation_help < ' tcx > (
29973024 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 > ) > ,
29993026 err : & mut Diagnostic ,
30003027 trait_name : String ,
30013028 rcvr_ty : Ty < ' _ > ,
@@ -3007,7 +3034,7 @@ fn print_disambiguation_help<'tcx>(
30073034 fn_has_self_parameter : bool ,
30083035) {
30093036 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) {
30113038 let args = format ! (
30123039 "({}{})" ,
30133040 rcvr_ty. ref_mutability( ) . map_or( "" , |mutbl| mutbl. ref_prefix_str( ) ) ,
0 commit comments