@@ -987,59 +987,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
987987 ) {
988988 let mut alt_rcvr_sugg = false ;
989989 if let SelfSource :: MethodCall ( rcvr) = source {
990- info ! ( ?span, ?item_name, ?rcvr_ty, ?rcvr) ;
991- if let ty:: Adt ( ..) = rcvr_ty. kind ( ) {
992- // Try alternative arbitrary self types that could fulfill this call.
993- // FIXME: probe for all types that *could* be arbitrary self-types, not
994- // just this list.
995- for ( rcvr_ty, post) in & [
996- ( rcvr_ty, "" ) ,
997- ( self . tcx . mk_mut_ref ( & ty:: ReErased , rcvr_ty) , "&mut " ) ,
998- ( self . tcx . mk_imm_ref ( & ty:: ReErased , rcvr_ty) , "&" ) ,
990+ debug ! ( ?span, ?item_name, ?rcvr_ty, ?rcvr) ;
991+ // Try alternative arbitrary self types that could fulfill this call.
992+ // FIXME: probe for all types that *could* be arbitrary self-types, not
993+ // just this list.
994+ for ( rcvr_ty, post) in & [
995+ ( rcvr_ty, "" ) ,
996+ ( self . tcx . mk_mut_ref ( & ty:: ReErased , rcvr_ty) , "&mut " ) ,
997+ ( self . tcx . mk_imm_ref ( & ty:: ReErased , rcvr_ty) , "&" ) ,
998+ ] {
999+ for ( rcvr_ty, pre) in & [
1000+ ( self . tcx . mk_lang_item ( rcvr_ty, LangItem :: OwnedBox ) , "Box::new" ) ,
1001+ ( self . tcx . mk_lang_item ( rcvr_ty, LangItem :: Pin ) , "Pin::new" ) ,
1002+ ( self . tcx . mk_diagnostic_item ( rcvr_ty, sym:: Arc ) , "Arc::new" ) ,
1003+ ( self . tcx . mk_diagnostic_item ( rcvr_ty, sym:: Rc ) , "Rc::new" ) ,
9991004 ] {
1000- for ( rcvr_ty, pre) in & [
1001- ( self . tcx . mk_lang_item ( rcvr_ty, LangItem :: OwnedBox ) , "Box::new" ) ,
1002- ( self . tcx . mk_lang_item ( rcvr_ty, LangItem :: Pin ) , "Pin::new" ) ,
1003- ( self . tcx . mk_diagnostic_item ( rcvr_ty, sym:: Arc ) , "Arc::new" ) ,
1004- ( self . tcx . mk_diagnostic_item ( rcvr_ty, sym:: Rc ) , "Rc::new" ) ,
1005- ] {
1006- if let Some ( new_rcvr_t) = * rcvr_ty {
1007- if let Ok ( pick) = self . lookup_probe (
1008- span,
1009- item_name,
1010- new_rcvr_t,
1011- rcvr,
1012- crate :: check:: method:: probe:: ProbeScope :: AllTraits ,
1013- ) {
1014- debug ! ( "try_alt_rcvr: pick candidate {:?}" , pick) ;
1015- // Make sure the method is defined for the *actual* receiver:
1016- // we don't want to treat `Box<Self>` as a receiver if
1017- // it only works because of an autoderef to `&self`
1018- if pick. autoderefs == 0
1019- // We don't want to suggest a container type when the missing method is
1020- // `.clone()`, otherwise we'd suggest `Arc::new(foo).clone()`, which is
1021- // far from what the user really wants.
1022- && Some ( pick. item . container . id ( ) ) != self . tcx . lang_items ( ) . clone_trait ( )
1023- {
1024- err. span_label (
1025- pick. item . ident . span ,
1026- & format ! (
1027- "the method is available for `{}` here" ,
1028- new_rcvr_t
1029- ) ,
1030- ) ;
1031- err. multipart_suggestion (
1032- "consider wrapping the receiver expression with the \
1033- appropriate type",
1034- vec ! [
1035- ( rcvr. span. shrink_to_lo( ) , format!( "{}({}" , pre, post) ) ,
1036- ( rcvr. span. shrink_to_hi( ) , ")" . to_string( ) ) ,
1037- ] ,
1038- Applicability :: MaybeIncorrect ,
1039- ) ;
1040- // We don't care about the other suggestions.
1041- alt_rcvr_sugg = true ;
1042- }
1005+ if let Some ( new_rcvr_t) = * rcvr_ty {
1006+ if let Ok ( pick) = self . lookup_probe (
1007+ span,
1008+ item_name,
1009+ new_rcvr_t,
1010+ rcvr,
1011+ crate :: check:: method:: probe:: ProbeScope :: AllTraits ,
1012+ ) {
1013+ debug ! ( "try_alt_rcvr: pick candidate {:?}" , pick) ;
1014+ let did = Some ( pick. item . container . id ( ) ) ;
1015+ // We don't want to suggest a container type when the missing
1016+ // method is `.clone()` or `.deref()` otherwise we'd suggest
1017+ // `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) ;
1025+ // Make sure the method is defined for the *actual* receiver: we don't
1026+ // want to treat `Box<Self>` as a receiver if it only works because of
1027+ // an autoderef to `&self`
1028+ if pick. autoderefs == 0 && !skip {
1029+ err. span_label (
1030+ pick. item . ident . span ,
1031+ & format ! ( "the method is available for `{}` here" , new_rcvr_t) ,
1032+ ) ;
1033+ err. multipart_suggestion (
1034+ "consider wrapping the receiver expression with the \
1035+ appropriate type",
1036+ vec ! [
1037+ ( rcvr. span. shrink_to_lo( ) , format!( "{}({}" , pre, post) ) ,
1038+ ( rcvr. span. shrink_to_hi( ) , ")" . to_string( ) ) ,
1039+ ] ,
1040+ Applicability :: MaybeIncorrect ,
1041+ ) ;
1042+ // We don't care about the other suggestions.
1043+ alt_rcvr_sugg = true ;
10431044 }
10441045 }
10451046 }
0 commit comments