@@ -988,6 +988,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
988
988
let mut alt_rcvr_sugg = false ;
989
989
if let SelfSource :: MethodCall ( rcvr) = source {
990
990
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
+ ] ;
991
997
// Try alternative arbitrary self types that could fulfill this call.
992
998
// FIXME: probe for all types that *could* be arbitrary self-types, not
993
999
// just this list.
@@ -996,6 +1002,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
996
1002
( self . tcx . mk_mut_ref ( & ty:: ReErased , rcvr_ty) , "&mut " ) ,
997
1003
( self . tcx . mk_imm_ref ( & ty:: ReErased , rcvr_ty) , "&" ) ,
998
1004
] {
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
+ }
999
1026
for ( rcvr_ty, pre) in & [
1000
1027
( self . tcx . mk_lang_item ( rcvr_ty, LangItem :: OwnedBox ) , "Box::new" ) ,
1001
1028
( self . tcx . mk_lang_item ( rcvr_ty, LangItem :: Pin ) , "Pin::new" ) ,
@@ -1015,13 +1042,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1015
1042
// We don't want to suggest a container type when the missing
1016
1043
// method is `.clone()` or `.deref()` otherwise we'd suggest
1017
1044
// `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) ;
1025
1046
// Make sure the method is defined for the *actual* receiver: we don't
1026
1047
// want to treat `Box<Self>` as a receiver if it only works because of
1027
1048
// an autoderef to `&self`
@@ -1047,7 +1068,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1047
1068
}
1048
1069
}
1049
1070
}
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) {
1051
1072
return ;
1052
1073
}
1053
1074
0 commit comments