@@ -50,15 +50,6 @@ use rustc_hir::intravisit::Visitor;
5050use  std:: cmp:: { self ,  Ordering } ; 
5151use  std:: iter; 
5252
53- /// After identifying that `full_expr` is a method call, we use this type to keep the expression's 
54- /// components readily available to us to point at the right place in diagnostics. 
55- #[ derive( Debug ,  Clone ,  Copy ) ]  
56- pub  struct  MethodCallComponents < ' tcx >  { 
57-  pub  receiver :  & ' tcx  hir:: Expr < ' tcx > , 
58-  pub  args :  & ' tcx  [ hir:: Expr < ' tcx > ] , 
59-  pub  full_expr :  & ' tcx  hir:: Expr < ' tcx > , 
60- } 
61- 
6253impl < ' a ,  ' tcx >  FnCtxt < ' a ,  ' tcx >  { 
6354 fn  is_fn_ty ( & self ,  ty :  Ty < ' tcx > ,  span :  Span )  -> bool  { 
6455 let  tcx = self . tcx ; 
@@ -124,7 +115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
124115 item_name :  Ident , 
125116 source :  SelfSource < ' tcx > , 
126117 error :  MethodError < ' tcx > , 
127-  args :  Option < MethodCallComponents < ' tcx > > , 
118+  args :  Option < & ' tcx   [ hir :: Expr < ' tcx > ] > , 
128119 expected :  Expectation < ' tcx > , 
129120 trait_missing_method :  bool , 
130121 )  -> Option < DiagnosticBuilder < ' _ ,  ErrorGuaranteed > >  { 
@@ -167,6 +158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
167158 self . note_candidates_on_method_error ( 
168159 rcvr_ty, 
169160 item_name, 
161+  source, 
170162 args, 
171163 span, 
172164 & mut  err, 
@@ -266,23 +258,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
266258 fn  suggest_missing_writer ( 
267259 & self , 
268260 rcvr_ty :  Ty < ' tcx > , 
269-  args :   MethodCallComponents < ' tcx > , 
261+  rcvr_expr :   & hir :: Expr < ' tcx > , 
270262 )  -> DiagnosticBuilder < ' _ ,  ErrorGuaranteed >  { 
271263 let  ( ty_str,  _ty_file)  = self . tcx . short_ty_string ( rcvr_ty) ; 
272264 let  mut  err = struct_span_err ! ( 
273265 self . tcx. sess, 
274-  args . receiver . span, 
266+  rcvr_expr . span, 
275267 E0599 , 
276268 "cannot write into `{}`" , 
277269 ty_str
278270 ) ; 
279271 err. span_note ( 
280-  args . receiver . span , 
272+  rcvr_expr . span , 
281273 "must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method" , 
282274 ) ; 
283-  if  let  ExprKind :: Lit ( _)  = args . receiver . kind  { 
275+  if  let  ExprKind :: Lit ( _)  = rcvr_expr . kind  { 
284276 err. span_help ( 
285-  args . receiver . span . shrink_to_lo ( ) , 
277+  rcvr_expr . span . shrink_to_lo ( ) , 
286278 "a writer is needed before this format string" , 
287279 ) ; 
288280 } ; 
@@ -296,7 +288,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
296288 rcvr_ty :  Ty < ' tcx > , 
297289 item_name :  Ident , 
298290 source :  SelfSource < ' tcx > , 
299-  args :  Option < MethodCallComponents < ' tcx > > , 
291+  args :  Option < & ' tcx   [ hir :: Expr < ' tcx > ] > , 
300292 sugg_span :  Span , 
301293 no_match_data :  & mut  NoMatchData < ' tcx > , 
302294 expected :  Expectation < ' tcx > , 
@@ -377,23 +369,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
377369 tcx. is_diagnostic_item ( sym:: write_macro,  def_id) 
378370 || tcx. is_diagnostic_item ( sym:: writeln_macro,  def_id) 
379371 } )  && item_name. name  == Symbol :: intern ( "write_fmt" ) ; 
380-  let  mut  err = if  is_write && let  Some ( args)  = args { 
381-  self . suggest_missing_writer ( rcvr_ty,  args) 
382-  }  else  { 
383-  tcx. sess . create_err ( NoAssociatedItem  { 
384-  span, 
385-  item_kind, 
386-  item_name, 
387-  ty_prefix :  if  trait_missing_method { 
388-  // FIXME(mu001999) E0599 maybe not suitable here because it is for types 
389-  Cow :: from ( "trait" ) 
390-  }  else  { 
391-  rcvr_ty. prefix_string ( self . tcx ) 
392-  } , 
393-  ty_str :  ty_str_reported, 
394-  trait_missing_method, 
395-  } ) 
396-  } ; 
372+  let  mut  err =
373+  if  is_write && let  SelfSource :: MethodCall ( rcvr_expr)  = source
374+  { 
375+  self . suggest_missing_writer ( rcvr_ty,  rcvr_expr) 
376+  }  else  { 
377+  tcx. sess . create_err ( NoAssociatedItem  { 
378+  span, 
379+  item_kind, 
380+  item_name, 
381+  ty_prefix :  if  trait_missing_method { 
382+  // FIXME(mu001999) E0599 maybe not suitable here because it is for types 
383+  Cow :: from ( "trait" ) 
384+  }  else  { 
385+  rcvr_ty. prefix_string ( self . tcx ) 
386+  } , 
387+  ty_str :  ty_str_reported, 
388+  trait_missing_method, 
389+  } ) 
390+  } ; 
397391 if  tcx. sess . source_map ( ) . is_multiline ( sugg_span)  { 
398392 err. span_label ( sugg_span. with_hi ( span. lo ( ) ) ,  "" ) ; 
399393 } 
@@ -409,7 +403,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
409403 err. downgrade_to_delayed_bug ( ) ; 
410404 } 
411405
412-  self . find_builder_fn ( & mut  err,  rcvr_ty,  source) ; 
406+  if  matches ! ( source,  SelfSource :: QPath ( _) )  && args. is_some ( )  { 
407+  self . find_builder_fn ( & mut  err,  rcvr_ty) ; 
408+  } 
409+ 
413410 if  tcx. ty_is_opaque_future ( rcvr_ty)  && item_name. name  == sym:: poll { 
414411 err. help ( format ! ( 
415412 "method `poll` found on `Pin<&mut {ty_str}>`, \  
@@ -523,6 +520,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
523520 self . note_candidates_on_method_error ( 
524521 rcvr_ty, 
525522 item_name, 
523+  source, 
526524 args, 
527525 span, 
528526 & mut  err, 
@@ -533,6 +531,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
533531 self . note_candidates_on_method_error ( 
534532 rcvr_ty, 
535533 item_name, 
534+  source, 
536535 args, 
537536 span, 
538537 & mut  err, 
@@ -976,7 +975,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
976975 unsatisfied_bounds = true ; 
977976 } 
978977 }  else  if  let  ty:: Adt ( def,  targs)  = rcvr_ty. kind ( ) 
979-  && let  Some ( args )  = args 
978+  && let  SelfSource :: MethodCall ( rcvr_expr )  = source 
980979 { 
981980 // This is useful for methods on arbitrary self types that might have a simple 
982981 // mutability difference, like calling a method on `Pin<&mut Self>` that is on 
@@ -999,8 +998,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
999998 rcvr_ty, 
1000999 & item_segment, 
10011000 span, 
1002-  args . full_expr , 
1003-  args . receiver , 
1001+  tcx . hir ( ) . get_parent ( rcvr_expr . hir_id ) . expect_expr ( ) , 
1002+  rcvr_expr , 
10041003 )  { 
10051004 err. span_note ( 
10061005 tcx. def_span ( method. def_id ) , 
@@ -1169,7 +1168,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11691168 span, 
11701169 rcvr_ty, 
11711170 item_name, 
1172-  args. map ( |MethodCallComponents   {   args,  ..  } | args. len ( )  + 1 ) , 
1171+  args. map ( |args| args. len ( )  + 1 ) , 
11731172 source, 
11741173 no_match_data. out_of_scope_traits . clone ( ) , 
11751174 & unsatisfied_predicates, 
@@ -1250,7 +1249,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12501249 & self , 
12511250 rcvr_ty :  Ty < ' tcx > , 
12521251 item_name :  Ident , 
1253-  args :  Option < MethodCallComponents < ' tcx > > , 
1252+  self_source :  SelfSource < ' tcx > , 
1253+  args :  Option < & ' tcx  [ hir:: Expr < ' tcx > ] > , 
12541254 span :  Span , 
12551255 err :  & mut  Diagnostic , 
12561256 sources :  & mut  Vec < CandidateSource > , 
@@ -1339,6 +1339,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13391339 if  let  Some ( sugg)  = print_disambiguation_help ( 
13401340 item_name, 
13411341 args, 
1342+  self_source, 
13421343 err, 
13431344 path, 
13441345 ty, 
@@ -1378,6 +1379,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13781379 if  let  Some ( sugg)  = print_disambiguation_help ( 
13791380 item_name, 
13801381 args, 
1382+  self_source, 
13811383 err, 
13821384 path, 
13831385 rcvr_ty, 
@@ -1410,18 +1412,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14101412
14111413 /// Look at all the associated functions without receivers in the type's inherent impls 
14121414/// to look for builders that return `Self`, `Option<Self>` or `Result<Self, _>`. 
1413- fn  find_builder_fn ( & self ,  err :  & mut  Diagnostic ,  rcvr_ty :  Ty < ' tcx > ,   source :   SelfSource < ' tcx > )  { 
1415+ fn  find_builder_fn ( & self ,  err :  & mut  Diagnostic ,  rcvr_ty :  Ty < ' tcx > )  { 
14141416 let  ty:: Adt ( adt_def,  _)  = rcvr_ty. kind ( )  else  { 
14151417 return ; 
14161418 } ; 
1417-  let  SelfSource :: QPath ( ty)  = source else  { 
1418-  return ; 
1419-  } ; 
1420-  let  hir = self . tcx . hir ( ) ; 
1421-  if  let  Some ( Node :: Pat ( _) )  = hir. find ( hir. parent_id ( ty. hir_id ) )  { 
1422-  // Do not suggest a fn call when a pattern is expected. 
1423-  return ; 
1424-  } 
14251419 let  mut  items = self 
14261420 . tcx 
14271421 . inherent_impls ( adt_def. did ( ) ) 
@@ -1504,7 +1498,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15041498 rcvr_ty :  Ty < ' tcx > , 
15051499 source :  SelfSource < ' tcx > , 
15061500 item_name :  Ident , 
1507-  args :  Option < MethodCallComponents < ' tcx > > , 
1501+  args :  Option < & ' tcx   [ hir :: Expr < ' tcx > ] > , 
15081502 sugg_span :  Span , 
15091503 )  { 
15101504 let  mut  has_unsuggestable_args = false ; 
@@ -1578,38 +1572,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15781572 None 
15791573 } ; 
15801574 let  mut  applicability = Applicability :: MachineApplicable ; 
1581-  let  args = if  let  Some ( MethodCallComponents  {  receiver,  args,  .. } )  = args { 
1582-  // The first arg is the same kind as the receiver 
1583-  let  explicit_args = if  first_arg. is_some ( )  { 
1584-  std:: iter:: once ( receiver) . chain ( args. iter ( ) ) . collect :: < Vec < _ > > ( ) 
1575+  let  args = if  let  SelfSource :: MethodCall ( receiver)  = source
1576+  && let  Some ( args)  = args
1577+  { 
1578+  // The first arg is the same kind as the receiver 
1579+  let  explicit_args = if  first_arg. is_some ( )  { 
1580+  std:: iter:: once ( receiver) . chain ( args. iter ( ) ) . collect :: < Vec < _ > > ( ) 
1581+  }  else  { 
1582+  // There is no `Self` kind to infer the arguments from 
1583+  if  has_unsuggestable_args { 
1584+  applicability = Applicability :: HasPlaceholders ; 
1585+  } 
1586+  args. iter ( ) . collect ( ) 
1587+  } ; 
1588+  format ! ( 
1589+  "({}{})" , 
1590+  first_arg. unwrap_or( "" ) , 
1591+  explicit_args
1592+  . iter( ) 
1593+  . map( |arg| self 
1594+  . tcx
1595+  . sess
1596+  . source_map( ) 
1597+  . span_to_snippet( arg. span) 
1598+  . unwrap_or_else( |_| { 
1599+  applicability = Applicability :: HasPlaceholders ; 
1600+  "_" . to_owned( ) 
1601+  } ) ) 
1602+  . collect:: <Vec <_>>( ) 
1603+  . join( ", " ) , 
1604+  ) 
15851605 }  else  { 
1586-  // There is no `Self` kind to infer the arguments from 
1587-  if  has_unsuggestable_args { 
1588-  applicability = Applicability :: HasPlaceholders ; 
1589-  } 
1590-  args. iter ( ) . collect ( ) 
1606+  applicability = Applicability :: HasPlaceholders ; 
1607+  "(...)" . to_owned ( ) 
15911608 } ; 
1592-  format ! ( 
1593-  "({}{})" , 
1594-  first_arg. unwrap_or( "" ) , 
1595-  explicit_args
1596-  . iter( ) 
1597-  . map( |arg| self 
1598-  . tcx
1599-  . sess
1600-  . source_map( ) 
1601-  . span_to_snippet( arg. span) 
1602-  . unwrap_or_else( |_| { 
1603-  applicability = Applicability :: HasPlaceholders ; 
1604-  "_" . to_owned( ) 
1605-  } ) ) 
1606-  . collect:: <Vec <_>>( ) 
1607-  . join( ", " ) , 
1608-  ) 
1609-  }  else  { 
1610-  applicability = Applicability :: HasPlaceholders ; 
1611-  "(...)" . to_owned ( ) 
1612-  } ; 
16131609 err. span_suggestion ( 
16141610 sugg_span, 
16151611 "use associated function syntax instead" , 
@@ -3268,7 +3264,8 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
32683264
32693265fn  print_disambiguation_help < ' tcx > ( 
32703266 item_name :  Ident , 
3271-  args :  Option < MethodCallComponents < ' tcx > > , 
3267+  args :  Option < & ' tcx  [ hir:: Expr < ' tcx > ] > , 
3268+  source :  SelfSource < ' tcx > , 
32723269 err :  & mut  Diagnostic , 
32733270 trait_name :  String , 
32743271 rcvr_ty :  Ty < ' _ > , 
@@ -3281,7 +3278,9 @@ fn print_disambiguation_help<'tcx>(
32813278 fn_has_self_parameter :  bool , 
32823279)  -> Option < String >  { 
32833280 Some ( 
3284-  if  let  ( ty:: AssocKind :: Fn ,  Some ( MethodCallComponents  {  receiver,  args,  .. } ) )  = ( kind,  args) 
3281+  if  matches ! ( kind,  ty:: AssocKind :: Fn ) 
3282+  && let  SelfSource :: MethodCall ( receiver)  = source
3283+  && let  Some ( args)  = args
32853284 { 
32863285 let  args = format ! ( 
32873286 "({}{})" , 
0 commit comments