@@ -988,6 +988,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
988988 let mut alt_rcvr_sugg = false ;
989989 if let SelfSource :: MethodCall ( rcvr) = source {
990990 debug ! ( ?span, ?item_name, ?rcvr_ty, ?rcvr) ;
991+ let skippable = [
992+ self . tcx . lang_items ( ) . clone_trait ( ) ,
993+ self . tcx . lang_items ( ) . deref_trait ( ) ,
994+ self . tcx . lang_items ( ) . deref_mut_trait ( ) ,
995+ self . tcx . lang_items ( ) . drop_trait ( ) ,
996+ ] ;
991997 // Try alternative arbitrary self types that could fulfill this call.
992998 // FIXME: probe for all types that *could* be arbitrary self-types, not
993999 // just this list.
@@ -996,6 +1002,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9961002 ( self . tcx . mk_mut_ref ( & ty:: ReErased , rcvr_ty) , "&mut " ) ,
9971003 ( self . tcx . mk_imm_ref ( & ty:: ReErased , rcvr_ty) , "&" ) ,
9981004 ] {
1005+ if let Ok ( pick) = self . lookup_probe (
1006+ span,
1007+ item_name,
1008+ rcvr_ty,
1009+ rcvr,
1010+ crate :: check:: method:: probe:: ProbeScope :: AllTraits ,
1011+ ) {
1012+ // If the method is defined for the receiver we have, it likely wasn't `use`d.
1013+ // We point at the method, but we just skip the rest of the check for arbitrary
1014+ // self types and rely on the suggestion to `use` the trait from
1015+ // `suggest_valid_traits`.
1016+ let did = Some ( pick. item . container . id ( ) ) ;
1017+ let skip = skippable. contains ( & did) ;
1018+ if pick. autoderefs == 0 && !skip {
1019+ err. span_label (
1020+ pick. item . ident . span ,
1021+ & format ! ( "the method is available for `{}` here" , rcvr_ty) ,
1022+ ) ;
1023+ }
1024+ break ;
1025+ }
9991026 for ( rcvr_ty, pre) in & [
10001027 ( self . tcx . mk_lang_item ( rcvr_ty, LangItem :: OwnedBox ) , "Box::new" ) ,
10011028 ( self . tcx . mk_lang_item ( rcvr_ty, LangItem :: Pin ) , "Pin::new" ) ,
@@ -1015,13 +1042,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10151042 // We don't want to suggest a container type when the missing
10161043 // method is `.clone()` or `.deref()` otherwise we'd suggest
10171044 // `Arc::new(foo).clone()`, which is far from what the user wants.
1018- let skip = [
1019- self . tcx . lang_items ( ) . clone_trait ( ) ,
1020- self . tcx . lang_items ( ) . deref_trait ( ) ,
1021- self . tcx . lang_items ( ) . deref_mut_trait ( ) ,
1022- self . tcx . lang_items ( ) . drop_trait ( ) ,
1023- ]
1024- . contains ( & did) ;
1045+ let skip = skippable. contains ( & did) ;
10251046 // Make sure the method is defined for the *actual* receiver: we don't
10261047 // want to treat `Box<Self>` as a receiver if it only works because of
10271048 // an autoderef to `&self`
@@ -1047,7 +1068,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10471068 }
10481069 }
10491070 }
1050- if !alt_rcvr_sugg && self . suggest_valid_traits ( err, valid_out_of_scope_traits) {
1071+ if self . suggest_valid_traits ( err, valid_out_of_scope_traits) {
10511072 return ;
10521073 }
10531074
0 commit comments