rustc_trait_selection/error_reporting/infer/
need_type_info.rs

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