@@ -2496,13 +2496,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2496
2496
// FIXME: probe for all types that *could* be arbitrary self-types, not
2497
2497
// just this list.
2498
2498
for ( rcvr_ty, post, pin_call) in & [
2499
- ( rcvr_ty, "" , "" ) ,
2499
+ ( rcvr_ty, "" , None ) ,
2500
2500
(
2501
2501
Ty :: new_mut_ref ( self . tcx , self . tcx . lifetimes . re_erased , rcvr_ty) ,
2502
2502
"&mut " ,
2503
- "as_mut" ,
2503
+ Some ( "as_mut" ) ,
2504
+ ) ,
2505
+ (
2506
+ Ty :: new_imm_ref ( self . tcx , self . tcx . lifetimes . re_erased , rcvr_ty) ,
2507
+ "&" ,
2508
+ Some ( "as_ref" ) ,
2504
2509
) ,
2505
- ( Ty :: new_imm_ref ( self . tcx , self . tcx . lifetimes . re_erased , rcvr_ty) , "&" , "as_ref" ) ,
2506
2510
] {
2507
2511
match self . lookup_probe_for_diagnostic (
2508
2512
item_name,
@@ -2594,22 +2598,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2594
2598
}
2595
2599
}
2596
2600
}
2597
- // We special case the situation where `Pin::new` wouldn't work, and isntead
2601
+ // We special case the situation where `Pin::new` wouldn't work, and instead
2598
2602
// suggest using the `pin!()` macro instead.
2599
2603
if let Some ( new_rcvr_t) = Ty :: new_lang_item ( self . tcx , * rcvr_ty, LangItem :: Pin )
2604
+ // We didn't find an alternative receiver for the method.
2600
2605
&& !alt_rcvr_sugg
2606
+ // `T: !Unpin`
2601
2607
&& !unpin
2608
+ // The method isn't `as_ref`, as it would provide a wrong suggestion for `Pin`.
2602
2609
&& sym:: as_ref != item_name. name
2603
- && * pin_call != ""
2610
+ // Either `Pin::as_ref` or `Pin::as_mut`.
2611
+ && let Some ( pin_call) = pin_call
2612
+ // Search for `item_name` as a method accessible on `Pin<T>`.
2604
2613
&& let Ok ( pick) = self . lookup_probe_for_diagnostic (
2605
2614
item_name,
2606
2615
new_rcvr_t,
2607
2616
rcvr,
2608
2617
ProbeScope :: AllTraits ,
2609
2618
return_type,
2610
2619
)
2620
+ // We skip some common traits that we don't want to consider because autoderefs
2621
+ // would take care of them.
2611
2622
&& !skippable. contains ( & Some ( pick. item . container_id ( self . tcx ) ) )
2623
+ // We don't want to go through derefs.
2612
2624
&& pick. autoderefs == 0
2625
+ // Check that the method of the same name that was found on the new `Pin<T>`
2626
+ // receiver has the same number of arguments that appear in the user's code.
2613
2627
&& inputs_len. is_some_and ( |inputs_len| pick. item . kind == ty:: AssocKind :: Fn && self . tcx . fn_sig ( pick. item . def_id ) . skip_binder ( ) . skip_binder ( ) . inputs ( ) . len ( ) == inputs_len)
2614
2628
{
2615
2629
let indent = self . tcx . sess
0 commit comments