@@ -16,11 +16,11 @@ use rustc_data_structures::unord::UnordSet;
1616use rustc_errors:: {
1717 codes:: * , pluralize, struct_span_code_err, Applicability , Diag , MultiSpan , StashKey ,
1818} ;
19- use rustc_hir as hir;
2019use rustc_hir:: def:: DefKind ;
2120use rustc_hir:: def_id:: DefId ;
2221use rustc_hir:: lang_items:: LangItem ;
2322use rustc_hir:: PathSegment ;
23+ use rustc_hir:: { self as hir, HirId } ;
2424use rustc_hir:: { ExprKind , Node , QPath } ;
2525use rustc_infer:: infer:: { self , RegionVariableOrigin } ;
2626use rustc_middle:: bug;
@@ -187,37 +187,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
187187 #[ instrument( level = "debug" , skip( self ) ) ]
188188 pub fn report_method_error (
189189 & self ,
190- span : Span ,
191- rcvr_opt : Option < & ' tcx hir:: Expr < ' tcx > > ,
190+ call_id : HirId ,
192191 rcvr_ty : Ty < ' tcx > ,
193- item_name : Ident ,
194- expr_id : hir:: HirId ,
195- source : SelfSource < ' tcx > ,
196192 error : MethodError < ' tcx > ,
197- args : Option < & ' tcx [ hir:: Expr < ' tcx > ] > ,
198193 expected : Expectation < ' tcx > ,
199194 trait_missing_method : bool ,
200195 ) -> Option < Diag < ' _ > > {
196+ let ( span, sugg_span, source, item_name, args) = match self . tcx . hir_node ( call_id) {
197+ hir:: Node :: Expr ( & hir:: Expr {
198+ kind : hir:: ExprKind :: MethodCall ( segment, rcvr, args, _) ,
199+ span,
200+ ..
201+ } ) => {
202+ ( segment. ident . span , span, SelfSource :: MethodCall ( rcvr) , segment. ident , Some ( args) )
203+ }
204+ hir:: Node :: Expr ( & hir:: Expr {
205+ kind : hir:: ExprKind :: Path ( QPath :: TypeRelative ( rcvr, segment) ) ,
206+ span,
207+ ..
208+ } )
209+ | hir:: Node :: Pat ( & hir:: Pat {
210+ kind :
211+ hir:: PatKind :: Path ( QPath :: TypeRelative ( rcvr, segment) )
212+ | hir:: PatKind :: Struct ( QPath :: TypeRelative ( rcvr, segment) , ..)
213+ | hir:: PatKind :: TupleStruct ( QPath :: TypeRelative ( rcvr, segment) , ..) ,
214+ span,
215+ ..
216+ } ) => {
217+ let args = match self . tcx . parent_hir_node ( call_id) {
218+ hir:: Node :: Expr ( & hir:: Expr {
219+ kind : hir:: ExprKind :: Call ( callee, args) , ..
220+ } ) if callee. hir_id == call_id => Some ( args) ,
221+ _ => None ,
222+ } ;
223+ ( segment. ident . span , span, SelfSource :: QPath ( rcvr) , segment. ident , args)
224+ }
225+ node => unreachable ! ( "{node:?}" ) ,
226+ } ;
227+
201228 // Avoid suggestions when we don't know what's going on.
202229 if rcvr_ty. references_error ( ) {
203230 return None ;
204231 }
205232
206- let sugg_span = if let SelfSource :: MethodCall ( expr) = source {
207- // Given `foo.bar(baz)`, `expr` is `bar`, but we want to point to the whole thing.
208- self . tcx . hir ( ) . expect_expr ( self . tcx . parent_hir_id ( expr. hir_id ) ) . span
209- } else {
210- span
211- } ;
212-
213233 match error {
214234 MethodError :: NoMatch ( mut no_match_data) => {
215235 return self . report_no_match_method_error (
216236 span,
217- rcvr_opt,
218237 rcvr_ty,
219238 item_name,
220- expr_id ,
239+ call_id ,
221240 source,
222241 args,
223242 sugg_span,
@@ -362,7 +381,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
362381
363382 pub fn suggest_use_shadowed_binding_with_method (
364383 & self ,
365- rcvr_opt : Option < & ' tcx hir :: Expr < ' tcx > > ,
384+ self_source : SelfSource < ' tcx > ,
366385 method_name : Ident ,
367386 ty_str_reported : & str ,
368387 err : & mut Diag < ' _ > ,
@@ -502,7 +521,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
502521 }
503522 }
504523
505- if let Some ( rcvr) = rcvr_opt
524+ if let SelfSource :: MethodCall ( rcvr) = self_source
506525 && let hir:: ExprKind :: Path ( QPath :: Resolved ( _, path) ) = rcvr. kind
507526 && let hir:: def:: Res :: Local ( recv_id) = path. res
508527 && let Some ( segment) = path. segments . first ( )
@@ -548,7 +567,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
548567 pub fn report_no_match_method_error (
549568 & self ,
550569 mut span : Span ,
551- rcvr_opt : Option < & ' tcx hir:: Expr < ' tcx > > ,
552570 rcvr_ty : Ty < ' tcx > ,
553571 item_name : Ident ,
554572 expr_id : hir:: HirId ,
@@ -658,7 +676,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
658676
659677 if is_method {
660678 self . suggest_use_shadowed_binding_with_method (
661- rcvr_opt ,
679+ source ,
662680 item_name,
663681 & ty_str_reported,
664682 & mut err,
0 commit comments