]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
drive-by: Fix path spans
[rust.git] / compiler / rustc_infer / src / infer / error_reporting / need_type_info.rs
1 use crate::errors::{
2     AmbigousImpl, AmbigousReturn, AnnotationRequired, InferenceBadError, NeedTypeInfoInGenerator,
3     SourceKindMultiSuggestion, SourceKindSubdiag,
4 };
5 use crate::infer::error_reporting::TypeErrCtxt;
6 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
7 use crate::infer::InferCtxt;
8 use rustc_errors::IntoDiagnostic;
9 use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, IntoDiagnosticArg};
10 use rustc_hir as hir;
11 use rustc_hir::def::Res;
12 use rustc_hir::def::{CtorOf, DefKind, Namespace};
13 use rustc_hir::def_id::DefId;
14 use rustc_hir::intravisit::{self, Visitor};
15 use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource};
16 use rustc_middle::hir::nested_filter;
17 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
18 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
19 use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
20 use rustc_middle::ty::{self, DefIdTree, InferConst};
21 use rustc_middle::ty::{GenericArg, GenericArgKind, SubstsRef};
22 use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults};
23 use rustc_span::symbol::{kw, sym, Ident};
24 use rustc_span::{BytePos, Span};
25 use std::borrow::Cow;
26 use std::iter;
27
28 pub enum TypeAnnotationNeeded {
29     /// ```compile_fail,E0282
30     /// let x = "hello".chars().rev().collect();
31     /// ```
32     E0282,
33     /// An implementation cannot be chosen unambiguously because of lack of information.
34     /// ```compile_fail,E0283
35     /// let _ = Default::default();
36     /// ```
37     E0283,
38     /// ```compile_fail,E0284
39     /// let mut d: u64 = 2;
40     /// d = d % 1u32.into();
41     /// ```
42     E0284,
43 }
44
45 impl Into<rustc_errors::DiagnosticId> for TypeAnnotationNeeded {
46     fn into(self) -> rustc_errors::DiagnosticId {
47         match self {
48             Self::E0282 => rustc_errors::error_code!(E0282),
49             Self::E0283 => rustc_errors::error_code!(E0283),
50             Self::E0284 => rustc_errors::error_code!(E0284),
51         }
52     }
53 }
54
55 /// Information about a constant or a type containing inference variables.
56 pub struct InferenceDiagnosticsData {
57     pub name: String,
58     pub span: Option<Span>,
59     pub kind: UnderspecifiedArgKind,
60     pub parent: Option<InferenceDiagnosticsParentData>,
61 }
62
63 /// Data on the parent definition where a generic argument was declared.
64 pub struct InferenceDiagnosticsParentData {
65     prefix: &'static str,
66     name: String,
67 }
68
69 #[derive(Clone)]
70 pub enum UnderspecifiedArgKind {
71     Type { prefix: Cow<'static, str> },
72     Const { is_parameter: bool },
73 }
74
75 impl InferenceDiagnosticsData {
76     fn can_add_more_info(&self) -> bool {
77         !(self.name == "_" && matches!(self.kind, UnderspecifiedArgKind::Type { .. }))
78     }
79
80     fn where_x_is_kind(&self, in_type: Ty<'_>) -> &'static str {
81         if in_type.is_ty_infer() {
82             ""
83         } else if self.name == "_" {
84             // FIXME: Consider specializing this message if there is a single `_`
85             // in the type.
86             "underscore"
87         } else {
88             "has_name"
89         }
90     }
91
92     /// Generate a label for a generic argument which can't be inferred. When not
93     /// much is known about the argument, `use_diag` may be used to describe the
94     /// labeled value.
95     fn make_bad_error(&self, span: Span) -> InferenceBadError<'_> {
96         let has_parent = self.parent.is_some();
97         let bad_kind = if self.can_add_more_info() { "more_info" } else { "other" };
98         let (parent_prefix, parent_name) = self
99             .parent
100             .as_ref()
101             .map(|parent| (parent.prefix, parent.name.clone()))
102             .unwrap_or_default();
103         InferenceBadError {
104             span,
105             bad_kind,
106             prefix_kind: self.kind.clone(),
107             prefix: self.kind.try_get_prefix().unwrap_or_default(),
108             name: self.name.clone(),
109             has_parent,
110             parent_prefix,
111             parent_name,
112         }
113     }
114 }
115
116 impl InferenceDiagnosticsParentData {
117     fn for_parent_def_id(
118         tcx: TyCtxt<'_>,
119         parent_def_id: DefId,
120     ) -> Option<InferenceDiagnosticsParentData> {
121         let parent_name =
122             tcx.def_key(parent_def_id).disambiguated_data.data.get_opt_name()?.to_string();
123
124         Some(InferenceDiagnosticsParentData {
125             prefix: tcx.def_kind(parent_def_id).descr(parent_def_id),
126             name: parent_name,
127         })
128     }
129
130     fn for_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option<InferenceDiagnosticsParentData> {
131         Self::for_parent_def_id(tcx, tcx.parent(def_id))
132     }
133 }
134
135 impl IntoDiagnosticArg for UnderspecifiedArgKind {
136     fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
137         let kind = match self {
138             Self::Type { .. } => "type",
139             Self::Const { is_parameter: true } => "const_with_param",
140             Self::Const { is_parameter: false } => "const",
141         };
142         rustc_errors::DiagnosticArgValue::Str(kind.into())
143     }
144 }
145
146 impl UnderspecifiedArgKind {
147     fn try_get_prefix(&self) -> Option<&str> {
148         match self {
149             Self::Type { prefix } => Some(prefix.as_ref()),
150             Self::Const { .. } => None,
151         }
152     }
153 }
154
155 fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> {
156     let mut printer = FmtPrinter::new(infcx.tcx, ns);
157     let ty_getter = move |ty_vid| {
158         if infcx.probe_ty_var(ty_vid).is_ok() {
159             warn!("resolved ty var in error message");
160         }
161         if let TypeVariableOriginKind::TypeParameterDefinition(name, _) =
162             infcx.inner.borrow_mut().type_variables().var_origin(ty_vid).kind
163         {
164             Some(name)
165         } else {
166             None
167         }
168     };
169     printer.ty_infer_name_resolver = Some(Box::new(ty_getter));
170     let const_getter = move |ct_vid| {
171         if infcx.probe_const_var(ct_vid).is_ok() {
172             warn!("resolved const var in error message");
173         }
174         if let ConstVariableOriginKind::ConstParameterDefinition(name, _) =
175             infcx.inner.borrow_mut().const_unification_table().probe_value(ct_vid).origin.kind
176         {
177             return Some(name);
178         } else {
179             None
180         }
181     };
182     printer.const_infer_name_resolver = Some(Box::new(const_getter));
183     printer
184 }
185
186 fn ty_to_string<'tcx>(
187     infcx: &InferCtxt<'tcx>,
188     ty: Ty<'tcx>,
189     called_method_def_id: Option<DefId>,
190 ) -> String {
191     let printer = fmt_printer(infcx, Namespace::TypeNS);
192     let ty = infcx.resolve_vars_if_possible(ty);
193     match (ty.kind(), called_method_def_id) {
194         // We don't want the regular output for `fn`s because it includes its path in
195         // invalid pseudo-syntax, we want the `fn`-pointer output instead.
196         (ty::FnDef(..), _) => ty.fn_sig(infcx.tcx).print(printer).unwrap().into_buffer(),
197         (_, Some(def_id))
198             if ty.is_ty_infer()
199                 && infcx.tcx.get_diagnostic_item(sym::iterator_collect_fn) == Some(def_id) =>
200         {
201             "Vec<_>".to_string()
202         }
203         _ if ty.is_ty_infer() => "/* Type */".to_string(),
204         // FIXME: The same thing for closures, but this only works when the closure
205         // does not capture anything.
206         //
207         // We do have to hide the `extern "rust-call"` ABI in that case though,
208         // which is too much of a bother for now.
209         _ => ty.print(printer).unwrap().into_buffer(),
210     }
211 }
212
213 /// We don't want to directly use `ty_to_string` for closures as their type isn't really
214 /// something users are familiar with. Directly printing the `fn_sig` of closures also
215 /// doesn't work as they actually use the "rust-call" API.
216 fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String {
217     let ty::Closure(_, substs) = ty.kind() else { unreachable!() };
218     let fn_sig = substs.as_closure().sig();
219     let args = fn_sig
220         .inputs()
221         .skip_binder()
222         .iter()
223         .next()
224         .map(|args| {
225             args.tuple_fields()
226                 .iter()
227                 .map(|arg| ty_to_string(infcx, arg, None))
228                 .collect::<Vec<_>>()
229                 .join(", ")
230         })
231         .unwrap_or_default();
232     let ret = if fn_sig.output().skip_binder().is_unit() {
233         String::new()
234     } else {
235         format!(" -> {}", ty_to_string(infcx, fn_sig.output().skip_binder(), None))
236     };
237     format!("fn({}){}", args, ret)
238 }
239
240 impl<'tcx> InferCtxt<'tcx> {
241     /// Extracts data used by diagnostic for either types or constants
242     /// which were stuck during inference.
243     pub fn extract_inference_diagnostics_data(
244         &self,
245         arg: GenericArg<'tcx>,
246         highlight: Option<ty::print::RegionHighlightMode<'tcx>>,
247     ) -> InferenceDiagnosticsData {
248         match arg.unpack() {
249             GenericArgKind::Type(ty) => {
250                 if let ty::Infer(ty::TyVar(ty_vid)) = *ty.kind() {
251                     let mut inner = self.inner.borrow_mut();
252                     let ty_vars = &inner.type_variables();
253                     let var_origin = ty_vars.var_origin(ty_vid);
254                     if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) =
255                         var_origin.kind
256                     {
257                         if name != kw::SelfUpper {
258                             return InferenceDiagnosticsData {
259                                 name: name.to_string(),
260                                 span: Some(var_origin.span),
261                                 kind: UnderspecifiedArgKind::Type {
262                                     prefix: "type parameter".into(),
263                                 },
264                                 parent: def_id.and_then(|def_id| {
265                                     InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id)
266                                 }),
267                             };
268                         }
269                     }
270                 }
271
272                 let mut printer = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS);
273                 if let Some(highlight) = highlight {
274                     printer.region_highlight_mode = highlight;
275                 }
276                 InferenceDiagnosticsData {
277                     name: ty.print(printer).unwrap().into_buffer(),
278                     span: None,
279                     kind: UnderspecifiedArgKind::Type { prefix: ty.prefix_string(self.tcx) },
280                     parent: None,
281                 }
282             }
283             GenericArgKind::Const(ct) => {
284                 if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.kind() {
285                     let origin =
286                         self.inner.borrow_mut().const_unification_table().probe_value(vid).origin;
287                     if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) =
288                         origin.kind
289                     {
290                         return InferenceDiagnosticsData {
291                             name: name.to_string(),
292                             span: Some(origin.span),
293                             kind: UnderspecifiedArgKind::Const { is_parameter: true },
294                             parent: InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id),
295                         };
296                     }
297
298                     debug_assert!(!origin.span.is_dummy());
299                     let mut printer = ty::print::FmtPrinter::new(self.tcx, Namespace::ValueNS);
300                     if let Some(highlight) = highlight {
301                         printer.region_highlight_mode = highlight;
302                     }
303                     InferenceDiagnosticsData {
304                         name: ct.print(printer).unwrap().into_buffer(),
305                         span: Some(origin.span),
306                         kind: UnderspecifiedArgKind::Const { is_parameter: false },
307                         parent: None,
308                     }
309                 } else {
310                     // If we end up here the `FindInferSourceVisitor`
311                     // won't work, as its expected argument isn't an inference variable.
312                     //
313                     // FIXME: Ideally we should look into the generic constant
314                     // to figure out which inference var is actually unresolved so that
315                     // this path is unreachable.
316                     let mut printer = ty::print::FmtPrinter::new(self.tcx, Namespace::ValueNS);
317                     if let Some(highlight) = highlight {
318                         printer.region_highlight_mode = highlight;
319                     }
320                     InferenceDiagnosticsData {
321                         name: ct.print(printer).unwrap().into_buffer(),
322                         span: None,
323                         kind: UnderspecifiedArgKind::Const { is_parameter: false },
324                         parent: None,
325                     }
326                 }
327             }
328             GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
329         }
330     }
331
332     /// Used as a fallback in [TypeErrCtxt::emit_inference_failure_err]
333     /// in case we weren't able to get a better error.
334     fn bad_inference_failure_err(
335         &self,
336         span: Span,
337         arg_data: InferenceDiagnosticsData,
338         error_code: TypeAnnotationNeeded,
339     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
340         let source_kind = "other";
341         let source_name = "";
342         let failure_span = None;
343         let infer_subdiags = Vec::new();
344         let multi_suggestions = Vec::new();
345         let bad_label = Some(arg_data.make_bad_error(span));
346         match error_code {
347             TypeAnnotationNeeded::E0282 => AnnotationRequired {
348                 span,
349                 source_kind,
350                 source_name,
351                 failure_span,
352                 infer_subdiags,
353                 multi_suggestions,
354                 bad_label,
355             }
356             .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
357             TypeAnnotationNeeded::E0283 => AmbigousImpl {
358                 span,
359                 source_kind,
360                 source_name,
361                 failure_span,
362                 infer_subdiags,
363                 multi_suggestions,
364                 bad_label,
365             }
366             .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
367             TypeAnnotationNeeded::E0284 => AmbigousReturn {
368                 span,
369                 source_kind,
370                 source_name,
371                 failure_span,
372                 infer_subdiags,
373                 multi_suggestions,
374                 bad_label,
375             }
376             .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
377         }
378     }
379 }
380
381 impl<'tcx> TypeErrCtxt<'_, 'tcx> {
382     #[instrument(level = "debug", skip(self, error_code))]
383     pub fn emit_inference_failure_err(
384         &self,
385         body_id: Option<hir::BodyId>,
386         failure_span: Span,
387         arg: GenericArg<'tcx>,
388         error_code: TypeAnnotationNeeded,
389         should_label_span: bool,
390     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
391         let arg = self.resolve_vars_if_possible(arg);
392         let arg_data = self.extract_inference_diagnostics_data(arg, None);
393
394         let Some(typeck_results) = &self.typeck_results else {
395             // If we don't have any typeck results we're outside
396             // of a body, so we won't be able to get better info
397             // here.
398             return self.bad_inference_failure_err(failure_span, arg_data, error_code);
399         };
400
401         let mut local_visitor = FindInferSourceVisitor::new(&self, typeck_results, arg);
402         if let Some(body_id) = body_id {
403             let expr = self.tcx.hir().expect_expr(body_id.hir_id);
404             local_visitor.visit_expr(expr);
405         }
406
407         let Some(InferSource { span, kind }) = local_visitor.infer_source else {
408             return self.bad_inference_failure_err(failure_span, arg_data, error_code)
409         };
410
411         let (source_kind, name) = kind.ty_localized_msg(self);
412         let failure_span = if should_label_span && !failure_span.overlaps(span) {
413             Some(failure_span)
414         } else {
415             None
416         };
417
418         let mut infer_subdiags = Vec::new();
419         let mut multi_suggestions = Vec::new();
420         match kind {
421             InferSourceKind::LetBinding { insert_span, pattern_name, ty, def_id } => {
422                 infer_subdiags.push(SourceKindSubdiag::LetLike {
423                     span: insert_span,
424                     name: pattern_name.map(|name| name.to_string()).unwrap_or_else(String::new),
425                     x_kind: arg_data.where_x_is_kind(ty),
426                     prefix_kind: arg_data.kind.clone(),
427                     prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
428                     arg_name: arg_data.name,
429                     kind: if pattern_name.is_some() { "with_pattern" } else { "other" },
430                     type_name: ty_to_string(self, ty, def_id),
431                 });
432             }
433             InferSourceKind::ClosureArg { insert_span, ty } => {
434                 infer_subdiags.push(SourceKindSubdiag::LetLike {
435                     span: insert_span,
436                     name: String::new(),
437                     x_kind: arg_data.where_x_is_kind(ty),
438                     prefix_kind: arg_data.kind.clone(),
439                     prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
440                     arg_name: arg_data.name,
441                     kind: "closure",
442                     type_name: ty_to_string(self, ty, None),
443                 });
444             }
445             InferSourceKind::GenericArg {
446                 insert_span,
447                 argument_index,
448                 generics_def_id,
449                 def_id: _,
450                 generic_args,
451                 have_turbofish,
452             } => {
453                 let generics = self.tcx.generics_of(generics_def_id);
454                 let is_type = matches!(arg.unpack(), GenericArgKind::Type(_));
455
456                 let (parent_exists, parent_prefix, parent_name) =
457                     InferenceDiagnosticsParentData::for_parent_def_id(self.tcx, generics_def_id)
458                         .map_or((false, String::new(), String::new()), |parent| {
459                             (true, parent.prefix.to_string(), parent.name)
460                         });
461
462                 infer_subdiags.push(SourceKindSubdiag::GenericLabel {
463                     span,
464                     is_type,
465                     param_name: generics.params[argument_index].name.to_string(),
466                     parent_exists,
467                     parent_prefix,
468                     parent_name,
469                 });
470
471                 let args = if self.infcx.tcx.get_diagnostic_item(sym::iterator_collect_fn)
472                     == Some(generics_def_id)
473                 {
474                     "Vec<_>".to_string()
475                 } else {
476                     fmt_printer(self, Namespace::TypeNS)
477                         .comma_sep(generic_args.iter().copied().map(|arg| {
478                             if arg.is_suggestable(self.tcx, true) {
479                                 return arg;
480                             }
481
482                             match arg.unpack() {
483                                 GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),
484                                 GenericArgKind::Type(_) => self
485                                     .next_ty_var(TypeVariableOrigin {
486                                         span: rustc_span::DUMMY_SP,
487                                         kind: TypeVariableOriginKind::MiscVariable,
488                                     })
489                                     .into(),
490                                 GenericArgKind::Const(arg) => self
491                                     .next_const_var(
492                                         arg.ty(),
493                                         ConstVariableOrigin {
494                                             span: rustc_span::DUMMY_SP,
495                                             kind: ConstVariableOriginKind::MiscVariable,
496                                         },
497                                     )
498                                     .into(),
499                             }
500                         }))
501                         .unwrap()
502                         .into_buffer()
503                 };
504
505                 if !have_turbofish {
506                     infer_subdiags.push(SourceKindSubdiag::GenericSuggestion {
507                         span: insert_span,
508                         arg_count: generic_args.len(),
509                         args,
510                     });
511                 }
512             }
513             InferSourceKind::FullyQualifiedMethodCall { receiver, successor, substs, def_id } => {
514                 let printer = fmt_printer(self, Namespace::ValueNS);
515                 let def_path = printer.print_def_path(def_id, substs).unwrap().into_buffer();
516
517                 // We only care about whether we have to add `&` or `&mut ` for now.
518                 // This is the case if the last adjustment is a borrow and the
519                 // first adjustment was not a builtin deref.
520                 let adjustment = match typeck_results.expr_adjustments(receiver) {
521                     [
522                         Adjustment { kind: Adjust::Deref(None), target: _ },
523                         ..,
524                         Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), target: _ },
525                     ] => "",
526                     [
527                         ..,
528                         Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mut_)), target: _ },
529                     ] => hir::Mutability::from(*mut_).ref_prefix_str(),
530                     _ => "",
531                 };
532
533                 multi_suggestions.push(SourceKindMultiSuggestion::new_fully_qualified(
534                     receiver.span,
535                     def_path,
536                     adjustment,
537                     successor,
538                 ));
539             }
540             InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => {
541                 let ty_info = ty_to_string(self, ty, None);
542                 multi_suggestions.push(SourceKindMultiSuggestion::new_closure_return(
543                     ty_info,
544                     data,
545                     should_wrap_expr,
546                 ));
547             }
548         }
549         match error_code {
550             TypeAnnotationNeeded::E0282 => AnnotationRequired {
551                 span,
552                 source_kind,
553                 source_name: &name,
554                 failure_span,
555                 infer_subdiags,
556                 multi_suggestions,
557                 bad_label: None,
558             }
559             .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
560             TypeAnnotationNeeded::E0283 => AmbigousImpl {
561                 span,
562                 source_kind,
563                 source_name: &name,
564                 failure_span,
565                 infer_subdiags,
566                 multi_suggestions,
567                 bad_label: None,
568             }
569             .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
570             TypeAnnotationNeeded::E0284 => AmbigousReturn {
571                 span,
572                 source_kind,
573                 source_name: &name,
574                 failure_span,
575                 infer_subdiags,
576                 multi_suggestions,
577                 bad_label: None,
578             }
579             .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic),
580         }
581     }
582 }
583
584 impl<'tcx> InferCtxt<'tcx> {
585     pub fn need_type_info_err_in_generator(
586         &self,
587         kind: hir::GeneratorKind,
588         span: Span,
589         ty: ty::Term<'tcx>,
590     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
591         let ty = self.resolve_vars_if_possible(ty);
592         let data = self.extract_inference_diagnostics_data(ty.into(), None);
593
594         NeedTypeInfoInGenerator {
595             bad_label: data.make_bad_error(span),
596             span,
597             generator_kind: GeneratorKindAsDiagArg(kind),
598         }
599         .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic)
600     }
601 }
602
603 pub struct GeneratorKindAsDiagArg(pub hir::GeneratorKind);
604
605 impl IntoDiagnosticArg for GeneratorKindAsDiagArg {
606     fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
607         let kind = match self.0 {
608             hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "async_block",
609             hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "async_closure",
610             hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "async_fn",
611             hir::GeneratorKind::Gen => "generator",
612         };
613         rustc_errors::DiagnosticArgValue::Str(kind.into())
614     }
615 }
616
617 #[derive(Debug)]
618 struct InferSource<'tcx> {
619     span: Span,
620     kind: InferSourceKind<'tcx>,
621 }
622
623 #[derive(Debug)]
624 enum InferSourceKind<'tcx> {
625     LetBinding {
626         insert_span: Span,
627         pattern_name: Option<Ident>,
628         ty: Ty<'tcx>,
629         def_id: Option<DefId>,
630     },
631     ClosureArg {
632         insert_span: Span,
633         ty: Ty<'tcx>,
634     },
635     GenericArg {
636         insert_span: Span,
637         argument_index: usize,
638         generics_def_id: DefId,
639         def_id: DefId,
640         generic_args: &'tcx [GenericArg<'tcx>],
641         have_turbofish: bool,
642     },
643     FullyQualifiedMethodCall {
644         receiver: &'tcx Expr<'tcx>,
645         /// If the method has other arguments, this is ", " and the start of the first argument,
646         /// while for methods without arguments this is ")" and the end of the method call.
647         successor: (&'static str, BytePos),
648         substs: SubstsRef<'tcx>,
649         def_id: DefId,
650     },
651     ClosureReturn {
652         ty: Ty<'tcx>,
653         data: &'tcx FnRetTy<'tcx>,
654         should_wrap_expr: Option<Span>,
655     },
656 }
657
658 impl<'tcx> InferSource<'tcx> {
659     fn from_expansion(&self) -> bool {
660         let source_from_expansion = match self.kind {
661             InferSourceKind::LetBinding { insert_span, .. }
662             | InferSourceKind::ClosureArg { insert_span, .. }
663             | InferSourceKind::GenericArg { insert_span, .. } => insert_span.from_expansion(),
664             InferSourceKind::FullyQualifiedMethodCall { receiver, .. } => {
665                 receiver.span.from_expansion()
666             }
667             InferSourceKind::ClosureReturn { data, should_wrap_expr, .. } => {
668                 data.span().from_expansion() || should_wrap_expr.map_or(false, Span::from_expansion)
669             }
670         };
671         source_from_expansion || self.span.from_expansion()
672     }
673 }
674
675 impl<'tcx> InferSourceKind<'tcx> {
676     fn ty_localized_msg(&self, infcx: &InferCtxt<'tcx>) -> (&'static str, String) {
677         match *self {
678             InferSourceKind::LetBinding { ty, .. }
679             | InferSourceKind::ClosureArg { ty, .. }
680             | InferSourceKind::ClosureReturn { ty, .. } => {
681                 if ty.is_closure() {
682                     ("closure", closure_as_fn_str(infcx, ty))
683                 } else if !ty.is_ty_infer() {
684                     ("normal", ty_to_string(infcx, ty, None))
685                 } else {
686                     ("other", String::new())
687                 }
688             }
689             // FIXME: We should be able to add some additional info here.
690             InferSourceKind::GenericArg { .. }
691             | InferSourceKind::FullyQualifiedMethodCall { .. } => ("other", String::new()),
692         }
693     }
694 }
695
696 #[derive(Debug)]
697 struct InsertableGenericArgs<'tcx> {
698     insert_span: Span,
699     substs: SubstsRef<'tcx>,
700     generics_def_id: DefId,
701     def_id: DefId,
702     have_turbofish: bool,
703 }
704
705 /// A visitor which searches for the "best" spot to use in the inference error.
706 ///
707 /// For this it walks over the hir body and tries to check all places where
708 /// inference variables could be bound.
709 ///
710 /// While doing so, the currently best spot is stored in `infer_source`.
711 /// For details on how we rank spots, see [Self::source_cost]
712 struct FindInferSourceVisitor<'a, 'tcx> {
713     infcx: &'a InferCtxt<'tcx>,
714     typeck_results: &'a TypeckResults<'tcx>,
715
716     target: GenericArg<'tcx>,
717
718     attempt: usize,
719     infer_source_cost: usize,
720     infer_source: Option<InferSource<'tcx>>,
721 }
722
723 impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
724     fn new(
725         infcx: &'a InferCtxt<'tcx>,
726         typeck_results: &'a TypeckResults<'tcx>,
727         target: GenericArg<'tcx>,
728     ) -> Self {
729         FindInferSourceVisitor {
730             infcx,
731             typeck_results,
732
733             target,
734
735             attempt: 0,
736             infer_source_cost: usize::MAX,
737             infer_source: None,
738         }
739     }
740
741     /// Computes cost for the given source.
742     ///
743     /// Sources with a small cost are prefer and should result
744     /// in a clearer and idiomatic suggestion.
745     fn source_cost(&self, source: &InferSource<'tcx>) -> usize {
746         #[derive(Clone, Copy)]
747         struct CostCtxt<'tcx> {
748             tcx: TyCtxt<'tcx>,
749         }
750         impl<'tcx> CostCtxt<'tcx> {
751             fn arg_cost(self, arg: GenericArg<'tcx>) -> usize {
752                 match arg.unpack() {
753                     GenericArgKind::Lifetime(_) => 0, // erased
754                     GenericArgKind::Type(ty) => self.ty_cost(ty),
755                     GenericArgKind::Const(_) => 3, // some non-zero value
756                 }
757             }
758             fn ty_cost(self, ty: Ty<'tcx>) -> usize {
759                 match *ty.kind() {
760                     ty::Closure(..) => 1000,
761                     ty::FnDef(..) => 150,
762                     ty::FnPtr(..) => 30,
763                     ty::Adt(def, substs) => {
764                         5 + self
765                             .tcx
766                             .generics_of(def.did())
767                             .own_substs_no_defaults(self.tcx, substs)
768                             .iter()
769                             .map(|&arg| self.arg_cost(arg))
770                             .sum::<usize>()
771                     }
772                     ty::Tuple(args) => 5 + args.iter().map(|arg| self.ty_cost(arg)).sum::<usize>(),
773                     ty::Ref(_, ty, _) => 2 + self.ty_cost(ty),
774                     ty::Infer(..) => 0,
775                     _ => 1,
776                 }
777             }
778         }
779
780         // The sources are listed in order of preference here.
781         let tcx = self.infcx.tcx;
782         let ctx = CostCtxt { tcx };
783         let base_cost = match source.kind {
784             InferSourceKind::LetBinding { ty, .. } => ctx.ty_cost(ty),
785             InferSourceKind::ClosureArg { ty, .. } => ctx.ty_cost(ty),
786             InferSourceKind::GenericArg { def_id, generic_args, .. } => {
787                 let variant_cost = match tcx.def_kind(def_id) {
788                     // `None::<u32>` and friends are ugly.
789                     DefKind::Variant | DefKind::Ctor(CtorOf::Variant, _) => 15,
790                     _ => 10,
791                 };
792                 variant_cost + generic_args.iter().map(|&arg| ctx.arg_cost(arg)).sum::<usize>()
793             }
794             InferSourceKind::FullyQualifiedMethodCall { substs, .. } => {
795                 20 + substs.iter().map(|arg| ctx.arg_cost(arg)).sum::<usize>()
796             }
797             InferSourceKind::ClosureReturn { ty, should_wrap_expr, .. } => {
798                 30 + ctx.ty_cost(ty) + if should_wrap_expr.is_some() { 10 } else { 0 }
799             }
800         };
801
802         let suggestion_may_apply = if source.from_expansion() { 10000 } else { 0 };
803
804         base_cost + suggestion_may_apply
805     }
806
807     /// Uses `fn source_cost` to determine whether this inference source is preferable to
808     /// previous sources. We generally prefer earlier sources.
809     #[instrument(level = "debug", skip(self))]
810     fn update_infer_source(&mut self, mut new_source: InferSource<'tcx>) {
811         let cost = self.source_cost(&new_source) + self.attempt;
812         debug!(?cost);
813         self.attempt += 1;
814         if let Some(InferSource { kind: InferSourceKind::GenericArg { def_id: did, ..}, .. }) = self.infer_source
815             && let InferSourceKind::LetBinding { ref ty, ref mut def_id, ..} = new_source.kind
816             && ty.is_ty_infer()
817         {
818             // Customize the output so we talk about `let x: Vec<_> = iter.collect();` instead of
819             // `let x: _ = iter.collect();`, as this is a very common case.
820             *def_id = Some(did);
821         }
822         if cost < self.infer_source_cost {
823             self.infer_source_cost = cost;
824             self.infer_source = Some(new_source);
825         }
826     }
827
828     fn node_substs_opt(&self, hir_id: HirId) -> Option<SubstsRef<'tcx>> {
829         let substs = self.typeck_results.node_substs_opt(hir_id);
830         self.infcx.resolve_vars_if_possible(substs)
831     }
832
833     fn opt_node_type(&self, hir_id: HirId) -> Option<Ty<'tcx>> {
834         let ty = self.typeck_results.node_type_opt(hir_id);
835         self.infcx.resolve_vars_if_possible(ty)
836     }
837
838     // Check whether this generic argument is the inference variable we
839     // are looking for.
840     fn generic_arg_is_target(&self, arg: GenericArg<'tcx>) -> bool {
841         if arg == self.target {
842             return true;
843         }
844
845         match (arg.unpack(), self.target.unpack()) {
846             (GenericArgKind::Type(inner_ty), GenericArgKind::Type(target_ty)) => {
847                 use ty::{Infer, TyVar};
848                 match (inner_ty.kind(), target_ty.kind()) {
849                     (&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => {
850                         self.infcx.inner.borrow_mut().type_variables().sub_unified(a_vid, b_vid)
851                     }
852                     _ => false,
853                 }
854             }
855             (GenericArgKind::Const(inner_ct), GenericArgKind::Const(target_ct)) => {
856                 use ty::InferConst::*;
857                 match (inner_ct.kind(), target_ct.kind()) {
858                     (ty::ConstKind::Infer(Var(a_vid)), ty::ConstKind::Infer(Var(b_vid))) => self
859                         .infcx
860                         .inner
861                         .borrow_mut()
862                         .const_unification_table()
863                         .unioned(a_vid, b_vid),
864                     _ => false,
865                 }
866             }
867             _ => false,
868         }
869     }
870
871     /// Does this generic argument contain our target inference variable
872     /// in a way which can be written by the user.
873     fn generic_arg_contains_target(&self, arg: GenericArg<'tcx>) -> bool {
874         let mut walker = arg.walk();
875         while let Some(inner) = walker.next() {
876             if self.generic_arg_is_target(inner) {
877                 return true;
878             }
879             match inner.unpack() {
880                 GenericArgKind::Lifetime(_) => {}
881                 GenericArgKind::Type(ty) => {
882                     if matches!(
883                         ty.kind(),
884                         ty::Alias(ty::Opaque, ..) | ty::Closure(..) | ty::Generator(..)
885                     ) {
886                         // Opaque types can't be named by the user right now.
887                         //
888                         // Both the generic arguments of closures and generators can
889                         // also not be named. We may want to only look into the closure
890                         // signature in case it has no captures, as that can be represented
891                         // using `fn(T) -> R`.
892
893                         // FIXME(type_alias_impl_trait): These opaque types
894                         // can actually be named, so it would make sense to
895                         // adjust this case and add a test for it.
896                         walker.skip_current_subtree();
897                     }
898                 }
899                 GenericArgKind::Const(ct) => {
900                     if matches!(ct.kind(), ty::ConstKind::Unevaluated(..)) {
901                         // You can't write the generic arguments for
902                         // unevaluated constants.
903                         walker.skip_current_subtree();
904                     }
905                 }
906             }
907         }
908         false
909     }
910
911     fn expr_inferred_subst_iter(
912         &self,
913         expr: &'tcx hir::Expr<'tcx>,
914     ) -> Box<dyn Iterator<Item = InsertableGenericArgs<'tcx>> + 'a> {
915         let tcx = self.infcx.tcx;
916         match expr.kind {
917             hir::ExprKind::Path(ref path) => {
918                 if let Some(substs) = self.node_substs_opt(expr.hir_id) {
919                     return self.path_inferred_subst_iter(expr.hir_id, substs, path);
920                 }
921             }
922             // FIXME(#98711): Ideally we would also deal with type relative
923             // paths here, even if that is quite rare.
924             //
925             // See the `need_type_info/expr-struct-type-relative-gat.rs` test
926             // for an example where that would be needed.
927             //
928             // However, the `type_dependent_def_id` for `Self::Output` in an
929             // impl is currently the `DefId` of `Output` in the trait definition
930             // which makes this somewhat difficult and prevents us from just
931             // using `self.path_inferred_subst_iter` here.
932             hir::ExprKind::Struct(&hir::QPath::Resolved(_self_ty, path), _, _)
933             // FIXME(TaKO8Ki): Ideally we should support this. For that
934             // we have to map back from the self type to the
935             // type alias though. That's difficult.
936             //
937             // See the `need_type_info/issue-103053.rs` test for
938             // a example.
939             if !matches!(path.res, Res::Def(DefKind::TyAlias, _)) => {
940                 if let Some(ty) = self.opt_node_type(expr.hir_id)
941                     && let ty::Adt(_, substs) = ty.kind()
942                 {
943                     return Box::new(self.resolved_path_inferred_subst_iter(path, substs));
944                 }
945             }
946             hir::ExprKind::MethodCall(segment, ..) => {
947                 if let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id) {
948                     let generics = tcx.generics_of(def_id);
949                     let insertable: Option<_> = try {
950                         if generics.has_impl_trait() {
951                             None?
952                         }
953                         let substs = self.node_substs_opt(expr.hir_id)?;
954                         let span = tcx.hir().span(segment.hir_id);
955                         let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
956                         InsertableGenericArgs {
957                             insert_span,
958                             substs,
959                             generics_def_id: def_id,
960                             def_id,
961                             have_turbofish: false,
962                         }
963                     };
964                     return Box::new(insertable.into_iter());
965                 }
966             }
967             _ => {}
968         }
969
970         Box::new(iter::empty())
971     }
972
973     fn resolved_path_inferred_subst_iter(
974         &self,
975         path: &'tcx hir::Path<'tcx>,
976         substs: SubstsRef<'tcx>,
977     ) -> impl Iterator<Item = InsertableGenericArgs<'tcx>> + 'a {
978         let tcx = self.infcx.tcx;
979         let have_turbofish = path.segments.iter().any(|segment| {
980             segment.args.map_or(false, |args| args.args.iter().any(|arg| arg.is_ty_or_const()))
981         });
982         // The last segment of a path often has `Res::Err` and the
983         // correct `Res` is the one of the whole path.
984         //
985         // FIXME: We deal with that one separately for now,
986         // would be good to remove this special case.
987         let last_segment_using_path_data: Option<_> = try {
988             let generics_def_id = tcx.res_generics_def_id(path.res)?;
989             let generics = tcx.generics_of(generics_def_id);
990             if generics.has_impl_trait() {
991                 None?;
992             }
993             let insert_span =
994                 path.segments.last().unwrap().ident.span.shrink_to_hi().with_hi(path.span.hi());
995             InsertableGenericArgs {
996                 insert_span,
997                 substs,
998                 generics_def_id,
999                 def_id: path.res.def_id(),
1000                 have_turbofish,
1001             }
1002         };
1003
1004         path.segments
1005             .iter()
1006             .filter_map(move |segment| {
1007                 let res = segment.res;
1008                 let generics_def_id = tcx.res_generics_def_id(res)?;
1009                 let generics = tcx.generics_of(generics_def_id);
1010                 if generics.has_impl_trait() {
1011                     return None;
1012                 }
1013                 let span = tcx.hir().span(segment.hir_id);
1014                 let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
1015                 Some(InsertableGenericArgs {
1016                     insert_span,
1017                     substs,
1018                     generics_def_id,
1019                     def_id: res.def_id(),
1020                     have_turbofish,
1021                 })
1022             })
1023             .chain(last_segment_using_path_data)
1024     }
1025
1026     fn path_inferred_subst_iter(
1027         &self,
1028         hir_id: HirId,
1029         substs: SubstsRef<'tcx>,
1030         qpath: &'tcx hir::QPath<'tcx>,
1031     ) -> Box<dyn Iterator<Item = InsertableGenericArgs<'tcx>> + 'a> {
1032         let tcx = self.infcx.tcx;
1033         match qpath {
1034             hir::QPath::Resolved(_self_ty, path) => {
1035                 Box::new(self.resolved_path_inferred_subst_iter(path, substs))
1036             }
1037             hir::QPath::TypeRelative(ty, segment) => {
1038                 let Some(def_id) = self.typeck_results.type_dependent_def_id(hir_id) else {
1039                     return Box::new(iter::empty());
1040                 };
1041
1042                 let generics = tcx.generics_of(def_id);
1043                 let segment: Option<_> = try {
1044                     if !segment.infer_args || generics.has_impl_trait() {
1045                         None?;
1046                     }
1047                     let span = tcx.hir().span(segment.hir_id);
1048                     let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
1049                     InsertableGenericArgs {
1050                         insert_span,
1051                         substs,
1052                         generics_def_id: def_id,
1053                         def_id,
1054                         have_turbofish: false,
1055                     }
1056                 };
1057
1058                 let parent_def_id = generics.parent.unwrap();
1059                 if tcx.def_kind(parent_def_id) == DefKind::Impl {
1060                     let parent_ty = tcx.bound_type_of(parent_def_id).subst(tcx, substs);
1061                     match (parent_ty.kind(), &ty.kind) {
1062                         (
1063                             ty::Adt(def, substs),
1064                             hir::TyKind::Path(hir::QPath::Resolved(_self_ty, path)),
1065                         ) => {
1066                             if tcx.res_generics_def_id(path.res) != Some(def.did()) {
1067                                 match path.res {
1068                                     Res::Def(DefKind::TyAlias, _) => {
1069                                         // FIXME: Ideally we should support this. For that
1070                                         // we have to map back from the self type to the
1071                                         // type alias though. That's difficult.
1072                                         //
1073                                         // See the `need_type_info/type-alias.rs` test for
1074                                         // some examples.
1075                                     }
1076                                     // There cannot be inference variables in the self type,
1077                                     // so there's nothing for us to do here.
1078                                     Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {}
1079                                     _ => warn!(
1080                                         "unexpected path: def={:?} substs={:?} path={:?}",
1081                                         def, substs, path,
1082                                     ),
1083                                 }
1084                             } else {
1085                                 return Box::new(
1086                                     self.resolved_path_inferred_subst_iter(path, substs)
1087                                         .chain(segment),
1088                                 );
1089                             }
1090                         }
1091                         _ => (),
1092                     }
1093                 }
1094
1095                 Box::new(segment.into_iter())
1096             }
1097             hir::QPath::LangItem(_, _, _) => Box::new(iter::empty()),
1098         }
1099     }
1100 }
1101
1102 impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
1103     type NestedFilter = nested_filter::OnlyBodies;
1104
1105     fn nested_visit_map(&mut self) -> Self::Map {
1106         self.infcx.tcx.hir()
1107     }
1108
1109     fn visit_local(&mut self, local: &'tcx Local<'tcx>) {
1110         intravisit::walk_local(self, local);
1111
1112         if let Some(ty) = self.opt_node_type(local.hir_id) {
1113             if self.generic_arg_contains_target(ty.into()) {
1114                 match local.source {
1115                     LocalSource::Normal if local.ty.is_none() => {
1116                         self.update_infer_source(InferSource {
1117                             span: local.pat.span,
1118                             kind: InferSourceKind::LetBinding {
1119                                 insert_span: local.pat.span.shrink_to_hi(),
1120                                 pattern_name: local.pat.simple_ident(),
1121                                 ty,
1122                                 def_id: None,
1123                             },
1124                         })
1125                     }
1126                     _ => {}
1127                 }
1128             }
1129         }
1130     }
1131
1132     /// For closures, we first visit the parameters and then the content,
1133     /// as we prefer those.
1134     fn visit_body(&mut self, body: &'tcx Body<'tcx>) {
1135         for param in body.params {
1136             debug!(
1137                 "param: span {:?}, ty_span {:?}, pat.span {:?}",
1138                 param.span, param.ty_span, param.pat.span
1139             );
1140             if param.ty_span != param.pat.span {
1141                 debug!("skipping param: has explicit type");
1142                 continue;
1143             }
1144
1145             let Some(param_ty) = self.opt_node_type(param.hir_id) else {
1146                 continue
1147             };
1148
1149             if self.generic_arg_contains_target(param_ty.into()) {
1150                 self.update_infer_source(InferSource {
1151                     span: param.pat.span,
1152                     kind: InferSourceKind::ClosureArg {
1153                         insert_span: param.pat.span.shrink_to_hi(),
1154                         ty: param_ty,
1155                     },
1156                 })
1157             }
1158         }
1159         intravisit::walk_body(self, body);
1160     }
1161
1162     #[instrument(level = "debug", skip(self))]
1163     fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
1164         let tcx = self.infcx.tcx;
1165         match expr.kind {
1166             // When encountering `func(arg)` first look into `arg` and then `func`,
1167             // as `arg` is "more specific".
1168             ExprKind::Call(func, args) => {
1169                 for arg in args {
1170                     self.visit_expr(arg);
1171                 }
1172                 self.visit_expr(func);
1173             }
1174             _ => intravisit::walk_expr(self, expr),
1175         }
1176
1177         for args in self.expr_inferred_subst_iter(expr) {
1178             debug!(?args);
1179             let InsertableGenericArgs {
1180                 insert_span,
1181                 substs,
1182                 generics_def_id,
1183                 def_id,
1184                 have_turbofish,
1185             } = args;
1186             let generics = tcx.generics_of(generics_def_id);
1187             if let Some(argument_index) = generics
1188                 .own_substs(substs)
1189                 .iter()
1190                 .position(|&arg| self.generic_arg_contains_target(arg))
1191             {
1192                 let substs = self.infcx.resolve_vars_if_possible(substs);
1193                 let generic_args = &generics.own_substs_no_defaults(tcx, substs)
1194                     [generics.own_counts().lifetimes..];
1195                 let span = match expr.kind {
1196                     ExprKind::MethodCall(path, ..) => path.ident.span,
1197                     _ => expr.span,
1198                 };
1199
1200                 self.update_infer_source(InferSource {
1201                     span,
1202                     kind: InferSourceKind::GenericArg {
1203                         insert_span,
1204                         argument_index,
1205                         generics_def_id,
1206                         def_id,
1207                         generic_args,
1208                         have_turbofish,
1209                     },
1210                 });
1211             }
1212         }
1213
1214         if let Some(node_ty) = self.opt_node_type(expr.hir_id) {
1215             if let (
1216                 &ExprKind::Closure(&Closure { fn_decl, body, fn_decl_span, .. }),
1217                 ty::Closure(_, substs),
1218             ) = (&expr.kind, node_ty.kind())
1219             {
1220                 let output = substs.as_closure().sig().output().skip_binder();
1221                 if self.generic_arg_contains_target(output.into()) {
1222                     let body = self.infcx.tcx.hir().body(body);
1223                     let should_wrap_expr = if matches!(body.value.kind, ExprKind::Block(..)) {
1224                         None
1225                     } else {
1226                         Some(body.value.span.shrink_to_hi())
1227                     };
1228                     self.update_infer_source(InferSource {
1229                         span: fn_decl_span,
1230                         kind: InferSourceKind::ClosureReturn {
1231                             ty: output,
1232                             data: &fn_decl.output,
1233                             should_wrap_expr,
1234                         },
1235                     })
1236                 }
1237             }
1238         }
1239
1240         let has_impl_trait = |def_id| {
1241             iter::successors(Some(tcx.generics_of(def_id)), |generics| {
1242                 generics.parent.map(|def_id| tcx.generics_of(def_id))
1243             })
1244             .any(|generics| generics.has_impl_trait())
1245         };
1246         if let ExprKind::MethodCall(path, receiver, args, span) = expr.kind
1247             && let Some(substs) = self.node_substs_opt(expr.hir_id)
1248             && substs.iter().any(|arg| self.generic_arg_contains_target(arg))
1249             && let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id)
1250             && self.infcx.tcx.trait_of_item(def_id).is_some()
1251             && !has_impl_trait(def_id)
1252         {
1253             let successor =
1254                 args.get(0).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo()));
1255             let substs = self.infcx.resolve_vars_if_possible(substs);
1256             self.update_infer_source(InferSource {
1257                 span: path.ident.span,
1258                 kind: InferSourceKind::FullyQualifiedMethodCall {
1259                     receiver,
1260                     successor,
1261                     substs,
1262                     def_id,
1263                 }
1264             })
1265         }
1266     }
1267 }