@@ -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 , MethodError } ;
1616use crate :: util:: common:: ErrorReported ;
1717use crate :: util:: nodemap:: FxHashMap ;
1818use crate :: astconv:: AstConv as _;
@@ -29,6 +29,7 @@ use rustc::hir::def::{CtorKind, Res, DefKind};
2929use rustc:: hir:: ptr:: P ;
3030use rustc:: infer;
3131use rustc:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
32+ use rustc:: middle:: lang_items;
3233use rustc:: mir:: interpret:: GlobalId ;
3334use rustc:: ty;
3435use rustc:: ty:: adjustment:: {
@@ -775,35 +776,80 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
775776 // no need to check for bot/err -- callee does that
776777 let rcvr_t = self . structurally_resolved_type ( args[ 0 ] . span , rcvr_t) ;
777778
778- let method = match self . lookup_method ( rcvr_t,
779- segment,
780- span,
781- expr,
782- rcvr) {
779+ let method = match self . lookup_method ( rcvr_t, segment, span, expr, rcvr) {
783780 Ok ( method) => {
784781 self . write_method_call ( expr. hir_id , method) ;
785782 Ok ( method)
786783 }
787784 Err ( error) => {
788785 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) ) ;
786+ self . report_extended_method_error ( segment, span, args, rcvr_t, error) ;
795787 }
796788 Err ( ( ) )
797789 }
798790 } ;
799791
800792 // Call the generic checker.
801- self . check_method_argument_types ( span,
802- expr. span ,
803- method,
804- & args[ 1 ..] ,
805- DontTupleArguments ,
806- expected)
793+ self . check_method_argument_types (
794+ span,
795+ expr. span ,
796+ method,
797+ & args[ 1 ..] ,
798+ DontTupleArguments ,
799+ expected,
800+ )
801+ }
802+
803+ fn report_extended_method_error (
804+ & self ,
805+ segment : & hir:: PathSegment ,
806+ span : Span ,
807+ args : & ' tcx [ hir:: Expr ] ,
808+ rcvr_t : Ty < ' tcx > ,
809+ error : MethodError < ' tcx >
810+ ) {
811+ let rcvr = & args[ 0 ] ;
812+ let try_alt_rcvr = |err : & mut DiagnosticBuilder < ' _ > , new_rcvr_t| {
813+ if let Ok ( pick) = self . lookup_probe (
814+ span,
815+ segment. ident ,
816+ new_rcvr_t,
817+ rcvr,
818+ probe:: ProbeScope :: AllTraits ,
819+ ) {
820+ err. span_label (
821+ pick. item . ident . span ,
822+ & format ! ( "the method is available for `{}` here" , new_rcvr_t) ,
823+ ) ;
824+ }
825+ } ;
826+
827+ if let Some ( mut err) = self . report_method_error (
828+ span,
829+ rcvr_t,
830+ segment. ident ,
831+ SelfSource :: MethodCall ( rcvr) ,
832+ error,
833+ Some ( args) ,
834+ ) {
835+ if let ty:: Adt ( ..) = rcvr_t. sty {
836+ // Try alternative arbitrary self types that could fulfill this call.
837+ // FIXME: probe for all types that *could* be arbitrary self-types, not
838+ // just this whitelist.
839+ let box_rcvr_t = self . tcx . mk_box ( rcvr_t) ;
840+ try_alt_rcvr ( & mut err, box_rcvr_t) ;
841+ let pin_rcvr_t = self . tcx . mk_lang_item (
842+ rcvr_t,
843+ lang_items:: PinTypeLangItem ,
844+ ) ;
845+ try_alt_rcvr ( & mut err, pin_rcvr_t) ;
846+ let arc_rcvr_t = self . tcx . mk_lang_item ( rcvr_t, lang_items:: Arc ) ;
847+ try_alt_rcvr ( & mut err, arc_rcvr_t) ;
848+ let rc_rcvr_t = self . tcx . mk_lang_item ( rcvr_t, lang_items:: Rc ) ;
849+ try_alt_rcvr ( & mut err, rc_rcvr_t) ;
850+ }
851+ err. emit ( ) ;
852+ }
807853 }
808854
809855 fn check_expr_cast (
@@ -1466,8 +1512,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14661512 let struct_variant_def = def. non_enum_variant ( ) ;
14671513 let field_names = self . available_field_names ( struct_variant_def) ;
14681514 if !field_names. is_empty ( ) {
1469- err. note ( & format ! ( "available fields are: {}" ,
1470- self . name_series_display( field_names) ) ) ;
1515+ err. note ( & format ! (
1516+ "available fields are: {}" ,
1517+ self . name_series_display( field_names) ,
1518+ ) ) ;
14711519 }
14721520 }
14731521 }
0 commit comments