Skip to main content

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::def::{CtorOf, DefKind, Namespace, Res};
8use rustc_hir::def_id::{DefId, LocalDefId};
9use rustc_hir::intravisit::{self, Visitor};
10use rustc_hir::{
11    self as hir, Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource, PatKind,
12};
13use rustc_middle::hir::nested_filter;
14use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, DerefAdjustKind};
15use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
16use rustc_middle::ty::{
17    self, GenericArg, GenericArgKind, GenericArgsRef, GenericParamDefKind, InferConst,
18    IsSuggestable, Term, TermKind, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
19    TypeVisitableExt, TypeckResults,
20};
21use rustc_next_trait_solver::solve::TyOrConstInferVar;
22use rustc_span::{BytePos, DUMMY_SP, Ident, Span, bug, sym};
23use tracing::{debug, instrument, warn};
24
25use super::nice_region_error::placeholder_error::Highlighted;
26use crate::diagnostics::{
27    AmbiguousImpl, AmbiguousReturn, AnnotationRequired, InferenceBadError, SourceKindSubdiag,
28    SpecifyGenericParamsSuggestion,
29};
30use crate::error_reporting::TypeErrCtxt;
31use crate::infer::InferCtxt;
32
33pub enum TypeAnnotationNeeded {
34    /// ```compile_fail,E0282
35    /// let x;
36    /// ```
37    E0282,
38    /// An implementation cannot be chosen unambiguously because of lack of information.
39    /// ```compile_fail,E0790
40    /// let _ = Default::default();
41    /// ```
42    E0283,
43    /// ```compile_fail,E0284
44    /// let mut d: u64 = 2;
45    /// d = d % 1u32.into();
46    /// ```
47    E0284,
48}
49
50impl From<TypeAnnotationNeeded> for ErrCode {
51    fn from(val: TypeAnnotationNeeded) -> Self {
52        match val {
53            TypeAnnotationNeeded::E0282 => E0282,
54            TypeAnnotationNeeded::E0283 => E0283,
55            TypeAnnotationNeeded::E0284 => E0284,
56        }
57    }
58}
59
60/// Information about a constant or a type containing inference variables.
61pub struct InferenceDiagnosticsData {
62    pub name: String,
63    pub span: Option<Span>,
64    pub kind: UnderspecifiedArgKind,
65    pub parent: Option<InferenceDiagnosticsParentData>,
66}
67
68/// Data on the parent definition where a generic argument was declared.
69pub struct InferenceDiagnosticsParentData {
70    prefix: &'static str,
71    name: String,
72}
73
74#[derive(#[automatically_derived]
impl ::core::clone::Clone for UnderspecifiedArgKind {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            Self::Type { prefix: __self_0 } =>
                UnderspecifiedArgKind::Type {
                    prefix: ::core::clone::Clone::clone(__self_0),
                },
            Self::Const { is_parameter: __self_0 } =>
                UnderspecifiedArgKind::Const {
                    is_parameter: ::core::clone::Clone::clone(__self_0),
                },
        }
    }
}Clone)]
75pub enum UnderspecifiedArgKind {
76    Type { prefix: Cow<'static, str> },
77    Const { is_parameter: bool },
78}
79
80impl InferenceDiagnosticsData {
81    fn can_add_more_info(&self) -> bool {
82        !(self.name == "_" && #[allow(non_exhaustive_omitted_patterns)] match self.kind {
    UnderspecifiedArgKind::Type { .. } => true,
    _ => false,
}matches!(self.kind, UnderspecifiedArgKind::Type { .. }))
83    }
84
85    fn where_x_is_kind<'tcx>(&self, infcx: &InferCtxt<'tcx>, in_type: Ty<'tcx>) -> &'static str {
86        if in_type.is_ty_or_numeric_infer() {
87            ""
88        } else if self.name == "_" {
89            let displayed_ty = infcx
90                .deeply_resolve_ignoring_regions(in_type)
91                .fold_with(&mut ClosureEraser { infcx, depth: 0 });
92            if displayed_ty.is_ty_or_numeric_infer() {
93                ""
94            } else {
95                match displayed_ty
96                    .walk()
97                    .filter_map(TyOrConstInferVar::maybe_from_generic_arg::<TyCtxt<'tcx>>)
98                    .take(2)
99                    .count()
100                {
101                    0 => "",
102                    1 => "underscore_single",
103                    _ => "underscore_multiple",
104                }
105            }
106        } else {
107            "has_name"
108        }
109    }
110
111    /// Generate a label for a generic argument which can't be inferred. When not
112    /// much is known about the argument, `use_diag` may be used to describe the
113    /// labeled value.
114    fn make_bad_error(&self, span: Span) -> InferenceBadError<'_> {
115        let has_parent = self.parent.is_some();
116        let bad_kind = if self.can_add_more_info() { "more_info" } else { "other" };
117        let (parent_prefix, parent_name) = self
118            .parent
119            .as_ref()
120            .map(|parent| (parent.prefix, parent.name.clone()))
121            .unwrap_or_default();
122        InferenceBadError {
123            span,
124            bad_kind,
125            prefix_kind: self.kind.clone(),
126            prefix: self.kind.try_get_prefix().unwrap_or_default(),
127            name: self.name.clone(),
128            has_parent,
129            parent_prefix,
130            parent_name,
131        }
132    }
133}
134
135impl InferenceDiagnosticsParentData {
136    fn for_parent_def_id(
137        tcx: TyCtxt<'_>,
138        parent_def_id: DefId,
139    ) -> Option<InferenceDiagnosticsParentData> {
140        let parent_name =
141            tcx.def_key(parent_def_id).disambiguated_data.data.get_opt_name()?.to_string();
142
143        Some(InferenceDiagnosticsParentData {
144            prefix: tcx.def_descr(parent_def_id),
145            name: parent_name,
146        })
147    }
148
149    fn for_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option<InferenceDiagnosticsParentData> {
150        Self::for_parent_def_id(tcx, tcx.parent(def_id))
151    }
152}
153
154impl IntoDiagArg for UnderspecifiedArgKind {
155    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> rustc_errors::DiagArgValue {
156        let kind = match self {
157            Self::Type { .. } => "type",
158            Self::Const { is_parameter: true } => "const_with_param",
159            Self::Const { is_parameter: false } => "const",
160        };
161        rustc_errors::DiagArgValue::Str(kind.into())
162    }
163}
164
165impl UnderspecifiedArgKind {
166    fn try_get_prefix(&self) -> Option<&str> {
167        match self {
168            Self::Type { prefix } => Some(prefix.as_ref()),
169            Self::Const { .. } => None,
170        }
171    }
172}
173
174struct ClosureEraser<'a, 'tcx> {
175    infcx: &'a InferCtxt<'tcx>,
176    depth: usize,
177}
178
179impl<'a, 'tcx> ClosureEraser<'a, 'tcx> {
180    fn new_infer(&mut self) -> Ty<'tcx> {
181        self.infcx.next_ty_var(DUMMY_SP)
182    }
183}
184
185impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ClosureEraser<'a, 'tcx> {
186    fn cx(&self) -> TyCtxt<'tcx> {
187        self.infcx.tcx
188    }
189
190    fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
191        self.depth += 1;
192        let ty = match ty.kind() {
193            ty::Closure(_, args) => {
194                // For a closure type, we turn it into a function pointer so that it gets rendered
195                // as `fn(args) -> Ret`.
196                let closure_sig = args.as_closure().sig();
197                Ty::new_fn_ptr(
198                    self.cx(),
199                    self.cx().signature_unclosure(closure_sig, hir::Safety::Safe),
200                )
201            }
202            ty::Adt(_, args) if !args.iter().any(|a| a.has_infer()) => {
203                // We have a type that doesn't have any inference variables, so we replace
204                // the whole thing with `_`. The type system already knows about this type in
205                // its entirety and it is redundant to specify it for the user. The user only
206                // needs to specify the type parameters that we *couldn't* figure out.
207                self.new_infer()
208            }
209            ty::Adt(def, args) => {
210                let generics = self.cx().generics_of(def.did());
211                let generics: Vec<bool> = generics
212                    .own_params
213                    .iter()
214                    .map(|param| param.default_value(self.cx()).is_some())
215                    .collect();
216                let ty = Ty::new_adt(
217                    self.cx(),
218                    *def,
219                    self.cx().mk_args_from_iter(generics.into_iter().zip(args.iter()).map(
220                        |(has_default, arg)| {
221                            if arg.has_infer() {
222                                // This param has an unsubstituted type variable, meaning that this
223                                // type has a (potentially deeply nested) type parameter from the
224                                // corresponding type's definition. We have explicitly asked this
225                                // type to not be hidden. In either case, we keep the type and don't
226                                // substitute with `_` just yet.
227                                arg.fold_with(self)
228                            } else if has_default {
229                                // We have a type param that has a default type, like the allocator
230                                // in Vec. We decided to show `Vec` itself, because it hasn't yet
231                                // been replaced by an `_` `Infer`, but we want to ensure that the
232                                // type parameter with default types does *not* get replaced with
233                                // `_` because then we'd end up with `Vec<_, _>`, instead of
234                                // `Vec<_>`.
235                                arg
236                            } else if let GenericArgKind::Type(_) = arg.kind() {
237                                // We don't replace lifetime or const params, only type params.
238                                self.new_infer().into()
239                            } else {
240                                arg.fold_with(self)
241                            }
242                        },
243                    )),
244                );
245                ty
246            }
247            _ if ty.has_infer() => {
248                // This type has a (potentially nested) type parameter that we couldn't figure out.
249                // We will print this depth of type, so at least the type name and at least one of
250                // its type parameters.
251                ty.super_fold_with(self)
252            }
253            // We are in the top-level type, not one of its type parameters. Name it with its
254            // parameters replaced.
255            _ if self.depth == 1 => ty.super_fold_with(self),
256            // We don't have an unknown type parameter anywhere, and we are in a type parameter.
257            // Replace with `_`.
258            _ => self.new_infer(),
259        };
260        self.depth -= 1;
261        ty
262    }
263
264    fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
265        // Avoid accidentally erasing the type of the const.
266        c
267    }
268}
269
270fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinter<'a, 'tcx> {
271    let mut p = FmtPrinter::new(infcx.tcx, ns);
272    let ty_getter = move |ty_vid| {
273        if infcx.try_resolve_ty_var(ty_vid).is_ok() {
274            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs:274",
                        "rustc_trait_selection::error_reporting::infer::need_type_info",
                        ::tracing::Level::WARN,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
                        ::tracing_core::__macro_support::Option::Some(274u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::WARN <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("resolved ty var in error message")
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};warn!("resolved ty var in error message");
275        }
276
277        let var_origin = infcx.type_var_origin(ty_vid);
278        if let Some(def_id) = var_origin.param_def_id
279            // The `Self` param of a trait has the def-id of the trait,
280            // since it's a synthetic parameter.
281            && infcx.tcx.def_kind(def_id) == DefKind::TyParam
282            && let name = infcx.tcx.item_name(def_id)
283            && !var_origin.span.from_expansion()
284        {
285            let generics = infcx.tcx.generics_of(infcx.tcx.parent(def_id));
286            let idx = generics.param_def_id_to_index(infcx.tcx, def_id).unwrap();
287            let generic_param_def = generics.param_at(idx as usize, infcx.tcx);
288            if let ty::GenericParamDefKind::Type { synthetic: true, .. } = generic_param_def.kind {
289                None
290            } else {
291                Some(name)
292            }
293        } else {
294            None
295        }
296    };
297    p.ty_infer_name_resolver = Some(Box::new(ty_getter));
298    let const_getter =
299        move |ct_vid| Some(infcx.tcx.item_name(infcx.const_var_origin(ct_vid)?.param_def_id?));
300    p.const_infer_name_resolver = Some(Box::new(const_getter));
301    p
302}
303
304fn ty_to_string<'tcx>(
305    infcx: &InferCtxt<'tcx>,
306    ty: Ty<'tcx>,
307    called_method_def_id: Option<DefId>,
308) -> String {
309    let mut p = fmt_printer(infcx, Namespace::TypeNS);
310    let ty = infcx.deeply_resolve_ignoring_regions(ty);
311    // We use `fn` ptr syntax for closures, but this only works when the closure does not capture
312    // anything. We also remove all type parameters that are fully known to the type system.
313    let ty = ty.fold_with(&mut ClosureEraser { infcx, depth: 0 });
314
315    match (ty.kind(), called_method_def_id) {
316        // We don't want the regular output for `fn`s because it includes its path in
317        // invalid pseudo-syntax, we want the `fn`-pointer output instead.
318        (ty::FnDef(..), _) => {
319            ty.fn_sig(infcx.tcx).print(&mut p).unwrap();
320            p.into_buffer()
321        }
322        (_, Some(def_id))
323            if ty.is_ty_or_numeric_infer()
324                && infcx.tcx.get_diagnostic_item(sym::iterator_collect_fn) == Some(def_id) =>
325        {
326            "Vec<_>".to_string()
327        }
328        _ if ty.is_ty_or_numeric_infer() => "/* Type */".to_string(),
329        _ => {
330            ty.print(&mut p).unwrap();
331            p.into_buffer()
332        }
333    }
334}
335
336/// We don't want to directly use `ty_to_string` for closures as their type isn't really
337/// something users are familiar with. Directly printing the `fn_sig` of closures also
338/// doesn't work as they actually use the "rust-call" API.
339fn closure_as_fn_str<'tcx>(infcx: &InferCtxt<'tcx>, ty: Ty<'tcx>) -> String {
340    let ty::Closure(_, args) = ty.kind() else {
341        ::rustc_span::macros::bug_impl(None,
    format_args!("cannot convert non-closure to fn str in `closure_as_fn_str`"),
    Location::caller())bug!("cannot convert non-closure to fn str in `closure_as_fn_str`")
342    };
343    let fn_sig = args.as_closure().sig();
344    let args = fn_sig
345        .inputs()
346        .skip_binder()
347        .iter()
348        .next()
349        .map(|args| {
350            args.tuple_fields()
351                .iter()
352                .map(|arg| ty_to_string(infcx, arg, None))
353                .collect::<Vec<_>>()
354                .join(", ")
355        })
356        .unwrap_or_default();
357    let ret = if fn_sig.output().skip_binder().is_unit() {
358        String::new()
359    } else {
360        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!(" -> {0}",
                ty_to_string(infcx, fn_sig.output().skip_binder(), None)))
    })format!(" -> {}", ty_to_string(infcx, fn_sig.output().skip_binder(), None))
361    };
362    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("fn({0}){1}", args, ret))
    })format!("fn({args}){ret}")
363}
364
365impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
366    /// Extracts data used by diagnostic for either types or constants
367    /// which were stuck during inference.
368    pub fn extract_inference_diagnostics_data(
369        &self,
370        term: Term<'tcx>,
371        highlight: ty::print::RegionHighlightMode<'tcx>,
372    ) -> InferenceDiagnosticsData {
373        let tcx = self.tcx;
374        match term.kind() {
375            TermKind::Ty(ty) => {
376                if let ty::Infer(ty::TyVar(ty_vid)) = *ty.kind() {
377                    let var_origin = self.infcx.type_var_origin(ty_vid);
378                    if let Some(def_id) = var_origin.param_def_id
379                        // The `Self` param of a trait has the def-id of the trait,
380                        // since it's a synthetic parameter.
381                        && self.tcx.def_kind(def_id) == DefKind::TyParam
382                        && !var_origin.span.from_expansion()
383                    {
384                        return InferenceDiagnosticsData {
385                            name: self.tcx.item_name(def_id).to_string(),
386                            span: Some(var_origin.span),
387                            kind: UnderspecifiedArgKind::Type { prefix: "type parameter".into() },
388                            parent: InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id),
389                        };
390                    }
391                }
392
393                InferenceDiagnosticsData {
394                    name: Highlighted { highlight, ns: Namespace::TypeNS, tcx, value: ty }
395                        .to_string(),
396                    span: None,
397                    kind: UnderspecifiedArgKind::Type { prefix: ty.prefix_string(self.tcx) },
398                    parent: None,
399                }
400            }
401            TermKind::Const(ct) => {
402                if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.kind() {
403                    let origin = self.const_var_origin(vid).expect("expected unresolved const var");
404                    if let Some(def_id) = origin.param_def_id {
405                        return InferenceDiagnosticsData {
406                            name: self.tcx.item_name(def_id).to_string(),
407                            span: Some(origin.span),
408                            kind: UnderspecifiedArgKind::Const { is_parameter: true },
409                            parent: InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id),
410                        };
411                    }
412
413                    if true {
    if !!origin.span.is_dummy() {
        ::core::panicking::panic("assertion failed: !origin.span.is_dummy()")
    };
};debug_assert!(!origin.span.is_dummy());
414                    InferenceDiagnosticsData {
415                        name: Highlighted { highlight, ns: Namespace::ValueNS, tcx, value: ct }
416                            .to_string(),
417                        span: Some(origin.span),
418                        kind: UnderspecifiedArgKind::Const { is_parameter: false },
419                        parent: None,
420                    }
421                } else {
422                    // If we end up here the `FindInferSourceVisitor`
423                    // won't work, as its expected argument isn't an inference variable.
424                    //
425                    // FIXME: Ideally we should look into the generic constant
426                    // to figure out which inference var is actually unresolved so that
427                    // this path is unreachable.
428                    InferenceDiagnosticsData {
429                        name: Highlighted { highlight, ns: Namespace::ValueNS, tcx, value: ct }
430                            .to_string(),
431                        span: None,
432                        kind: UnderspecifiedArgKind::Const { is_parameter: false },
433                        parent: None,
434                    }
435                }
436            }
437        }
438    }
439
440    /// Used as a fallback in [TypeErrCtxt::emit_inference_failure_err]
441    /// in case we weren't able to get a better error.
442    fn bad_inference_failure_err(
443        &self,
444        span: Span,
445        arg_data: InferenceDiagnosticsData,
446        error_code: TypeAnnotationNeeded,
447    ) -> Diag<'a> {
448        let source_kind = "other";
449        let source_name = "";
450        let failure_span = None;
451        let subdiagnostic = None;
452        let bad_label = Some(arg_data.make_bad_error(span));
453        match error_code {
454            TypeAnnotationNeeded::E0282 => self.dcx().create_err(AnnotationRequired {
455                span,
456                source_kind,
457                source_name,
458                failure_span,
459                subdiagnostic,
460                bad_label,
461            }),
462            TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
463                span,
464                source_kind,
465                source_name,
466                failure_span,
467                subdiagnostic,
468                bad_label,
469            }),
470            TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn {
471                span,
472                source_kind,
473                source_name,
474                failure_span,
475                subdiagnostic,
476                bad_label,
477            }),
478        }
479    }
480
481    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("emit_inference_failure_err",
                                    "rustc_trait_selection::error_reporting::infer::need_type_info",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
                                    ::tracing_core::__macro_support::Option::Some(481u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("body_def_id")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("body_def_id");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("failure_span")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("failure_span");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("term")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("term");
                                                        NAME.as_str()
                                                    },
                                                    {
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("should_label_span")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("should_label_span");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&body_def_id)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&failure_span)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&term)
                                                            as &dyn ::tracing::field::Value)),
                                                (::tracing::__macro_support::Option::Some(&should_label_span
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: Diag<'a> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            self.emit_inference_failure_err_with_type_hint(body_def_id,
                failure_span, term, error_code, should_label_span, None)
        }
    }
}#[instrument(level = "debug", skip(self, error_code))]
482    pub fn emit_inference_failure_err(
483        &self,
484        body_def_id: LocalDefId,
485        failure_span: Span,
486        term: Term<'tcx>,
487        error_code: TypeAnnotationNeeded,
488        should_label_span: bool,
489    ) -> Diag<'a> {
490        self.emit_inference_failure_err_with_type_hint(
491            body_def_id,
492            failure_span,
493            term,
494            error_code,
495            should_label_span,
496            None,
497        )
498    }
499
500    pub fn emit_inference_failure_err_with_type_hint(
501        &self,
502        body_def_id: LocalDefId,
503        failure_span: Span,
504        term: Term<'tcx>,
505        error_code: TypeAnnotationNeeded,
506        should_label_span: bool,
507        ty: Option<Ty<'tcx>>,
508    ) -> Diag<'a> {
509        let term = self.deeply_resolve_ignoring_regions(term);
510        let arg_data = self
511            .extract_inference_diagnostics_data(term, ty::print::RegionHighlightMode::default());
512
513        let Some(typeck_results) = &self.typeck_results else {
514            // If we don't have any typeck results we're outside
515            // of a body, so we won't be able to get better info
516            // here.
517            return self.bad_inference_failure_err(failure_span, arg_data, error_code);
518        };
519
520        let mut local_visitor = FindInferSourceVisitor::new(self, typeck_results, term, ty);
521        let mut body_from_expansion = false;
522        if let Some(body) =
523            self.tcx.hir_maybe_body_owned_by(self.tcx.typeck_root_def_id_local(body_def_id))
524        {
525            let expr = body.value;
526            local_visitor.visit_expr(expr);
527            body_from_expansion = body.value.span.from_expansion();
528        }
529
530        let Some(InferSource { span, kind }) = local_visitor.infer_source else {
531            let silence = if let DefKind::AssocFn = self.tcx.def_kind(body_def_id)
532                && let parent = self.tcx.local_parent(body_def_id)
533                && self.tcx.is_automatically_derived(parent.to_def_id())
534                && let hir::Node::Item(item) = self.tcx.hir_node_by_def_id(parent)
535                && let hir::ItemKind::Impl(imp) = item.kind
536                && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = imp.self_ty.kind
537                && let Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, def_id) = path.res
538                && let Some(def_id) = def_id.as_local()
539                && let hir::Node::Item(item) = self.tcx.hir_node_by_def_id(def_id)
540            {
541                // We have encountered an inference error within an automatically derived `impl`,
542                // from a `#[derive(..)]` on an item that had a parse error. Because the parse
543                // error might have caused the expanded code to be malformed, we silence the
544                // inference error.
545                item.kind.recovered()
546            } else {
547                false
548            };
549            let mut err = self.bad_inference_failure_err(failure_span, arg_data, error_code);
550            if silence {
551                err.downgrade_to_delayed_bug();
552            }
553            return err;
554        };
555
556        let (source_kind, name, long_ty_path) = kind.ty_localized_msg(self);
557        let failure_span = if should_label_span && !failure_span.overlaps(span) {
558            Some(failure_span)
559        } else {
560            None
561        };
562
563        let subdiagnostic = kind.suggestion(
564            self.tcx,
565            self.infcx,
566            body_def_id,
567            term,
568            &arg_data,
569            typeck_results,
570            body_from_expansion,
571            span,
572        );
573        let delay_as_bug = match kind {
574            InferSourceKind::ClosureArg { kind, .. } if let PatKind::Err(_) = kind => {
575                // We will have already emitted an error about this pattern.
576                true
577            }
578            InferSourceKind::GenericArg { hir_id, argument_index, .. }
579                if let hir::Node::PathSegment(segment) = self.tcx.hir_node(hir_id)
580                    && let Some(args) = segment.args
581                    && let Some(hir::GenericArg::Type(ty)) = args.args.get(argument_index)
582                    && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
583                    && let Res::Err = path.res =>
584            {
585                // We have already emitted a name resolution error.
586                true
587            }
588            _ => false,
589        };
590
591        let mut err = match error_code {
592            TypeAnnotationNeeded::E0282 => self.dcx().create_err(AnnotationRequired {
593                span,
594                source_kind,
595                source_name: &name,
596                failure_span,
597                subdiagnostic,
598                bad_label: None,
599            }),
600            TypeAnnotationNeeded::E0283 => self.dcx().create_err(AmbiguousImpl {
601                span,
602                source_kind,
603                source_name: &name,
604                failure_span,
605                subdiagnostic,
606                bad_label: None,
607            }),
608            TypeAnnotationNeeded::E0284 => self.dcx().create_err(AmbiguousReturn {
609                span,
610                source_kind,
611                source_name: &name,
612                failure_span,
613                subdiagnostic,
614                bad_label: None,
615            }),
616        };
617        *err.long_ty_path() = long_ty_path;
618        if delay_as_bug {
619            // We have already emitted an earlier more relevant error.
620            err.downgrade_to_delayed_bug();
621        }
622        err
623    }
624}
625
626#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for InferSource<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "InferSource",
            "span", &self.span, "kind", &&self.kind)
    }
}Debug)]
627struct InferSource<'tcx> {
628    span: Span,
629    kind: InferSourceKind<'tcx>,
630}
631
632#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for InferSourceKind<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::LetBinding {
                insert_span: __self_0,
                pattern_name: __self_1,
                ty: __self_2,
                def_id: __self_3 } =>
                ::core::fmt::Formatter::debug_struct_field4_finish(f,
                    "LetBinding", "insert_span", __self_0, "pattern_name",
                    __self_1, "ty", __self_2, "def_id", &__self_3),
            Self::ClosureArg {
                insert_span: __self_0, ty: __self_1, kind: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "ClosureArg", "insert_span", __self_0, "ty", __self_1,
                    "kind", &__self_2),
            Self::GenericArg {
                insert_span: __self_0,
                argument_index: __self_1,
                generics_def_id: __self_2,
                def_id: __self_3,
                generic_args: __self_4,
                have_turbofish: __self_5,
                hir_id: __self_6 } => {
                let names: &'static _ =
                    &["insert_span", "argument_index", "generics_def_id",
                                "def_id", "generic_args", "have_turbofish", "hir_id"];
                let values: &[&dyn ::core::fmt::Debug] =
                    &[__self_0, __self_1, __self_2, __self_3, __self_4,
                                __self_5, &__self_6];
                ::core::fmt::Formatter::debug_struct_fields_finish(f,
                    "GenericArg", names, values)
            }
            Self::FullyQualifiedMethodCall {
                receiver: __self_0,
                successor: __self_1,
                args: __self_2,
                def_id: __self_3 } =>
                ::core::fmt::Formatter::debug_struct_field4_finish(f,
                    "FullyQualifiedMethodCall", "receiver", __self_0,
                    "successor", __self_1, "args", __self_2, "def_id",
                    &__self_3),
            Self::ClosureReturn {
                ty: __self_0, data: __self_1, should_wrap_expr: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "ClosureReturn", "ty", __self_0, "data", __self_1,
                    "should_wrap_expr", &__self_2),
        }
    }
}Debug)]
633enum InferSourceKind<'tcx> {
634    LetBinding {
635        insert_span: Span,
636        pattern_name: Option<Ident>,
637        ty: Ty<'tcx>,
638        def_id: Option<DefId>,
639    },
640    ClosureArg {
641        insert_span: Span,
642        ty: Ty<'tcx>,
643        kind: PatKind<'tcx>,
644    },
645    GenericArg {
646        insert_span: Span,
647        argument_index: usize,
648        generics_def_id: DefId,
649        def_id: DefId,
650        generic_args: &'tcx [GenericArg<'tcx>],
651        have_turbofish: bool,
652        hir_id: HirId,
653    },
654    FullyQualifiedMethodCall {
655        receiver: &'tcx Expr<'tcx>,
656        /// If the method has other arguments, this is ", " and the start of the first argument,
657        /// while for methods without arguments this is ")" and the end of the method call.
658        successor: (&'static str, BytePos),
659        args: GenericArgsRef<'tcx>,
660        def_id: DefId,
661    },
662    ClosureReturn {
663        ty: Ty<'tcx>,
664        data: &'tcx FnRetTy<'tcx>,
665        should_wrap_expr: Option<Span>,
666    },
667}
668
669impl<'tcx> InferSource<'tcx> {
670    fn from_expansion(&self) -> bool {
671        let source_from_expansion = match self.kind {
672            InferSourceKind::LetBinding { insert_span, .. }
673            | InferSourceKind::ClosureArg { insert_span, .. }
674            | InferSourceKind::GenericArg { insert_span, .. } => insert_span.from_expansion(),
675            InferSourceKind::FullyQualifiedMethodCall { receiver, .. } => {
676                receiver.span.from_expansion()
677            }
678            InferSourceKind::ClosureReturn { data, should_wrap_expr, .. } => {
679                data.span().from_expansion() || should_wrap_expr.is_some_and(Span::from_expansion)
680            }
681        };
682        source_from_expansion || self.span.from_expansion()
683    }
684}
685
686impl<'tcx> InferSourceKind<'tcx> {
687    fn ty_localized_msg(&self, infcx: &InferCtxt<'tcx>) -> (&'static str, String, Option<PathBuf>) {
688        let mut long_ty_path = None;
689        match *self {
690            InferSourceKind::LetBinding { ty, .. }
691            | InferSourceKind::ClosureArg { ty, .. }
692            | InferSourceKind::ClosureReturn { ty, .. } => {
693                if ty.is_closure() {
694                    ("closure", closure_as_fn_str(infcx, ty), long_ty_path)
695                } else if ty.is_ty_or_numeric_infer()
696                    || ty.is_primitive()
697                    || #[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
    ty::Adt(_, args) if args.terms().next().is_none() => true,
    _ => false,
}matches!(
698                        ty.kind(),
699                        ty::Adt(_, args)
700                        if args.terms().next().is_none()
701                    )
702                {
703                    // `ty` is either `_`, a primitive type like `u32` or a type with no type or
704                    // const parameters. We will not mention the type in the main inference error
705                    // message.
706                    ("other", String::new(), long_ty_path)
707                } else {
708                    ("normal", infcx.tcx.short_string(ty, &mut long_ty_path), long_ty_path)
709                }
710            }
711            // FIXME: We should be able to add some additional info here.
712            InferSourceKind::GenericArg { .. }
713            | InferSourceKind::FullyQualifiedMethodCall { .. } => {
714                ("other", String::new(), long_ty_path)
715            }
716        }
717    }
718
719    fn suggestion<'local>(
720        &self,
721        tcx: TyCtxt<'tcx>,
722        infcx: &InferCtxt<'tcx>,
723        body_def_id: LocalDefId,
724        term: Term<'tcx>,
725        arg_data: &'local InferenceDiagnosticsData,
726        typeck_results: &TypeckResults<'tcx>,
727        body_from_expansion: bool,
728        span: Span,
729    ) -> Option<SourceKindSubdiag<'local>>
730    where
731        'tcx: 'local,
732    {
733        let subdiag = match *self {
734            InferSourceKind::LetBinding { insert_span, pattern_name, ty, def_id } => {
735                SourceKindSubdiag::LetLike {
736                    span: insert_span,
737                    name: pattern_name.map(|name| name.to_string()).unwrap_or_else(String::new),
738                    x_kind: arg_data.where_x_is_kind(infcx, ty),
739                    prefix_kind: arg_data.kind.clone(),
740                    prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
741                    arg_name: &arg_data.name,
742                    kind: if pattern_name.is_some() { "with_pattern" } else { "other" },
743                    type_name: ty_to_string(infcx, ty, def_id),
744                }
745            }
746            InferSourceKind::ClosureArg { insert_span, ty, .. } => SourceKindSubdiag::LetLike {
747                span: insert_span,
748                name: String::new(),
749                x_kind: arg_data.where_x_is_kind(infcx, ty),
750                prefix_kind: arg_data.kind.clone(),
751                prefix: arg_data.kind.try_get_prefix().unwrap_or_default(),
752                arg_name: &arg_data.name,
753                kind: "closure",
754                type_name: ty_to_string(infcx, ty, None),
755            },
756            InferSourceKind::GenericArg {
757                insert_span,
758                argument_index,
759                generics_def_id,
760                def_id: _,
761                generic_args,
762                have_turbofish,
763                hir_id,
764            } => {
765                let generics = tcx.generics_of(generics_def_id);
766                let is_type = term.as_type().is_some();
767
768                let (parent_exists, parent_prefix, parent_name) =
769                    InferenceDiagnosticsParentData::for_parent_def_id(tcx, generics_def_id)
770                        .map_or((false, String::new(), String::new()), |parent| {
771                            (true, parent.prefix.to_string(), parent.name)
772                        });
773
774                let param = &generics.own_params[argument_index];
775                let param_name = param.name.to_string();
776
777                let mut used_fallback = false;
778                let args = if tcx.get_diagnostic_item(sym::iterator_collect_fn)
779                    == Some(generics_def_id)
780                {
781                    if let hir::Node::Expr(expr) = tcx.parent_hir_node(hir_id)
782                        && let hir::ExprKind::Call(expr, _args) = expr.kind
783                        && let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind
784                        && let Res::Def(DefKind::AssocFn, def_id) = path.res
785                        && let Some(try_trait) = tcx.lang_items().try_trait()
786                        && try_trait == tcx.parent(def_id)
787                        && let DefKind::Fn | DefKind::AssocFn =
788                            tcx.def_kind(body_def_id.to_def_id())
789                        && let ret = tcx
790                            .fn_sig(body_def_id.to_def_id())
791                            .instantiate_identity()
792                            .skip_binder()
793                            .output()
794                        && let ty::Adt(adt, _args) = ret.kind()
795                        && let Some(sym::Option | sym::Result) = tcx.get_diagnostic_name(adt.did())
796                    {
797                        if let Some(sym::Option) = tcx.get_diagnostic_name(adt.did()) {
798                            "Option<_>".to_string()
799                        } else {
800                            "Result<_, _>".to_string()
801                        }
802                    } else {
803                        "Vec<_>".to_string()
804                    }
805                } else {
806                    let mut p = fmt_printer(infcx, Namespace::TypeNS);
807                    p.comma_sep(generic_args.iter().copied().map(|arg| {
808                        if arg.is_suggestable(tcx, true) {
809                            used_fallback = true;
810                            return arg;
811                        }
812                        match arg.kind() {
813                            GenericArgKind::Lifetime(_) => ::rustc_span::macros::bug_impl(None, format_args!("unexpected lifetime"),
    Location::caller())bug!("unexpected lifetime"),
814                            GenericArgKind::Type(_) => infcx.next_ty_var(DUMMY_SP).into(),
815                            GenericArgKind::Const(_) => infcx.next_const_var(DUMMY_SP).into(),
816                        }
817                    }))
818                    .unwrap();
819                    p.into_buffer()
820                };
821
822                let suggestion = if have_turbofish || body_from_expansion {
823                    None
824                } else if generic_args.len() == 1 && used_fallback {
825                    match param.kind {
826                        GenericParamDefKind::Type { .. } => {
827                            Some(SpecifyGenericParamsSuggestion::GenericTypeSuggestion {
828                                span: insert_span,
829                                param: param_name.clone(),
830                            })
831                        }
832                        GenericParamDefKind::Const { .. } => {
833                            Some(SpecifyGenericParamsSuggestion::ConstGenericSuggestion {
834                                span: insert_span,
835                                param: param_name.clone(),
836                            })
837                        }
838                        GenericParamDefKind::Lifetime => {
839                            ::rustc_span::macros::bug_impl(None, format_args!("unexpected lifetime"),
    Location::caller())bug!("unexpected lifetime")
840                        }
841                    }
842                } else {
843                    Some(SpecifyGenericParamsSuggestion::GenericSuggestion {
844                        span: insert_span,
845                        arg_count: generic_args.len(),
846                        args,
847                    })
848                };
849
850                SourceKindSubdiag::Generic {
851                    span,
852                    is_type,
853                    param_name,
854                    parent_exists,
855                    parent_prefix,
856                    parent_name,
857                    suggestion,
858                }
859            }
860            InferSourceKind::FullyQualifiedMethodCall { receiver, successor, args, def_id } => {
861                let placeholder = Some(infcx.next_ty_var(DUMMY_SP));
862                let args = args.make_suggestable(tcx, true, placeholder)?;
863
864                let mut p = fmt_printer(infcx, Namespace::ValueNS);
865                p.print_def_path(def_id, args).unwrap();
866                let def_path = p.into_buffer();
867
868                // We only care about whether we have to add `&` or `&mut ` for now.
869                // This is the case if the last adjustment is a borrow and the
870                // first adjustment was not a builtin deref.
871                let adjustment = match typeck_results.expr_adjustments(receiver) {
872                    [
873                        Adjustment { kind: Adjust::Deref(DerefAdjustKind::Builtin), target: _ },
874                        ..,
875                        Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), target: _ },
876                    ] => "",
877                    [.., Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mut_)), target: _ }] => {
878                        hir::Mutability::from(*mut_).ref_prefix_str()
879                    }
880                    _ => "",
881                };
882
883                SourceKindSubdiag::new_fully_qualified(
884                    receiver.span,
885                    def_path,
886                    adjustment,
887                    successor,
888                )
889            }
890            InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => {
891                let placeholder = Some(infcx.next_ty_var(DUMMY_SP));
892
893                let ty = ty.make_suggestable(tcx, true, placeholder)?;
894                let ty_info = ty_to_string(infcx, ty, None);
895                SourceKindSubdiag::new_closure_return(ty_info, data, should_wrap_expr)
896            }
897        };
898
899        Some(subdiag)
900    }
901}
902
903#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for InsertableGenericArgs<'tcx> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["insert_span", "args", "generics_def_id", "def_id",
                        "have_turbofish", "hir_id"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.insert_span, &self.args, &self.generics_def_id,
                        &self.def_id, &self.have_turbofish, &&self.hir_id];
        ::core::fmt::Formatter::debug_struct_fields_finish(f,
            "InsertableGenericArgs", names, values)
    }
}Debug)]
904struct InsertableGenericArgs<'tcx> {
905    insert_span: Span,
906    args: GenericArgsRef<'tcx>,
907    generics_def_id: DefId,
908    def_id: DefId,
909    have_turbofish: bool,
910    hir_id: HirId,
911}
912
913/// A visitor which searches for the "best" spot to use in the inference error.
914///
915/// For this it walks over the hir body and tries to check all places where
916/// inference variables could be bound.
917///
918/// While doing so, the currently best spot is stored in `infer_source`.
919/// For details on how we rank spots, see [Self::source_cost]
920struct FindInferSourceVisitor<'a, 'tcx> {
921    tecx: &'a TypeErrCtxt<'a, 'tcx>,
922    typeck_results: &'a TypeckResults<'tcx>,
923
924    target: Term<'tcx>,
925    ty: Option<Ty<'tcx>>,
926
927    attempt: usize,
928    infer_source_cost: usize,
929    infer_source: Option<InferSource<'tcx>>,
930}
931
932impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
933    fn new(
934        tecx: &'a TypeErrCtxt<'a, 'tcx>,
935        typeck_results: &'a TypeckResults<'tcx>,
936        target: Term<'tcx>,
937        ty: Option<Ty<'tcx>>,
938    ) -> Self {
939        FindInferSourceVisitor {
940            tecx,
941            typeck_results,
942
943            target,
944            ty,
945
946            attempt: 0,
947            infer_source_cost: usize::MAX,
948            infer_source: None,
949        }
950    }
951
952    /// Computes cost for the given source.
953    ///
954    /// Sources with a small cost are prefer and should result
955    /// in a clearer and idiomatic suggestion.
956    fn source_cost(&self, source: &InferSource<'tcx>) -> usize {
957        #[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for CostCtxt<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for CostCtxt<'tcx> {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<TyCtxt<'tcx>>;
        *self
    }
}Clone, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for CostCtxt<'tcx> { }Copy)]
958        struct CostCtxt<'tcx> {
959            tcx: TyCtxt<'tcx>,
960        }
961        impl<'tcx> CostCtxt<'tcx> {
962            fn arg_cost(self, arg: GenericArg<'tcx>) -> usize {
963                match arg.kind() {
964                    GenericArgKind::Lifetime(_) => 0, // erased
965                    GenericArgKind::Type(ty) => self.ty_cost(ty),
966                    GenericArgKind::Const(_) => 3, // some non-zero value
967                }
968            }
969            fn ty_cost(self, ty: Ty<'tcx>) -> usize {
970                match *ty.kind() {
971                    ty::Closure(..) => 1000,
972                    ty::FnDef(..) => 150,
973                    ty::FnPtr(..) => 30,
974                    ty::Adt(def, args) => {
975                        5 + self
976                            .tcx
977                            .generics_of(def.did())
978                            .own_args_no_defaults(self.tcx, args)
979                            .iter()
980                            .map(|&arg| self.arg_cost(arg))
981                            .sum::<usize>()
982                    }
983                    ty::Tuple(args) => 5 + args.iter().map(|arg| self.ty_cost(arg)).sum::<usize>(),
984                    ty::Ref(_, ty, _) => 2 + self.ty_cost(ty),
985                    ty::Infer(..) => 0,
986                    _ => 1,
987                }
988            }
989        }
990
991        // The sources are listed in order of preference here.
992        let tcx = self.tecx.tcx;
993        let ctx = CostCtxt { tcx };
994        match source.kind {
995            InferSourceKind::LetBinding { ty, .. } => ctx.ty_cost(ty),
996            InferSourceKind::ClosureArg { ty, .. } => ctx.ty_cost(ty),
997            InferSourceKind::GenericArg { def_id, generic_args, .. } => {
998                let variant_cost = match tcx.def_kind(def_id) {
999                    // `None::<u32>` and friends are ugly.
1000                    DefKind::Variant | DefKind::Ctor(CtorOf::Variant, _) => 15,
1001                    _ => 10,
1002                };
1003                variant_cost + generic_args.iter().map(|&arg| ctx.arg_cost(arg)).sum::<usize>()
1004            }
1005            InferSourceKind::FullyQualifiedMethodCall { args, .. } => {
1006                20 + args.iter().map(|arg| ctx.arg_cost(arg)).sum::<usize>()
1007            }
1008            InferSourceKind::ClosureReturn { ty, should_wrap_expr, .. } => {
1009                30 + ctx.ty_cost(ty) + if should_wrap_expr.is_some() { 10 } else { 0 }
1010            }
1011        }
1012    }
1013
1014    /// Uses `fn source_cost` to determine whether this inference source is preferable to
1015    /// previous sources. We generally prefer earlier sources.
1016    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("update_infer_source",
                                    "rustc_trait_selection::error_reporting::infer::need_type_info",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
                                    ::tracing_core::__macro_support::Option::Some(1016u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("new_source")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("new_source");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&new_source)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            if new_source.from_expansion() { return; }
            let cost = self.source_cost(&new_source) + self.attempt;
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("event /rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs:1023",
                                    "rustc_trait_selection::error_reporting::infer::need_type_info",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
                                    ::tracing_core::__macro_support::Option::Some(1023u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("cost")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("cost");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::EVENT)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let enabled =
                    ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::DEBUG <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        {
                            let interest = __CALLSITE.interest();
                            !interest.is_never() &&
                                ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                    interest)
                        };
                if enabled {
                    (|value_set: ::tracing::field::ValueSet|
                                {
                                    let meta = __CALLSITE.metadata();
                                    ::tracing::Event::dispatch(meta, &value_set);
                                    ;
                                })({
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&cost)
                                                        as &dyn ::tracing::field::Value))])
                        });
                } else { ; }
            };
            self.attempt += 1;
            if let Some(InferSource {
                            kind: InferSourceKind::GenericArg { def_id: did, .. }, .. })
                            = self.infer_source &&
                        let InferSourceKind::LetBinding { ref ty, ref mut def_id, ..
                            } = new_source.kind && ty.is_ty_or_numeric_infer() {
                *def_id = Some(did);
            }
            if cost < self.infer_source_cost {
                self.infer_source_cost = cost;
                self.infer_source = Some(new_source);
            }
        }
    }
}#[instrument(level = "debug", skip(self))]
1017    fn update_infer_source(&mut self, mut new_source: InferSource<'tcx>) {
1018        if new_source.from_expansion() {
1019            return;
1020        }
1021
1022        let cost = self.source_cost(&new_source) + self.attempt;
1023        debug!(?cost);
1024        self.attempt += 1;
1025        if let Some(InferSource { kind: InferSourceKind::GenericArg { def_id: did, .. }, .. }) =
1026            self.infer_source
1027            && let InferSourceKind::LetBinding { ref ty, ref mut def_id, .. } = new_source.kind
1028            && ty.is_ty_or_numeric_infer()
1029        {
1030            // Customize the output so we talk about `let x: Vec<_> = iter.collect();` instead of
1031            // `let x: _ = iter.collect();`, as this is a very common case.
1032            *def_id = Some(did);
1033        }
1034
1035        if cost < self.infer_source_cost {
1036            self.infer_source_cost = cost;
1037            self.infer_source = Some(new_source);
1038        }
1039    }
1040
1041    fn node_args_opt(&self, hir_id: HirId) -> Option<GenericArgsRef<'tcx>> {
1042        let args = self.typeck_results.node_args_opt(hir_id);
1043        self.tecx.deeply_resolve_ignoring_regions(args)
1044    }
1045
1046    fn opt_node_type(&self, hir_id: HirId) -> Option<Ty<'tcx>> {
1047        let ty = self.typeck_results.node_type_opt(hir_id);
1048        self.tecx.deeply_resolve_ignoring_regions(ty)
1049    }
1050
1051    // Check whether this generic argument is the inference variable we
1052    // are looking for.
1053    fn generic_arg_is_target(&self, arg: GenericArg<'tcx>) -> bool {
1054        if arg == self.target.into() {
1055            return true;
1056        }
1057
1058        match (arg.kind(), self.target.kind()) {
1059            (GenericArgKind::Type(inner_ty), TermKind::Ty(target_ty)) => {
1060                use ty::{Infer, TyVar};
1061                match (inner_ty.kind(), target_ty.kind()) {
1062                    (&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => {
1063                        self.tecx.sub_unification_table_root_var(a_vid)
1064                            == self.tecx.sub_unification_table_root_var(b_vid)
1065                    }
1066                    _ => false,
1067                }
1068            }
1069            (GenericArgKind::Const(inner_ct), TermKind::Const(target_ct)) => {
1070                match (inner_ct.kind(), target_ct.kind()) {
1071                    (
1072                        ty::ConstKind::Infer(ty::InferConst::Var(a_vid)),
1073                        ty::ConstKind::Infer(ty::InferConst::Var(b_vid)),
1074                    ) => self.tecx.root_const_var(a_vid) == self.tecx.root_const_var(b_vid),
1075                    _ => false,
1076                }
1077            }
1078            _ => false,
1079        }
1080    }
1081
1082    /// Does this generic argument contain our target inference variable
1083    /// in a way which can be written by the user.
1084    fn generic_arg_contains_target(&self, arg: GenericArg<'tcx>) -> bool {
1085        let mut walker = arg.walk();
1086        while let Some(inner) = walker.next() {
1087            if self.generic_arg_is_target(inner) {
1088                return true;
1089            }
1090            match inner.kind() {
1091                GenericArgKind::Lifetime(_) => {}
1092                GenericArgKind::Type(ty) => {
1093                    if #[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
    ty::Alias(_, ty::AliasTy { kind: ty::Opaque { .. }, .. }) |
        ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) =>
        true,
    _ => false,
}matches!(
1094                        ty.kind(),
1095                        ty::Alias(_, ty::AliasTy { kind: ty::Opaque { .. }, .. })
1096                            | ty::Closure(..)
1097                            | ty::CoroutineClosure(..)
1098                            | ty::Coroutine(..)
1099                    ) {
1100                        // Opaque types can't be named by the user right now.
1101                        //
1102                        // Both the generic arguments of closures and coroutines can
1103                        // also not be named. We may want to only look into the closure
1104                        // signature in case it has no captures, as that can be represented
1105                        // using `fn(T) -> R`.
1106
1107                        // FIXME(type_alias_impl_trait): These opaque types
1108                        // can actually be named, so it would make sense to
1109                        // adjust this case and add a test for it.
1110                        walker.skip_current_subtree();
1111                    }
1112                }
1113                GenericArgKind::Const(ct) => {
1114                    if #[allow(non_exhaustive_omitted_patterns)] match ct.kind() {
    ty::ConstKind::Alias(..) => true,
    _ => false,
}matches!(ct.kind(), ty::ConstKind::Alias(..)) {
1115                        // You can't write the generic arguments for
1116                        // alias constants.
1117                        walker.skip_current_subtree();
1118                    }
1119                }
1120            }
1121        }
1122        false
1123    }
1124
1125    fn expr_inferred_arg_iter(
1126        &self,
1127        expr: &'tcx hir::Expr<'tcx>,
1128    ) -> Box<dyn Iterator<Item = InsertableGenericArgs<'tcx>> + 'a> {
1129        let tcx = self.tecx.tcx;
1130        match expr.kind {
1131            hir::ExprKind::Path(ref path) => {
1132                if let Some(args) = self.node_args_opt(expr.hir_id) {
1133                    return self.path_inferred_arg_iter(expr.hir_id, args, path);
1134                }
1135            }
1136            // FIXME(#98711): Ideally we would also deal with type relative
1137            // paths here, even if that is quite rare.
1138            //
1139            // See the `need_type_info/expr-struct-type-relative-gat.rs` test
1140            // for an example where that would be needed.
1141            //
1142            // However, the `type_dependent_def_id` for `Self::Output` in an
1143            // impl is currently the `DefId` of `Output` in the trait definition
1144            // which makes this somewhat difficult and prevents us from just
1145            // using `self.path_inferred_arg_iter` here.
1146            hir::ExprKind::Struct(&hir::QPath::Resolved(_self_ty, path), _, _)
1147            // FIXME(TaKO8Ki): Ideally we should support other kinds,
1148            // such as `TyAlias` or `AssocTy`. For that we have to map
1149            // back from the self type to the type alias though. That's difficult.
1150            //
1151            // See the `need_type_info/issue-103053.rs` test for
1152            // a example.
1153            if #[allow(non_exhaustive_omitted_patterns)] match path.res {
    Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _) => true,
    _ => false,
}matches!(path.res, Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)) => {
1154                if let Some(ty) = self.opt_node_type(expr.hir_id)
1155                    && let ty::Adt(_, args) = ty.kind()
1156                {
1157                    return Box::new(self.resolved_path_inferred_arg_iter(path, args));
1158                }
1159            }
1160            hir::ExprKind::MethodCall(segment, ..) => {
1161                if let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id) {
1162                    let generics = tcx.generics_of(def_id);
1163                    let insertable = try {
1164                        if generics.has_impl_trait() {
1165                            None?
1166                        }
1167                        let args = self.node_args_opt(expr.hir_id)?;
1168                        let span = tcx.hir_span(segment.hir_id);
1169                        let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
1170                        let have_turbofish = segment.args.is_some_and(|args| {
1171                            args.args.iter().any(|arg| arg.is_ty_or_const())
1172                        });
1173                        InsertableGenericArgs {
1174                            insert_span,
1175                            args,
1176                            generics_def_id: def_id,
1177                            def_id,
1178                            have_turbofish,
1179                            hir_id: expr.hir_id,
1180                        }
1181                    };
1182                    return Box::new(insertable.into_iter());
1183                }
1184            }
1185            _ => {}
1186        }
1187
1188        Box::new(iter::empty())
1189    }
1190
1191    fn resolved_path_inferred_arg_iter(
1192        &self,
1193        path: &'tcx hir::Path<'tcx>,
1194        args: GenericArgsRef<'tcx>,
1195    ) -> impl Iterator<Item = InsertableGenericArgs<'tcx>> + 'tcx {
1196        let tcx = self.tecx.tcx;
1197        let have_turbofish = path.segments.iter().any(|segment| {
1198            segment.args.is_some_and(|args| args.args.iter().any(|arg| arg.is_ty_or_const()))
1199        });
1200        // The last segment of a path often has `Res::Err` and the
1201        // correct `Res` is the one of the whole path.
1202        //
1203        // FIXME: We deal with that one separately for now,
1204        // would be good to remove this special case.
1205        let last_segment_using_path_data = try {
1206            let generics_def_id = tcx.res_generics_def_id(path.res)?;
1207            let generics = tcx.generics_of(generics_def_id);
1208            if generics.has_impl_trait() {
1209                do yeet ();
1210            }
1211            let insert_span =
1212                path.segments.last().unwrap().ident.span.shrink_to_hi().with_hi(path.span.hi());
1213            InsertableGenericArgs {
1214                insert_span,
1215                args,
1216                generics_def_id,
1217                def_id: path.res.def_id(),
1218                have_turbofish,
1219                hir_id: path.segments.last().unwrap().hir_id,
1220            }
1221        };
1222
1223        path.segments
1224            .iter()
1225            .filter_map(move |segment| {
1226                let res = segment.res;
1227                let generics_def_id = tcx.res_generics_def_id(res)?;
1228                let generics = tcx.generics_of(generics_def_id);
1229                if generics.has_impl_trait() {
1230                    return None;
1231                }
1232                let span = tcx.hir_span(segment.hir_id);
1233                let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
1234                Some(InsertableGenericArgs {
1235                    insert_span,
1236                    args,
1237                    generics_def_id,
1238                    def_id: res.def_id(),
1239                    have_turbofish,
1240                    hir_id: segment.hir_id,
1241                })
1242            })
1243            .chain(last_segment_using_path_data)
1244    }
1245
1246    fn path_inferred_arg_iter(
1247        &self,
1248        hir_id: HirId,
1249        args: GenericArgsRef<'tcx>,
1250        qpath: &'tcx hir::QPath<'tcx>,
1251    ) -> Box<dyn Iterator<Item = InsertableGenericArgs<'tcx>> + 'a> {
1252        let tcx = self.tecx.tcx;
1253        match qpath {
1254            hir::QPath::Resolved(_self_ty, path) => {
1255                Box::new(self.resolved_path_inferred_arg_iter(path, args))
1256            }
1257            hir::QPath::TypeRelative(ty, segment) => {
1258                let Some(def_id) = self.typeck_results.type_dependent_def_id(hir_id) else {
1259                    return Box::new(iter::empty());
1260                };
1261
1262                let generics = tcx.generics_of(def_id);
1263                let segment = if !segment.infer_args || generics.has_impl_trait() {
1264                    None
1265                } else {
1266                    let span = tcx.hir_span(segment.hir_id);
1267                    let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
1268                    Some(InsertableGenericArgs {
1269                        insert_span,
1270                        args,
1271                        generics_def_id: def_id,
1272                        def_id,
1273                        have_turbofish: false,
1274                        hir_id: segment.hir_id,
1275                    })
1276                };
1277
1278                let parent_def_id = generics.parent.unwrap();
1279                if let DefKind::Impl { .. } = tcx.def_kind(parent_def_id) {
1280                    let parent_ty =
1281                        tcx.type_of(parent_def_id).instantiate(tcx, args).skip_norm_wip();
1282                    match (parent_ty.kind(), &ty.kind) {
1283                        (
1284                            ty::Adt(def, args),
1285                            hir::TyKind::Path(hir::QPath::Resolved(_self_ty, path)),
1286                        ) => {
1287                            if tcx.res_generics_def_id(path.res) != Some(def.did()) {
1288                                match path.res {
1289                                    Res::Def(DefKind::TyAlias, _) => {
1290                                        // FIXME: Ideally we should support this. For that
1291                                        // we have to map back from the self type to the
1292                                        // type alias though. That's difficult.
1293                                        //
1294                                        // See the `need_type_info/type-alias.rs` test for
1295                                        // some examples.
1296                                    }
1297                                    // There cannot be inference variables in the self type,
1298                                    // so there's nothing for us to do here.
1299                                    Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {}
1300                                    _ => {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs:1300",
                        "rustc_trait_selection::error_reporting::infer::need_type_info",
                        ::tracing::Level::WARN,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
                        ::tracing_core::__macro_support::Option::Some(1300u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::WARN <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("unexpected path: def={0:?} args={1:?} path={2:?}",
                                                    def, args, path) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
}warn!(
1301                                        "unexpected path: def={:?} args={:?} path={:?}",
1302                                        def, args, path,
1303                                    ),
1304                                }
1305                            } else {
1306                                return Box::new(
1307                                    self.resolved_path_inferred_arg_iter(path, args).chain(segment),
1308                                );
1309                            }
1310                        }
1311                        _ => (),
1312                    }
1313                }
1314
1315                Box::new(segment.into_iter())
1316            }
1317        }
1318    }
1319}
1320
1321impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
1322    type NestedFilter = nested_filter::OnlyBodies;
1323
1324    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
1325        self.tecx.tcx
1326    }
1327
1328    fn visit_local(&mut self, local: &'tcx LetStmt<'tcx>) {
1329        intravisit::walk_local(self, local);
1330
1331        if let Some(mut ty) = self.opt_node_type(local.hir_id) {
1332            if self.generic_arg_contains_target(ty.into()) {
1333                fn get_did(
1334                    typeck_results: &TypeckResults<'_>,
1335                    expr: &hir::Expr<'_>,
1336                ) -> Option<DefId> {
1337                    match expr.kind {
1338                        hir::ExprKind::Match(expr, _, hir::MatchSource::TryDesugar(_))
1339                            if let hir::ExprKind::Call(_, [expr]) = expr.kind =>
1340                        {
1341                            get_did(typeck_results, expr)
1342                        }
1343                        hir::ExprKind::Call(base, _args)
1344                            if let hir::ExprKind::Path(path) = base.kind
1345                                && let hir::QPath::Resolved(_, path) = path
1346                                && let Res::Def(_, did) = path.res =>
1347                        {
1348                            Some(did)
1349                        }
1350                        hir::ExprKind::MethodCall(..)
1351                            if let Some(did) =
1352                                typeck_results.type_dependent_def_id(expr.hir_id) =>
1353                        {
1354                            Some(did)
1355                        }
1356                        _ => None,
1357                    }
1358                }
1359                if let Some(t) = self.ty
1360                    && ty.has_infer()
1361                {
1362                    ty = t;
1363                }
1364                if let LocalSource::Normal = local.source
1365                    && local.ty.is_none()
1366                {
1367                    self.update_infer_source(InferSource {
1368                        span: local.pat.span,
1369                        kind: InferSourceKind::LetBinding {
1370                            insert_span: local.pat.span.shrink_to_hi(),
1371                            pattern_name: local.pat.simple_ident(),
1372                            ty,
1373                            def_id: local.init.and_then(|expr| get_did(self.typeck_results, expr)),
1374                        },
1375                    });
1376                }
1377            }
1378        }
1379    }
1380
1381    /// For closures, we first visit the parameters and then the content,
1382    /// as we prefer those.
1383    fn visit_body(&mut self, body: &Body<'tcx>) {
1384        for param in body.params {
1385            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs:1385",
                        "rustc_trait_selection::error_reporting::infer::need_type_info",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
                        ::tracing_core::__macro_support::Option::Some(1385u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("param: span {0:?}, ty_span {1:?}, pat.span {2:?}",
                                                    param.span, param.ty_span, param.pat.span) as
                                            &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(
1386                "param: span {:?}, ty_span {:?}, pat.span {:?}",
1387                param.span, param.ty_span, param.pat.span
1388            );
1389            if param.ty_span != param.pat.span {
1390                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs:1390",
                        "rustc_trait_selection::error_reporting::infer::need_type_info",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
                        ::tracing_core::__macro_support::Option::Some(1390u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("skipping param: has explicit type")
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("skipping param: has explicit type");
1391                continue;
1392            }
1393
1394            let Some(param_ty) = self.opt_node_type(param.hir_id) else { continue };
1395
1396            if self.generic_arg_contains_target(param_ty.into()) {
1397                self.update_infer_source(InferSource {
1398                    span: param.pat.span,
1399                    kind: InferSourceKind::ClosureArg {
1400                        insert_span: param.pat.span.shrink_to_hi(),
1401                        ty: param_ty,
1402                        kind: param.pat.kind,
1403                    },
1404                })
1405            }
1406        }
1407        intravisit::walk_body(self, body);
1408    }
1409
1410    {}
#[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("visit_expr",
                                    "rustc_trait_selection::error_reporting::infer::need_type_info",
                                    ::tracing::Level::DEBUG,
                                    ::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
                                    ::tracing_core::__macro_support::Option::Some(1410u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("expr")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("expr");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&expr)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return: () = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let tcx = self.tecx.tcx;
            match expr.kind {
                ExprKind::Call(func, args) => {
                    for arg in args { self.visit_expr(arg); }
                    self.visit_expr(func);
                }
                _ => intravisit::walk_expr(self, expr),
            }
            for args in self.expr_inferred_arg_iter(expr) {
                {
                    use ::tracing::__macro_support::Callsite as _;
                    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                        {
                            static META: ::tracing::Metadata<'static> =
                                {
                                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs:1426",
                                        "rustc_trait_selection::error_reporting::infer::need_type_info",
                                        ::tracing::Level::DEBUG,
                                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/6f5da406b56c2db6607202b63daee73aa8c61297/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs"),
                                        ::tracing_core::__macro_support::Option::Some(1426u32),
                                        ::tracing_core::__macro_support::Option::Some("rustc_trait_selection::error_reporting::infer::need_type_info"),
                                        ::tracing_core::field::FieldSet::new(&[{
                                                            const NAME:
                                                                ::tracing::__macro_support::FieldName<{
                                                                    ::tracing::__macro_support::FieldName::len("args")
                                                                }> =
                                                                ::tracing::__macro_support::FieldName::new("args");
                                                            NAME.as_str()
                                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                        ::tracing::metadata::Kind::EVENT)
                                };
                            ::tracing::callsite::DefaultCallsite::new(&META)
                        };
                    let enabled =
                        ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::DEBUG <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            {
                                let interest = __CALLSITE.interest();
                                !interest.is_never() &&
                                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                                        interest)
                            };
                    if enabled {
                        (|value_set: ::tracing::field::ValueSet|
                                    {
                                        let meta = __CALLSITE.metadata();
                                        ::tracing::Event::dispatch(meta, &value_set);
                                        ;
                                    })({
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&args)
                                                            as &dyn ::tracing::field::Value))])
                            });
                    } else { ; }
                };
                let InsertableGenericArgs {
                        insert_span,
                        args,
                        generics_def_id,
                        def_id,
                        have_turbofish,
                        hir_id } = args;
                let generics = tcx.generics_of(generics_def_id);
                if let Some(argument_index) =
                        generics.own_args(args).iter().position(|&arg|
                                self.generic_arg_contains_target(arg)) {
                    let args = self.tecx.deeply_resolve_ignoring_regions(args);
                    let generic_args =
                        &generics.own_args_no_defaults(tcx,
                                    args)[generics.own_counts().lifetimes..];
                    let span =
                        match expr.kind {
                            ExprKind::MethodCall(segment, ..) if
                                have_turbofish && let Some(hir_args) = segment.args &&
                                        let Some(idx) =
                                            argument_index.checked_sub(generics.own_counts().lifetimes)
                                    &&
                                    let Some(arg) =
                                        hir_args.args.get(hir_args.num_lifetime_args() + idx) => {
                                arg.span()
                            }
                            ExprKind::MethodCall(segment, ..) => segment.ident.span,
                            _ => expr.span,
                        };
                    let mut argument_index = argument_index;
                    if generics.has_own_self() { argument_index += 1; }
                    self.update_infer_source(InferSource {
                            span,
                            kind: InferSourceKind::GenericArg {
                                insert_span,
                                argument_index,
                                generics_def_id,
                                def_id,
                                generic_args,
                                have_turbofish,
                                hir_id,
                            },
                        });
                }
            }
            if let Some(node_ty) = self.opt_node_type(expr.hir_id) {
                if let (&ExprKind::Closure(&Closure {
                        fn_decl, body, fn_decl_span, .. }), ty::Closure(_, args)) =
                        (&expr.kind, node_ty.kind()) {
                    let output = args.as_closure().sig().output().skip_binder();
                    if self.generic_arg_contains_target(output.into()) {
                        let body = self.tecx.tcx.hir_body(body);
                        let should_wrap_expr =
                            if #[allow(non_exhaustive_omitted_patterns)] match body.value.kind
                                    {
                                    ExprKind::Block(..) => true,
                                    _ => false,
                                } {
                                None
                            } else { Some(body.value.span.shrink_to_hi()) };
                        self.update_infer_source(InferSource {
                                span: fn_decl_span,
                                kind: InferSourceKind::ClosureReturn {
                                    ty: output,
                                    data: &fn_decl.output,
                                    should_wrap_expr,
                                },
                            })
                    }
                }
            }
            let has_impl_trait =
                |def_id|
                    {
                        iter::successors(Some(tcx.generics_of(def_id)),
                                |generics|
                                    {
                                        generics.parent.map(|def_id| tcx.generics_of(def_id))
                                    }).any(|generics| generics.has_impl_trait())
                    };
            if let ExprKind::MethodCall(path, receiver, method_args, span) =
                                            expr.kind &&
                                        let Some(args) = self.node_args_opt(expr.hir_id) &&
                                    args.iter().any(|arg| self.generic_arg_contains_target(arg))
                                &&
                                let Some(def_id) =
                                    self.typeck_results.type_dependent_def_id(expr.hir_id) &&
                            self.tecx.tcx.trait_of_assoc(def_id).is_some() &&
                        !has_impl_trait(def_id) &&
                    tcx.hir_opt_delegation_sig_id(expr.hir_id.owner.def_id).is_none()
                {
                let successor =
                    method_args.get(0).map_or_else(|| (")", span.hi()),
                        |arg| (", ", arg.span.lo()));
                let args = self.tecx.deeply_resolve_ignoring_regions(args);
                self.update_infer_source(InferSource {
                        span: path.ident.span,
                        kind: InferSourceKind::FullyQualifiedMethodCall {
                            receiver,
                            successor,
                            args,
                            def_id,
                        },
                    })
            }
        }
    }
}#[instrument(level = "debug", skip(self))]
1411    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
1412        let tcx = self.tecx.tcx;
1413        match expr.kind {
1414            // When encountering `func(arg)` first look into `arg` and then `func`,
1415            // as `arg` is "more specific".
1416            ExprKind::Call(func, args) => {
1417                for arg in args {
1418                    self.visit_expr(arg);
1419                }
1420                self.visit_expr(func);
1421            }
1422            _ => intravisit::walk_expr(self, expr),
1423        }
1424
1425        for args in self.expr_inferred_arg_iter(expr) {
1426            debug!(?args);
1427            let InsertableGenericArgs {
1428                insert_span,
1429                args,
1430                generics_def_id,
1431                def_id,
1432                have_turbofish,
1433                hir_id,
1434            } = args;
1435            let generics = tcx.generics_of(generics_def_id);
1436            if let Some(argument_index) = generics
1437                .own_args(args)
1438                .iter()
1439                .position(|&arg| self.generic_arg_contains_target(arg))
1440            {
1441                let args = self.tecx.deeply_resolve_ignoring_regions(args);
1442                let generic_args =
1443                    &generics.own_args_no_defaults(tcx, args)[generics.own_counts().lifetimes..];
1444                let span = match expr.kind {
1445                    ExprKind::MethodCall(segment, ..)
1446                        if have_turbofish
1447                            && let Some(hir_args) = segment.args
1448                            && let Some(idx) =
1449                                argument_index.checked_sub(generics.own_counts().lifetimes)
1450                            && let Some(arg) =
1451                                hir_args.args.get(hir_args.num_lifetime_args() + idx) =>
1452                    {
1453                        arg.span()
1454                    }
1455                    ExprKind::MethodCall(segment, ..) => segment.ident.span,
1456                    _ => expr.span,
1457                };
1458                let mut argument_index = argument_index;
1459                if generics.has_own_self() {
1460                    argument_index += 1;
1461                }
1462
1463                self.update_infer_source(InferSource {
1464                    span,
1465                    kind: InferSourceKind::GenericArg {
1466                        insert_span,
1467                        argument_index,
1468                        generics_def_id,
1469                        def_id,
1470                        generic_args,
1471                        have_turbofish,
1472                        hir_id,
1473                    },
1474                });
1475            }
1476        }
1477
1478        if let Some(node_ty) = self.opt_node_type(expr.hir_id) {
1479            if let (
1480                &ExprKind::Closure(&Closure { fn_decl, body, fn_decl_span, .. }),
1481                ty::Closure(_, args),
1482            ) = (&expr.kind, node_ty.kind())
1483            {
1484                let output = args.as_closure().sig().output().skip_binder();
1485                if self.generic_arg_contains_target(output.into()) {
1486                    let body = self.tecx.tcx.hir_body(body);
1487                    let should_wrap_expr = if matches!(body.value.kind, ExprKind::Block(..)) {
1488                        None
1489                    } else {
1490                        Some(body.value.span.shrink_to_hi())
1491                    };
1492                    self.update_infer_source(InferSource {
1493                        span: fn_decl_span,
1494                        kind: InferSourceKind::ClosureReturn {
1495                            ty: output,
1496                            data: &fn_decl.output,
1497                            should_wrap_expr,
1498                        },
1499                    })
1500                }
1501            }
1502        }
1503
1504        let has_impl_trait = |def_id| {
1505            iter::successors(Some(tcx.generics_of(def_id)), |generics| {
1506                generics.parent.map(|def_id| tcx.generics_of(def_id))
1507            })
1508            .any(|generics| generics.has_impl_trait())
1509        };
1510        if let ExprKind::MethodCall(path, receiver, method_args, span) = expr.kind
1511            && let Some(args) = self.node_args_opt(expr.hir_id)
1512            && args.iter().any(|arg| self.generic_arg_contains_target(arg))
1513            && let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id)
1514            && self.tecx.tcx.trait_of_assoc(def_id).is_some()
1515            && !has_impl_trait(def_id)
1516            // FIXME(fn_delegation): In delegation item argument spans are equal to last path
1517            // segment. This leads to ICE's when emitting `multipart_suggestion`.
1518            && tcx.hir_opt_delegation_sig_id(expr.hir_id.owner.def_id).is_none()
1519        {
1520            let successor =
1521                method_args.get(0).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo()));
1522            let args = self.tecx.deeply_resolve_ignoring_regions(args);
1523            self.update_infer_source(InferSource {
1524                span: path.ident.span,
1525                kind: InferSourceKind::FullyQualifiedMethodCall {
1526                    receiver,
1527                    successor,
1528                    args,
1529                    def_id,
1530                },
1531            })
1532        }
1533    }
1534}