@@ -12,7 +12,7 @@ use crate::check::fatally_break_rust;
1212use crate :: check:: report_unexpected_variant_res;
1313use crate :: check:: Needs ;
1414use crate :: check:: TupleArgumentsFlag :: DontTupleArguments ;
15- use crate :: check:: method:: SelfSource ;
15+ use crate :: check:: method:: { probe , SelfSource } ;
1616use crate :: util:: common:: ErrorReported ;
1717use crate :: util:: nodemap:: FxHashMap ;
1818use crate :: astconv:: AstConv as _;
@@ -775,35 +775,65 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
775775 // no need to check for bot/err -- callee does that
776776 let rcvr_t = self . structurally_resolved_type ( args[ 0 ] . span , rcvr_t) ;
777777
778- let method = match self . lookup_method ( rcvr_t,
779- segment,
780- span,
781- expr,
782- rcvr) {
778+ let try_alt_rcvr = |err : & mut DiagnosticBuilder < ' _ > , new_rcvr_t| {
779+ if let Ok ( pick) = self . lookup_probe (
780+ span,
781+ segment. ident ,
782+ new_rcvr_t,
783+ rcvr,
784+ probe:: ProbeScope :: AllTraits ,
785+ ) {
786+ err. span_label (
787+ pick. item . ident . span ,
788+ & format ! ( "the method is available for `{}` here" , new_rcvr_t) ,
789+ ) ;
790+ }
791+ } ;
792+
793+ let method = match self . lookup_method ( rcvr_t, segment, span, expr, rcvr) {
783794 Ok ( method) => {
784795 self . write_method_call ( expr. hir_id , method) ;
785796 Ok ( method)
786797 }
787798 Err ( error) => {
788799 if segment. ident . name != kw:: Invalid {
789- self . report_method_error ( span,
790- rcvr_t,
791- segment. ident ,
792- SelfSource :: MethodCall ( rcvr) ,
793- error,
794- Some ( args) ) ;
800+ if let Some ( mut err) = self . report_method_error (
801+ span,
802+ rcvr_t,
803+ segment. ident ,
804+ SelfSource :: MethodCall ( rcvr) ,
805+ error,
806+ Some ( args) ,
807+ ) {
808+ if let ty:: Adt ( ..) = rcvr_t. sty {
809+ // Try alternative arbitrary self types that could fulfill this call.
810+ // FIXME: probe for all types that *could* be arbitrary self-types, not
811+ // just this whitelist.
812+ let box_rcvr_t = self . tcx . mk_box ( rcvr_t) ;
813+ try_alt_rcvr ( & mut err, box_rcvr_t) ;
814+ let pin_rcvr_t = self . tcx . mk_pin ( rcvr_t) ;
815+ try_alt_rcvr ( & mut err, pin_rcvr_t) ;
816+ let arc_rcvr_t = self . tcx . mk_arc ( rcvr_t) ;
817+ try_alt_rcvr ( & mut err, arc_rcvr_t) ;
818+ let rc_rcvr_t = self . tcx . mk_rc ( rcvr_t) ;
819+ try_alt_rcvr ( & mut err, rc_rcvr_t) ;
820+ }
821+ err. emit ( ) ;
822+ }
795823 }
796824 Err ( ( ) )
797825 }
798826 } ;
799827
800828 // Call the generic checker.
801- self . check_method_argument_types ( span,
802- expr. span ,
803- method,
804- & args[ 1 ..] ,
805- DontTupleArguments ,
806- expected)
829+ self . check_method_argument_types (
830+ span,
831+ expr. span ,
832+ method,
833+ & args[ 1 ..] ,
834+ DontTupleArguments ,
835+ expected,
836+ )
807837 }
808838
809839 fn check_expr_cast (
@@ -1466,8 +1496,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14661496 let struct_variant_def = def. non_enum_variant ( ) ;
14671497 let field_names = self . available_field_names ( struct_variant_def) ;
14681498 if !field_names. is_empty ( ) {
1469- err. note ( & format ! ( "available fields are: {}" ,
1470- self . name_series_display( field_names) ) ) ;
1499+ err. note ( & format ! (
1500+ "available fields are: {}" ,
1501+ self . name_series_display( field_names) ,
1502+ ) ) ;
14711503 }
14721504 }
14731505 }
0 commit comments