22//! found or is otherwise invalid.
33
44use crate :: errors;
5+ use crate :: Expectation ;
56use crate :: FnCtxt ;
67use rustc_ast:: ast:: Mutability ;
78use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
@@ -108,6 +109,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
108109 source : SelfSource < ' tcx > ,
109110 error : MethodError < ' tcx > ,
110111 args : Option < ( & ' tcx hir:: Expr < ' tcx > , & ' tcx [ hir:: Expr < ' tcx > ] ) > ,
112+ expected : Expectation < ' tcx > ,
111113 ) -> Option < DiagnosticBuilder < ' _ , ErrorGuaranteed > > {
112114 // Avoid suggestions when we don't know what's going on.
113115 if rcvr_ty. references_error ( ) {
@@ -131,6 +133,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
131133 args,
132134 sugg_span,
133135 & mut no_match_data,
136+ expected,
134137 ) ;
135138 }
136139
@@ -250,6 +253,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
250253 args : Option < ( & ' tcx hir:: Expr < ' tcx > , & ' tcx [ hir:: Expr < ' tcx > ] ) > ,
251254 sugg_span : Span ,
252255 no_match_data : & mut NoMatchData < ' tcx > ,
256+ expected : Expectation < ' tcx > ,
253257 ) -> Option < DiagnosticBuilder < ' _ , ErrorGuaranteed > > {
254258 let mode = no_match_data. mode ;
255259 let tcx = self . tcx ;
@@ -320,7 +324,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
320324
321325 if let Mode :: MethodCall = mode && let SelfSource :: MethodCall ( cal) = source {
322326 self . suggest_await_before_method (
323- & mut err, item_name, rcvr_ty, cal, span,
327+ & mut err, item_name, rcvr_ty, cal, span, expected . only_has_type ( self ) ,
324328 ) ;
325329 }
326330 if let Some ( span) =
@@ -898,7 +902,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
898902 // Don't suggest (for example) `expr.field.clone()` if `expr.clone()`
899903 // can't be called due to `typeof(expr): Clone` not holding.
900904 if unsatisfied_predicates. is_empty ( ) {
901- self . suggest_calling_method_on_field ( & mut err, source, span, rcvr_ty, item_name) ;
905+ self . suggest_calling_method_on_field (
906+ & mut err,
907+ source,
908+ span,
909+ rcvr_ty,
910+ item_name,
911+ expected. only_has_type ( self ) ,
912+ ) ;
902913 }
903914
904915 self . check_for_inner_self ( & mut err, source, rcvr_ty, item_name) ;
@@ -922,6 +933,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
922933 & unsatisfied_predicates,
923934 & static_candidates,
924935 unsatisfied_bounds,
936+ expected. only_has_type ( self ) ,
925937 ) ;
926938 }
927939
@@ -987,7 +999,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
987999 }
9881000 }
9891001
990- self . check_for_deref_method ( & mut err, source, rcvr_ty, item_name) ;
1002+ self . check_for_deref_method ( & mut err, source, rcvr_ty, item_name, expected ) ;
9911003 return Some ( err) ;
9921004 }
9931005
@@ -1377,6 +1389,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13771389 let pick = self . probe_for_name (
13781390 Mode :: MethodCall ,
13791391 item_name,
1392+ None ,
13801393 IsSuggestion ( true ) ,
13811394 range_ty,
13821395 expr. hir_id ,
@@ -1587,6 +1600,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15871600 span : Span ,
15881601 actual : Ty < ' tcx > ,
15891602 item_name : Ident ,
1603+ return_type : Option < Ty < ' tcx > > ,
15901604 ) {
15911605 if let SelfSource :: MethodCall ( expr) = source
15921606 && let mod_id = self . tcx . parent_module ( expr. hir_id ) . to_def_id ( )
@@ -1610,10 +1624,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16101624 self . check_for_nested_field_satisfying (
16111625 span,
16121626 & |_, field_ty| {
1613- self . lookup_probe (
1627+ self . probe_for_name (
1628+ Mode :: MethodCall ,
16141629 item_name,
1630+ return_type,
1631+ IsSuggestion ( true ) ,
16151632 field_ty,
1616- call_expr,
1633+ call_expr. hir_id ,
16171634 ProbeScope :: TraitsInScope ,
16181635 )
16191636 . map_or ( false , |pick| {
@@ -2010,12 +2027,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20102027 self_source : SelfSource < ' tcx > ,
20112028 rcvr_ty : Ty < ' tcx > ,
20122029 item_name : Ident ,
2030+ expected : Expectation < ' tcx > ,
20132031 ) {
20142032 let SelfSource :: QPath ( ty) = self_source else { return ; } ;
20152033 for ( deref_ty, _) in self . autoderef ( rustc_span:: DUMMY_SP , rcvr_ty) . skip ( 1 ) {
20162034 if let Ok ( pick) = self . probe_for_name (
20172035 Mode :: Path ,
20182036 item_name,
2037+ expected. only_has_type ( self ) ,
20192038 IsSuggestion ( true ) ,
20202039 deref_ty,
20212040 ty. hir_id ,
@@ -2080,12 +2099,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20802099 ty : Ty < ' tcx > ,
20812100 call : & hir:: Expr < ' _ > ,
20822101 span : Span ,
2102+ return_type : Option < Ty < ' tcx > > ,
20832103 ) {
20842104 let output_ty = match self . get_impl_future_output_ty ( ty) {
20852105 Some ( output_ty) => self . resolve_vars_if_possible ( output_ty) ,
20862106 _ => return ,
20872107 } ;
2088- let method_exists = self . method_exists ( item_name, output_ty, call. hir_id , true ) ;
2108+ let method_exists =
2109+ self . method_exists ( item_name, output_ty, call. hir_id , true , return_type) ;
20892110 debug ! ( "suggest_await_before_method: is_method_exist={}" , method_exists) ;
20902111 if method_exists {
20912112 err. span_suggestion_verbose (
@@ -2199,6 +2220,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21992220 ) ] ,
22002221 static_candidates : & [ CandidateSource ] ,
22012222 unsatisfied_bounds : bool ,
2223+ return_type : Option < Ty < ' tcx > > ,
22022224 ) {
22032225 let mut alt_rcvr_sugg = false ;
22042226 if let ( SelfSource :: MethodCall ( rcvr) , false ) = ( source, unsatisfied_bounds) {
@@ -2221,7 +2243,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22212243 ( self . tcx . mk_mut_ref ( self . tcx . lifetimes . re_erased , rcvr_ty) , "&mut " ) ,
22222244 ( self . tcx . mk_imm_ref ( self . tcx . lifetimes . re_erased , rcvr_ty) , "&" ) ,
22232245 ] {
2224- match self . lookup_probe ( item_name, * rcvr_ty, rcvr, ProbeScope :: AllTraits ) {
2246+ match self . probe_for_name (
2247+ Mode :: MethodCall ,
2248+ item_name,
2249+ return_type,
2250+ IsSuggestion ( true ) ,
2251+ * rcvr_ty,
2252+ rcvr. hir_id ,
2253+ ProbeScope :: AllTraits ,
2254+ ) {
22252255 Ok ( pick) => {
22262256 // If the method is defined for the receiver we have, it likely wasn't `use`d.
22272257 // We point at the method, but we just skip the rest of the check for arbitrary
@@ -2254,10 +2284,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22542284 ( self . tcx . mk_diagnostic_item ( * rcvr_ty, sym:: Rc ) , "Rc::new" ) ,
22552285 ] {
22562286 if let Some ( new_rcvr_t) = * rcvr_ty
2257- && let Ok ( pick) = self . lookup_probe (
2287+ && let Ok ( pick) = self . probe_for_name (
2288+ Mode :: MethodCall ,
22582289 item_name,
2290+ return_type,
2291+ IsSuggestion ( true ) ,
22592292 new_rcvr_t,
2260- rcvr,
2293+ rcvr. hir_id ,
22612294 ProbeScope :: AllTraits ,
22622295 )
22632296 {
0 commit comments