11use  crate :: FnCtxt ; 
22use  rustc_ast:: util:: parser:: PREC_POSTFIX ; 
3- use  rustc_data_structures:: fx:: FxHashMap ; 
43use  rustc_errors:: MultiSpan ; 
54use  rustc_errors:: { Applicability ,  Diagnostic ,  DiagnosticBuilder ,  ErrorGuaranteed } ; 
65use  rustc_hir as  hir; 
76use  rustc_hir:: def:: CtorKind ; 
8- use  rustc_hir:: intravisit:: Visitor ; 
97use  rustc_hir:: lang_items:: LangItem ; 
108use  rustc_hir:: { is_range_literal,  Node } ; 
119use  rustc_infer:: infer:: InferOk ; 
1210use  rustc_middle:: lint:: in_external_macro; 
1311use  rustc_middle:: middle:: stability:: EvalResult ; 
1412use  rustc_middle:: ty:: adjustment:: AllowTwoPhase ; 
1513use  rustc_middle:: ty:: error:: { ExpectedFound ,  TypeError } ; 
16- use  rustc_middle:: ty:: fold:: { BottomUpFolder ,  TypeFolder } ; 
17- use  rustc_middle:: ty:: print:: { with_forced_trimmed_paths,  with_no_trimmed_paths} ; 
18- use  rustc_middle:: ty:: relate:: TypeRelation ; 
19- use  rustc_middle:: ty:: { self ,  Article ,  AssocItem ,  Ty ,  TypeAndMut ,  TypeVisitable } ; 
14+ use  rustc_middle:: ty:: print:: with_no_trimmed_paths; 
15+ use  rustc_middle:: ty:: { self ,  Article ,  AssocItem ,  Ty ,  TypeAndMut } ; 
2016use  rustc_span:: symbol:: { sym,  Symbol } ; 
2117use  rustc_span:: { BytePos ,  Span } ; 
2218use  rustc_trait_selection:: infer:: InferCtxtExt  as  _; 
23- use  rustc_trait_selection:: traits:: error_reporting:: method_chain:: CollectAllMismatches ; 
2419use  rustc_trait_selection:: traits:: ObligationCause ; 
2520
2621use  super :: method:: probe; 
@@ -45,7 +40,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4540        self . annotate_alternative_method_deref ( err,  expr,  error) ; 
4641
4742        // Use `||` to give these suggestions a precedence 
48-         let  suggested  = self . suggest_missing_parentheses ( err,  expr) 
43+         let  _  = self . suggest_missing_parentheses ( err,  expr) 
4944            || self . suggest_remove_last_method_call ( err,  expr,  expected) 
5045            || self . suggest_associated_const ( err,  expr,  expected) 
5146            || self . suggest_deref_ref_or_into ( err,  expr,  expected,  expr_ty,  expected_ty_expr) 
@@ -60,9 +55,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6055            || self . suggest_clone_for_ref ( err,  expr,  expr_ty,  expected) 
6156            || self . suggest_into ( err,  expr,  expr_ty,  expected) 
6257            || self . suggest_floating_point_literal ( err,  expr,  expected) ; 
63-         if  !suggested { 
64-             self . point_at_expr_source_of_inferred_type ( err,  expr,  expr_ty,  expected) ; 
65-         } 
6658    } 
6759
6860    pub  fn  emit_coerce_suggestions ( 
@@ -216,216 +208,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
216208        ( expected,  Some ( err) ) 
217209    } 
218210
219-     pub  fn  point_at_expr_source_of_inferred_type ( 
220-         & self , 
221-         err :  & mut  Diagnostic , 
222-         expr :  & hir:: Expr < ' _ > , 
223-         found :  Ty < ' tcx > , 
224-         expected :  Ty < ' tcx > , 
225-     )  -> bool  { 
226-         let  map = self . tcx . hir ( ) ; 
227- 
228-         let  hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None ,  p) )  = expr. kind  else  {  return  false ;  } ; 
229-         let  [ hir:: PathSegment  {  ident,  args :  None ,  .. } ]  = p. segments  else  {  return  false ;  } ; 
230-         let  hir:: def:: Res :: Local ( hir_id)  = p. res  else  {  return  false ;  } ; 
231-         let  Some ( hir:: Node :: Pat ( pat) )  = map. find ( hir_id)  else  {  return  false ;  } ; 
232-         let  Some ( hir:: Node :: Local ( hir:: Local  { 
233-             ty :  None , 
234-             init :  Some ( init) , 
235-             ..
236-         } ) )  = map. find_parent ( pat. hir_id )  else  {  return  false ;  } ; 
237-         let  Some ( ty)  = self . node_ty_opt ( init. hir_id )  else  {  return  false ;  } ; 
238-         if  ty. is_closure ( )  || init. span . overlaps ( expr. span )  || pat. span . from_expansion ( )  { 
239-             return  false ; 
240-         } 
241- 
242-         // Locate all the usages of the relevant binding. 
243-         struct  FindExprs < ' hir >  { 
244-             hir_id :  hir:: HirId , 
245-             uses :  Vec < & ' hir  hir:: Expr < ' hir > > , 
246-         } 
247-         impl < ' v >  Visitor < ' v >  for  FindExprs < ' v >  { 
248-             fn  visit_expr ( & mut  self ,  ex :  & ' v  hir:: Expr < ' v > )  { 
249-                 if  let  hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( None ,  path) )  = ex. kind 
250-                     && let  hir:: def:: Res :: Local ( hir_id)  = path. res 
251-                     && hir_id == self . hir_id 
252-                 { 
253-                     self . uses . push ( ex) ; 
254-                 } 
255-                 hir:: intravisit:: walk_expr ( self ,  ex) ; 
256-             } 
257-         } 
258- 
259-         let  mut  expr_finder = FindExprs  {  hir_id,  uses :  vec ! [ ]  } ; 
260-         let  id = map. get_parent_item ( hir_id) ; 
261-         let  hir_id:  hir:: HirId  = id. into ( ) ; 
262- 
263-         let  Some ( node)  = map. find ( hir_id)  else  {  return  false ;  } ; 
264-         let  Some ( body_id)  = node. body_id ( )  else  {  return  false ;  } ; 
265-         let  body = map. body ( body_id) ; 
266-         expr_finder. visit_expr ( body. value ) ; 
267-         // Hack to make equality checks on types with inference variables and regions useful. 
268-         let  mut  eraser = BottomUpFolder  { 
269-             tcx :  self . tcx , 
270-             lt_op :  |_| self . tcx . lifetimes . re_erased , 
271-             ct_op :  |c| c, 
272-             ty_op :  |t| match  * t. kind ( )  { 
273-                 ty:: Infer ( ty:: TyVar ( vid) )  => self . tcx . mk_ty_infer ( ty:: TyVar ( self . root_var ( vid) ) ) , 
274-                 ty:: Infer ( ty:: IntVar ( _) )  => { 
275-                     self . tcx . mk_ty_infer ( ty:: IntVar ( ty:: IntVid  {  index :  0  } ) ) 
276-                 } 
277-                 ty:: Infer ( ty:: FloatVar ( _) )  => { 
278-                     self . tcx . mk_ty_infer ( ty:: FloatVar ( ty:: FloatVid  {  index :  0  } ) ) 
279-                 } 
280-                 _ => t, 
281-             } , 
282-         } ; 
283-         let  mut  prev = eraser. fold_ty ( ty) ; 
284-         let  mut  prev_span = None ; 
285- 
286-         for  binding in  expr_finder. uses  { 
287-             // In every expression where the binding is referenced, we will look at that 
288-             // expression's type and see if it is where the incorrect found type was fully 
289-             // "materialized" and point at it. We will also try to provide a suggestion there. 
290-             if  let  Some ( hir:: Node :: Expr ( expr) 
291-             | hir:: Node :: Stmt ( hir:: Stmt  { 
292-                 kind :  hir:: StmtKind :: Expr ( expr)  | hir:: StmtKind :: Semi ( expr) , 
293-                 ..
294-             } ) )  = & map. find_parent ( binding. hir_id ) 
295-                 && let  hir:: ExprKind :: MethodCall ( segment,  rcvr,  args,  _span)  = expr. kind 
296-                 && rcvr. hir_id  == binding. hir_id 
297-                 && let  Some ( def_id)  = self . typeck_results . borrow ( ) . type_dependent_def_id ( expr. hir_id ) 
298-             { 
299-                 // We special case methods, because they can influence inference through the 
300-                 // call's arguments and we can provide a more explicit span. 
301-                 let  sig = self . tcx . fn_sig ( def_id) ; 
302-                 let  def_self_ty = sig. input ( 0 ) . skip_binder ( ) ; 
303-                 let  rcvr_ty = self . node_ty ( rcvr. hir_id ) ; 
304-                 // Get the evaluated type *after* calling the method call, so that the influence 
305-                 // of the arguments can be reflected in the receiver type. The receiver 
306-                 // expression has the type *before* theis analysis is done. 
307-                 let  ty = match  self . lookup_probe_for_diagnostic ( 
308-                     segment. ident , 
309-                     rcvr_ty, 
310-                     expr, 
311-                     probe:: ProbeScope :: TraitsInScope , 
312-                     None , 
313-                 )  { 
314-                     Ok ( pick)  => pick. self_ty , 
315-                     Err ( _)  => rcvr_ty, 
316-                 } ; 
317-                 // Remove one layer of references to account for `&mut self` and 
318-                 // `&self`, so that we can compare it against the binding. 
319-                 let  ( ty,  def_self_ty)  = match  ( ty. kind ( ) ,  def_self_ty. kind ( ) )  { 
320-                     ( ty:: Ref ( _,  ty,  a) ,  ty:: Ref ( _,  self_ty,  b) )  if  a == b => ( * ty,  * self_ty) , 
321-                     _ => ( ty,  def_self_ty) , 
322-                 } ; 
323-                 let  mut  param_args = FxHashMap :: default ( ) ; 
324-                 let  mut  param_expected = FxHashMap :: default ( ) ; 
325-                 let  mut  param_found = FxHashMap :: default ( ) ; 
326-                 if  self . can_eq ( self . param_env ,  ty,  found) . is_ok ( )  { 
327-                     // We only point at the first place where the found type was inferred. 
328-                     for  ( i,  param_ty)  in  sig. inputs ( ) . skip_binder ( ) . iter ( ) . skip ( 1 ) . enumerate ( )  { 
329-                         if  def_self_ty. contains ( * param_ty)  && let  ty:: Param ( _)  = param_ty. kind ( )  { 
330-                             // We found an argument that references a type parameter in `Self`, 
331-                             // so we assume that this is the argument that caused the found 
332-                             // type, which we know already because of `can_eq` above was first 
333-                             // inferred in this method call. 
334-                             let  arg = & args[ i] ; 
335-                             let  arg_ty = self . node_ty ( arg. hir_id ) ; 
336-                             err. span_label ( 
337-                                 arg. span , 
338-                                 & format ! ( 
339-                                     "this is of type `{arg_ty}`, which causes `{ident}` to be \  
340- , 
341-                                 ) , 
342-                             ) ; 
343-                             param_args. insert ( param_ty,  ( arg,  arg_ty) ) ; 
344-                         } 
345-                     } 
346-                 } 
347- 
348-                 // Here we find, for a type param `T`, the type that `T` is in the current 
349-                 // method call *and* in the original expected type. That way, we can see if we 
350-                 // can give any structured suggestion for the function argument. 
351-                 let  mut  c = CollectAllMismatches  { 
352-                     infcx :  & self . infcx , 
353-                     param_env :  self . param_env , 
354-                     errors :  vec ! [ ] , 
355-                 } ; 
356-                 let  _ = c. relate ( def_self_ty,  ty) ; 
357-                 for  error in  c. errors  { 
358-                     if  let  TypeError :: Sorts ( error)  = error { 
359-                         param_found. insert ( error. expected ,  error. found ) ; 
360-                     } 
361-                 } 
362-                 c. errors  = vec ! [ ] ; 
363-                 let  _ = c. relate ( def_self_ty,  expected) ; 
364-                 for  error in  c. errors  { 
365-                     if  let  TypeError :: Sorts ( error)  = error { 
366-                         param_expected. insert ( error. expected ,  error. found ) ; 
367-                     } 
368-                 } 
369-                 for  ( param,  ( arg,  arg_ty) )  in  param_args. iter ( )  { 
370-                     let  Some ( expected)  = param_expected. get ( param)  else  {  continue ;  } ; 
371-                     let  Some ( found)  = param_found. get ( param)  else  {  continue ;  } ; 
372-                     if  self . can_eq ( self . param_env ,  * arg_ty,  * found) . is_err ( )  {  continue ;  } 
373-                     self . emit_coerce_suggestions ( err,  arg,  * found,  * expected,  None ,  None ) ; 
374-                 } 
375- 
376-                 let  ty = eraser. fold_ty ( ty) ; 
377-                 if  ty. references_error ( )  { 
378-                     break ; 
379-                 } 
380-                 if  ty != prev
381-                     && param_args. is_empty ( ) 
382-                     && self . can_eq ( self . param_env ,  ty,  found) . is_ok ( ) 
383-                 { 
384-                     // We only point at the first place where the found type was inferred. 
385-                     err. span_label ( 
386-                         segment. ident . span , 
387-                         with_forced_trimmed_paths ! ( format!( 
388-                             "here the type of `{ident}` is inferred to be `{ty}`" , 
389-                         ) ) , 
390-                     ) ; 
391-                     break ; 
392-                 }  else  if  !param_args. is_empty ( )  { 
393-                     break ; 
394-                 } 
395-                 prev = ty; 
396-             }  else  { 
397-                 let  ty = eraser. fold_ty ( self . node_ty ( binding. hir_id ) ) ; 
398-                 if  ty. references_error ( )  { 
399-                     break ; 
400-                 } 
401-                 if  ty != prev
402-                     && let  Some ( span)  = prev_span
403-                     && self . can_eq ( self . param_env ,  ty,  found) . is_ok ( ) 
404-                 { 
405-                     // We only point at the first place where the found type was inferred. 
406-                     // We use the *previous* span because if the type is known *here* it means 
407-                     // it was *evaluated earlier*. We don't do this for method calls because we 
408-                     // evaluate the method's self type eagerly, but not in any other case. 
409-                     err. span_label ( 
410-                         span, 
411-                         with_forced_trimmed_paths ! ( format!( 
412-                             "here the type of `{ident}` is inferred to be `{ty}`" , 
413-                         ) ) , 
414-                     ) ; 
415-                     break ; 
416-                 } 
417-                 prev = ty; 
418-             } 
419-             if  binding. hir_id  == expr. hir_id  { 
420-                 // Do not look at expressions that come after the expression we were originally 
421-                 // evaluating and had a type error. 
422-                 break ; 
423-             } 
424-             prev_span = Some ( binding. span ) ; 
425-         } 
426-         true 
427-     } 
428- 
429211    fn  annotate_expected_due_to_let_ty ( 
430212        & self , 
431213        err :  & mut  Diagnostic , 
0 commit comments