@@ -12,7 +12,7 @@ use crate::check::fatally_break_rust;
12
12
use crate :: check:: report_unexpected_variant_res;
13
13
use crate :: check:: Needs ;
14
14
use crate :: check:: TupleArgumentsFlag :: DontTupleArguments ;
15
- use crate :: check:: method:: SelfSource ;
15
+ use crate :: check:: method:: { probe , SelfSource } ;
16
16
use crate :: util:: common:: ErrorReported ;
17
17
use crate :: util:: nodemap:: FxHashMap ;
18
18
use crate :: astconv:: AstConv as _;
@@ -775,35 +775,65 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
775
775
// no need to check for bot/err -- callee does that
776
776
let rcvr_t = self . structurally_resolved_type ( args[ 0 ] . span , rcvr_t) ;
777
777
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) {
783
794
Ok ( method) => {
784
795
self . write_method_call ( expr. hir_id , method) ;
785
796
Ok ( method)
786
797
}
787
798
Err ( error) => {
788
799
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
+ }
795
823
}
796
824
Err ( ( ) )
797
825
}
798
826
} ;
799
827
800
828
// 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
+ )
807
837
}
808
838
809
839
fn check_expr_cast (
@@ -1466,8 +1496,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1466
1496
let struct_variant_def = def. non_enum_variant ( ) ;
1467
1497
let field_names = self . available_field_names ( struct_variant_def) ;
1468
1498
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
+ ) ) ;
1471
1503
}
1472
1504
}
1473
1505
}
0 commit comments