rustc_hir_analysis/
collect.rs

1//! "Collection" is the process of determining the type and other external
2//! details of each item in Rust. Collection is specifically concerned
3//! with *inter-procedural* things -- for example, for a function
4//! definition, collection will figure out the type and signature of the
5//! function, but it will not visit the *body* of the function in any way,
6//! nor examine type annotations on local variables (that's the job of
7//! type *checking*).
8//!
9//! Collecting is ultimately defined by a bundle of queries that
10//! inquire after various facts about the items in the crate (e.g.,
11//! `type_of`, `generics_of`, `predicates_of`, etc). See the `provide` function
12//! for the full set.
13//!
14//! At present, however, we do run collection across all items in the
15//! crate as a kind of pass. This should eventually be factored away.
16
17use std::cell::Cell;
18use std::iter;
19use std::ops::Bound;
20
21use rustc_abi::ExternAbi;
22use rustc_ast::Recovered;
23use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
24use rustc_data_structures::unord::UnordMap;
25use rustc_errors::{
26    Applicability, Diag, DiagCtxtHandle, E0228, ErrorGuaranteed, StashKey, struct_span_code_err,
27};
28use rustc_hir::def::DefKind;
29use rustc_hir::def_id::{DefId, LocalDefId};
30use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt, walk_generics};
31use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind};
32use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
33use rustc_infer::traits::ObligationCause;
34use rustc_middle::hir::nested_filter;
35use rustc_middle::query::Providers;
36use rustc_middle::ty::util::{Discr, IntTypeExt};
37use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, Ty, TyCtxt, TypingMode, fold_regions};
38use rustc_middle::{bug, span_bug};
39use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
40use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName;
41use rustc_trait_selection::infer::InferCtxtExt;
42use rustc_trait_selection::traits::ObligationCtxt;
43use tracing::{debug, instrument};
44
45use crate::check::intrinsic::intrinsic_operation_unsafety;
46use crate::errors;
47use crate::hir_ty_lowering::errors::assoc_kind_str;
48use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer, RegionInferReason};
49
50pub(crate) mod dump;
51mod generics_of;
52mod item_bounds;
53mod predicates_of;
54mod resolve_bound_vars;
55mod type_of;
56
57///////////////////////////////////////////////////////////////////////////
58
59pub(crate) fn provide(providers: &mut Providers) {
60    resolve_bound_vars::provide(providers);
61    *providers = Providers {
62        type_of: type_of::type_of,
63        type_of_opaque: type_of::type_of_opaque,
64        type_alias_is_lazy: type_of::type_alias_is_lazy,
65        item_bounds: item_bounds::item_bounds,
66        explicit_item_bounds: item_bounds::explicit_item_bounds,
67        item_self_bounds: item_bounds::item_self_bounds,
68        explicit_item_self_bounds: item_bounds::explicit_item_self_bounds,
69        item_non_self_bounds: item_bounds::item_non_self_bounds,
70        impl_super_outlives: item_bounds::impl_super_outlives,
71        generics_of: generics_of::generics_of,
72        predicates_of: predicates_of::predicates_of,
73        explicit_predicates_of: predicates_of::explicit_predicates_of,
74        explicit_super_predicates_of: predicates_of::explicit_super_predicates_of,
75        explicit_implied_predicates_of: predicates_of::explicit_implied_predicates_of,
76        explicit_supertraits_containing_assoc_item:
77            predicates_of::explicit_supertraits_containing_assoc_item,
78        trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
79        const_conditions: predicates_of::const_conditions,
80        explicit_implied_const_bounds: predicates_of::explicit_implied_const_bounds,
81        type_param_predicates: predicates_of::type_param_predicates,
82        trait_def,
83        adt_def,
84        fn_sig,
85        impl_trait_header,
86        coroutine_kind,
87        coroutine_for_closure,
88        opaque_ty_origin,
89        rendered_precise_capturing_args,
90        const_param_default,
91        ..*providers
92    };
93}
94
95///////////////////////////////////////////////////////////////////////////
96
97/// Context specific to some particular item. This is what implements [`HirTyLowerer`].
98///
99/// # `ItemCtxt` vs `FnCtxt`
100///
101/// `ItemCtxt` is primarily used to type-check item signatures and lower them
102/// from HIR to their [`ty::Ty`] representation, which is exposed using [`HirTyLowerer`].
103/// It's also used for the bodies of items like structs where the body (the fields)
104/// are just signatures.
105///
106/// This is in contrast to `FnCtxt`, which is used to type-check bodies of
107/// functions, closures, and `const`s -- anywhere that expressions and statements show up.
108///
109/// An important thing to note is that `ItemCtxt` does no inference -- it has no [`InferCtxt`] --
110/// while `FnCtxt` does do inference.
111///
112/// [`InferCtxt`]: rustc_infer::infer::InferCtxt
113///
114/// # Trait predicates
115///
116/// `ItemCtxt` has information about the predicates that are defined
117/// on the trait. Unfortunately, this predicate information is
118/// available in various different forms at various points in the
119/// process. So we can't just store a pointer to e.g., the HIR or the
120/// parsed ty form, we have to be more flexible. To this end, the
121/// `ItemCtxt` is parameterized by a `DefId` that it uses to satisfy
122/// `probe_ty_param_bounds` requests, drawing the information from
123/// the HIR (`hir::Generics`), recursively.
124pub(crate) struct ItemCtxt<'tcx> {
125    tcx: TyCtxt<'tcx>,
126    item_def_id: LocalDefId,
127    tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
128}
129
130///////////////////////////////////////////////////////////////////////////
131
132#[derive(Default)]
133pub(crate) struct HirPlaceholderCollector {
134    pub spans: Vec<Span>,
135    // If any of the spans points to a const infer var, then suppress any messages
136    // that may try to turn that const infer into a type parameter.
137    pub may_contain_const_infer: bool,
138}
139
140impl<'v> Visitor<'v> for HirPlaceholderCollector {
141    fn visit_infer(&mut self, _inf_id: HirId, inf_span: Span, kind: InferKind<'v>) -> Self::Result {
142        self.spans.push(inf_span);
143
144        if let InferKind::Const(_) | InferKind::Ambig(_) = kind {
145            self.may_contain_const_infer = true;
146        }
147    }
148}
149
150pub(crate) struct CollectItemTypesVisitor<'tcx> {
151    pub tcx: TyCtxt<'tcx>,
152}
153
154/// If there are any placeholder types (`_`), emit an error explaining that this is not allowed
155/// and suggest adding type parameters in the appropriate place, taking into consideration any and
156/// all already existing generic type parameters to avoid suggesting a name that is already in use.
157pub(crate) fn placeholder_type_error<'tcx>(
158    cx: &dyn HirTyLowerer<'tcx>,
159    generics: Option<&hir::Generics<'_>>,
160    placeholder_types: Vec<Span>,
161    suggest: bool,
162    hir_ty: Option<&hir::Ty<'_>>,
163    kind: &'static str,
164) {
165    if placeholder_types.is_empty() {
166        return;
167    }
168
169    placeholder_type_error_diag(cx, generics, placeholder_types, vec![], suggest, hir_ty, kind)
170        .emit();
171}
172
173pub(crate) fn placeholder_type_error_diag<'cx, 'tcx>(
174    cx: &'cx dyn HirTyLowerer<'tcx>,
175    generics: Option<&hir::Generics<'_>>,
176    placeholder_types: Vec<Span>,
177    additional_spans: Vec<Span>,
178    suggest: bool,
179    hir_ty: Option<&hir::Ty<'_>>,
180    kind: &'static str,
181) -> Diag<'cx> {
182    if placeholder_types.is_empty() {
183        return bad_placeholder(cx, additional_spans, kind);
184    }
185
186    let params = generics.map(|g| g.params).unwrap_or_default();
187    let type_name = params.next_type_param_name(None);
188    let mut sugg: Vec<_> =
189        placeholder_types.iter().map(|sp| (*sp, (*type_name).to_string())).collect();
190
191    if let Some(generics) = generics {
192        if let Some(span) = params.iter().find_map(|arg| match arg.name {
193            hir::ParamName::Plain(Ident { name: kw::Underscore, span }) => Some(span),
194            _ => None,
195        }) {
196            // Account for `_` already present in cases like `struct S<_>(_);` and suggest
197            // `struct S<T>(T);` instead of `struct S<_, T>(T);`.
198            sugg.push((span, (*type_name).to_string()));
199        } else if let Some(span) = generics.span_for_param_suggestion() {
200            // Account for bounds, we want `fn foo<T: E, K>(_: K)` not `fn foo<T, K: E>(_: K)`.
201            sugg.push((span, format!(", {type_name}")));
202        } else {
203            sugg.push((generics.span, format!("<{type_name}>")));
204        }
205    }
206
207    let mut err =
208        bad_placeholder(cx, placeholder_types.into_iter().chain(additional_spans).collect(), kind);
209
210    // Suggest, but only if it is not a function in const or static
211    if suggest {
212        let mut is_fn = false;
213        let mut is_const_or_static = false;
214
215        if let Some(hir_ty) = hir_ty
216            && let hir::TyKind::BareFn(_) = hir_ty.kind
217        {
218            is_fn = true;
219
220            // Check if parent is const or static
221            is_const_or_static = matches!(
222                cx.tcx().parent_hir_node(hir_ty.hir_id),
223                Node::Item(&hir::Item {
224                    kind: hir::ItemKind::Const(..) | hir::ItemKind::Static(..),
225                    ..
226                }) | Node::TraitItem(&hir::TraitItem { kind: hir::TraitItemKind::Const(..), .. })
227                    | Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
228            );
229        }
230
231        // if function is wrapped around a const or static,
232        // then don't show the suggestion
233        if !(is_fn && is_const_or_static) {
234            err.multipart_suggestion(
235                "use type parameters instead",
236                sugg,
237                Applicability::HasPlaceholders,
238            );
239        }
240    }
241
242    err
243}
244
245fn reject_placeholder_type_signatures_in_item<'tcx>(
246    tcx: TyCtxt<'tcx>,
247    item: &'tcx hir::Item<'tcx>,
248) {
249    let (generics, suggest) = match &item.kind {
250        hir::ItemKind::Union(_, _, generics)
251        | hir::ItemKind::Enum(_, _, generics)
252        | hir::ItemKind::TraitAlias(_, generics, _)
253        | hir::ItemKind::Trait(_, _, _, generics, ..)
254        | hir::ItemKind::Impl(hir::Impl { generics, .. })
255        | hir::ItemKind::Struct(_, _, generics) => (generics, true),
256        hir::ItemKind::TyAlias(_, _, generics) => (generics, false),
257        // `static`, `fn` and `const` are handled elsewhere to suggest appropriate type.
258        _ => return,
259    };
260
261    let mut visitor = HirPlaceholderCollector::default();
262    visitor.visit_item(item);
263
264    let icx = ItemCtxt::new(tcx, item.owner_id.def_id);
265
266    placeholder_type_error(
267        icx.lowerer(),
268        Some(generics),
269        visitor.spans,
270        suggest && !visitor.may_contain_const_infer,
271        None,
272        item.kind.descr(),
273    );
274}
275
276impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
277    type NestedFilter = nested_filter::OnlyBodies;
278
279    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
280        self.tcx
281    }
282
283    fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
284        lower_item(self.tcx, item.item_id());
285        reject_placeholder_type_signatures_in_item(self.tcx, item);
286        intravisit::walk_item(self, item);
287    }
288
289    fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
290        for param in generics.params {
291            match param.kind {
292                hir::GenericParamKind::Lifetime { .. } => {}
293                hir::GenericParamKind::Type { default: Some(_), .. } => {
294                    self.tcx.ensure_ok().type_of(param.def_id);
295                }
296                hir::GenericParamKind::Type { .. } => {}
297                hir::GenericParamKind::Const { default, .. } => {
298                    self.tcx.ensure_ok().type_of(param.def_id);
299                    if let Some(default) = default {
300                        // need to store default and type of default
301                        self.tcx.ensure_ok().const_param_default(param.def_id);
302                        if let hir::ConstArgKind::Anon(ac) = default.kind {
303                            self.tcx.ensure_ok().type_of(ac.def_id);
304                        }
305                    }
306                }
307            }
308        }
309        intravisit::walk_generics(self, generics);
310    }
311
312    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
313        if let hir::ExprKind::Closure(closure) = expr.kind {
314            self.tcx.ensure_ok().generics_of(closure.def_id);
315            self.tcx.ensure_ok().codegen_fn_attrs(closure.def_id);
316            // We do not call `type_of` for closures here as that
317            // depends on typecheck and would therefore hide
318            // any further errors in case one typeck fails.
319        }
320        intravisit::walk_expr(self, expr);
321    }
322
323    /// Don't call `type_of` on opaque types, since that depends on type checking function bodies.
324    /// `check_item_type` ensures that it's called instead.
325    fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) {
326        let def_id = opaque.def_id;
327        self.tcx.ensure_ok().generics_of(def_id);
328        self.tcx.ensure_ok().predicates_of(def_id);
329        self.tcx.ensure_ok().explicit_item_bounds(def_id);
330        self.tcx.ensure_ok().explicit_item_self_bounds(def_id);
331        self.tcx.ensure_ok().item_bounds(def_id);
332        self.tcx.ensure_ok().item_self_bounds(def_id);
333        if self.tcx.is_conditionally_const(def_id) {
334            self.tcx.ensure_ok().explicit_implied_const_bounds(def_id);
335            self.tcx.ensure_ok().const_conditions(def_id);
336        }
337        intravisit::walk_opaque_ty(self, opaque);
338    }
339
340    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
341        lower_trait_item(self.tcx, trait_item.trait_item_id());
342        intravisit::walk_trait_item(self, trait_item);
343    }
344
345    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
346        lower_impl_item(self.tcx, impl_item.impl_item_id());
347        intravisit::walk_impl_item(self, impl_item);
348    }
349}
350
351///////////////////////////////////////////////////////////////////////////
352// Utility types and common code for the above passes.
353
354fn bad_placeholder<'cx, 'tcx>(
355    cx: &'cx dyn HirTyLowerer<'tcx>,
356    mut spans: Vec<Span>,
357    kind: &'static str,
358) -> Diag<'cx> {
359    let kind = if kind.ends_with('s') { format!("{kind}es") } else { format!("{kind}s") };
360
361    spans.sort();
362    cx.dcx().create_err(errors::PlaceholderNotAllowedItemSignatures { spans, kind })
363}
364
365impl<'tcx> ItemCtxt<'tcx> {
366    pub(crate) fn new(tcx: TyCtxt<'tcx>, item_def_id: LocalDefId) -> ItemCtxt<'tcx> {
367        ItemCtxt { tcx, item_def_id, tainted_by_errors: Cell::new(None) }
368    }
369
370    pub(crate) fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
371        self.lowerer().lower_ty(hir_ty)
372    }
373
374    pub(crate) fn hir_id(&self) -> hir::HirId {
375        self.tcx.local_def_id_to_hir_id(self.item_def_id)
376    }
377
378    pub(crate) fn node(&self) -> hir::Node<'tcx> {
379        self.tcx.hir_node(self.hir_id())
380    }
381
382    fn check_tainted_by_errors(&self) -> Result<(), ErrorGuaranteed> {
383        match self.tainted_by_errors.get() {
384            Some(err) => Err(err),
385            None => Ok(()),
386        }
387    }
388}
389
390impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
391    fn tcx(&self) -> TyCtxt<'tcx> {
392        self.tcx
393    }
394
395    fn dcx(&self) -> DiagCtxtHandle<'_> {
396        self.tcx.dcx().taintable_handle(&self.tainted_by_errors)
397    }
398
399    fn item_def_id(&self) -> LocalDefId {
400        self.item_def_id
401    }
402
403    fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
404        if let RegionInferReason::ObjectLifetimeDefault = reason {
405            let e = struct_span_code_err!(
406                self.dcx(),
407                span,
408                E0228,
409                "the lifetime bound for this object type cannot be deduced \
410                from context; please supply an explicit bound"
411            )
412            .emit();
413            ty::Region::new_error(self.tcx(), e)
414        } else {
415            // This indicates an illegal lifetime in a non-assoc-trait position
416            ty::Region::new_error_with_message(self.tcx(), span, "unelided lifetime in signature")
417        }
418    }
419
420    fn ty_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> {
421        Ty::new_error_with_message(self.tcx(), span, "bad placeholder type")
422    }
423
424    fn ct_infer(&self, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> {
425        ty::Const::new_error_with_message(self.tcx(), span, "bad placeholder constant")
426    }
427
428    fn register_trait_ascription_bounds(
429        &self,
430        _: Vec<(ty::Clause<'tcx>, Span)>,
431        _: HirId,
432        span: Span,
433    ) {
434        self.dcx().span_delayed_bug(span, "trait ascription type not allowed here");
435    }
436
437    fn probe_ty_param_bounds(
438        &self,
439        span: Span,
440        def_id: LocalDefId,
441        assoc_name: Ident,
442    ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
443        self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_name))
444    }
445
446    fn lower_assoc_shared(
447        &self,
448        span: Span,
449        item_def_id: DefId,
450        item_segment: &rustc_hir::PathSegment<'tcx>,
451        poly_trait_ref: ty::PolyTraitRef<'tcx>,
452        kind: ty::AssocKind,
453    ) -> Result<(DefId, ty::GenericArgsRef<'tcx>), ErrorGuaranteed> {
454        if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
455            let item_args = self.lowerer().lower_generic_args_of_assoc_item(
456                span,
457                item_def_id,
458                item_segment,
459                trait_ref.args,
460            );
461            Ok((item_def_id, item_args))
462        } else {
463            // There are no late-bound regions; we can just ignore the binder.
464            let (mut mpart_sugg, mut inferred_sugg) = (None, None);
465            let mut bound = String::new();
466
467            match self.node() {
468                hir::Node::Field(_) | hir::Node::Ctor(_) | hir::Node::Variant(_) => {
469                    let item = self
470                        .tcx
471                        .hir_expect_item(self.tcx.hir_get_parent_item(self.hir_id()).def_id);
472                    match &item.kind {
473                        hir::ItemKind::Enum(_, _, generics)
474                        | hir::ItemKind::Struct(_, _, generics)
475                        | hir::ItemKind::Union(_, _, generics) => {
476                            let lt_name = get_new_lifetime_name(self.tcx, poly_trait_ref, generics);
477                            let (lt_sp, sugg) = match generics.params {
478                                [] => (generics.span, format!("<{lt_name}>")),
479                                [bound, ..] => (bound.span.shrink_to_lo(), format!("{lt_name}, ")),
480                            };
481                            mpart_sugg = Some(errors::AssociatedItemTraitUninferredGenericParamsMultipartSuggestion {
482                                fspan: lt_sp,
483                                first: sugg,
484                                sspan: span.with_hi(item_segment.ident.span.lo()),
485                                second: format!(
486                                    "{}::",
487                                    // Replace the existing lifetimes with a new named lifetime.
488                                    self.tcx.instantiate_bound_regions_uncached(
489                                        poly_trait_ref,
490                                        |_| {
491                                            ty::Region::new_early_param(self.tcx, ty::EarlyParamRegion {
492                                                index: 0,
493                                                name: Symbol::intern(&lt_name),
494                                            })
495                                        }
496                                    ),
497                                ),
498                            });
499                        }
500                        _ => {}
501                    }
502                }
503                hir::Node::Item(hir::Item {
504                    kind:
505                        hir::ItemKind::Struct(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Union(..),
506                    ..
507                }) => {}
508                hir::Node::Item(_)
509                | hir::Node::ForeignItem(_)
510                | hir::Node::TraitItem(_)
511                | hir::Node::ImplItem(_) => {
512                    inferred_sugg = Some(span.with_hi(item_segment.ident.span.lo()));
513                    bound = format!(
514                        "{}::",
515                        // Erase named lt, we want `<A as B<'_>::C`, not `<A as B<'a>::C`.
516                        self.tcx.anonymize_bound_vars(poly_trait_ref).skip_binder(),
517                    );
518                }
519                _ => {}
520            }
521
522            Err(self.tcx().dcx().emit_err(errors::AssociatedItemTraitUninferredGenericParams {
523                span,
524                inferred_sugg,
525                bound,
526                mpart_sugg,
527                what: assoc_kind_str(kind),
528            }))
529        }
530    }
531
532    fn probe_adt(&self, _span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>> {
533        // FIXME(#103640): Should we handle the case where `ty` is a projection?
534        ty.ty_adt_def()
535    }
536
537    fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) {
538        // There's no place to record types from signatures?
539    }
540
541    fn infcx(&self) -> Option<&InferCtxt<'tcx>> {
542        None
543    }
544
545    fn lower_fn_sig(
546        &self,
547        decl: &hir::FnDecl<'tcx>,
548        generics: Option<&hir::Generics<'_>>,
549        hir_id: rustc_hir::HirId,
550        hir_ty: Option<&hir::Ty<'_>>,
551    ) -> (Vec<Ty<'tcx>>, Ty<'tcx>) {
552        let tcx = self.tcx();
553        // We proactively collect all the inferred type params to emit a single error per fn def.
554        let mut visitor = HirPlaceholderCollector::default();
555        let mut infer_replacements = vec![];
556
557        if let Some(generics) = generics {
558            walk_generics(&mut visitor, generics);
559        }
560
561        let input_tys = decl
562            .inputs
563            .iter()
564            .enumerate()
565            .map(|(i, a)| {
566                if let hir::TyKind::Infer(()) = a.kind {
567                    if let Some(suggested_ty) =
568                        self.lowerer().suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i))
569                    {
570                        infer_replacements.push((a.span, suggested_ty.to_string()));
571                        return Ty::new_error_with_message(tcx, a.span, suggested_ty.to_string());
572                    }
573                }
574
575                // Only visit the type looking for `_` if we didn't fix the type above
576                visitor.visit_ty_unambig(a);
577                self.lowerer().lower_arg_ty(a, None)
578            })
579            .collect();
580
581        let output_ty = match decl.output {
582            hir::FnRetTy::Return(output) => {
583                if let hir::TyKind::Infer(()) = output.kind
584                    && let Some(suggested_ty) =
585                        self.lowerer().suggest_trait_fn_ty_for_impl_fn_infer(hir_id, None)
586                {
587                    infer_replacements.push((output.span, suggested_ty.to_string()));
588                    Ty::new_error_with_message(tcx, output.span, suggested_ty.to_string())
589                } else {
590                    visitor.visit_ty_unambig(output);
591                    self.lower_ty(output)
592                }
593            }
594            hir::FnRetTy::DefaultReturn(..) => tcx.types.unit,
595        };
596
597        if !(visitor.spans.is_empty() && infer_replacements.is_empty()) {
598            // We check for the presence of
599            // `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
600
601            let mut diag = crate::collect::placeholder_type_error_diag(
602                self,
603                generics,
604                visitor.spans,
605                infer_replacements.iter().map(|(s, _)| *s).collect(),
606                !visitor.may_contain_const_infer,
607                hir_ty,
608                "function",
609            );
610
611            if !infer_replacements.is_empty() {
612                diag.multipart_suggestion(
613                    format!(
614                        "try replacing `_` with the type{} in the corresponding trait method \
615                         signature",
616                        rustc_errors::pluralize!(infer_replacements.len()),
617                    ),
618                    infer_replacements,
619                    Applicability::MachineApplicable,
620                );
621            }
622
623            diag.emit();
624        }
625
626        (input_tys, output_ty)
627    }
628}
629
630/// Synthesize a new lifetime name that doesn't clash with any of the lifetimes already present.
631fn get_new_lifetime_name<'tcx>(
632    tcx: TyCtxt<'tcx>,
633    poly_trait_ref: ty::PolyTraitRef<'tcx>,
634    generics: &hir::Generics<'tcx>,
635) -> String {
636    let existing_lifetimes = tcx
637        .collect_referenced_late_bound_regions(poly_trait_ref)
638        .into_iter()
639        .filter_map(|lt| {
640            if let ty::BoundRegionKind::Named(_, name) = lt {
641                Some(name.as_str().to_string())
642            } else {
643                None
644            }
645        })
646        .chain(generics.params.iter().filter_map(|param| {
647            if let hir::GenericParamKind::Lifetime { .. } = &param.kind {
648                Some(param.name.ident().as_str().to_string())
649            } else {
650                None
651            }
652        }))
653        .collect::<FxHashSet<String>>();
654
655    let a_to_z_repeat_n = |n| {
656        (b'a'..=b'z').map(move |c| {
657            let mut s = '\''.to_string();
658            s.extend(std::iter::repeat(char::from(c)).take(n));
659            s
660        })
661    };
662
663    // If all single char lifetime names are present, we wrap around and double the chars.
664    (1..).flat_map(a_to_z_repeat_n).find(|lt| !existing_lifetimes.contains(lt.as_str())).unwrap()
665}
666
667#[instrument(level = "debug", skip_all)]
668fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
669    let it = tcx.hir_item(item_id);
670    debug!(item = ?it.kind.ident(), id = %it.hir_id());
671    let def_id = item_id.owner_id.def_id;
672    let icx = ItemCtxt::new(tcx, def_id);
673
674    match &it.kind {
675        // These don't define types.
676        hir::ItemKind::ExternCrate(..)
677        | hir::ItemKind::Use(..)
678        | hir::ItemKind::Macro(..)
679        | hir::ItemKind::Mod(..)
680        | hir::ItemKind::GlobalAsm { .. } => {}
681        hir::ItemKind::ForeignMod { items, .. } => {
682            for item in *items {
683                let item = tcx.hir_foreign_item(item.id);
684                tcx.ensure_ok().generics_of(item.owner_id);
685                tcx.ensure_ok().type_of(item.owner_id);
686                tcx.ensure_ok().predicates_of(item.owner_id);
687                if tcx.is_conditionally_const(def_id) {
688                    tcx.ensure_ok().explicit_implied_const_bounds(def_id);
689                    tcx.ensure_ok().const_conditions(def_id);
690                }
691                match item.kind {
692                    hir::ForeignItemKind::Fn(..) => {
693                        tcx.ensure_ok().codegen_fn_attrs(item.owner_id);
694                        tcx.ensure_ok().fn_sig(item.owner_id)
695                    }
696                    hir::ForeignItemKind::Static(..) => {
697                        tcx.ensure_ok().codegen_fn_attrs(item.owner_id);
698                        let mut visitor = HirPlaceholderCollector::default();
699                        visitor.visit_foreign_item(item);
700                        placeholder_type_error(
701                            icx.lowerer(),
702                            None,
703                            visitor.spans,
704                            false,
705                            None,
706                            "static variable",
707                        );
708                    }
709                    _ => (),
710                }
711            }
712        }
713        hir::ItemKind::Enum(..) => {
714            tcx.ensure_ok().generics_of(def_id);
715            tcx.ensure_ok().type_of(def_id);
716            tcx.ensure_ok().predicates_of(def_id);
717            lower_enum_variant_types(tcx, def_id.to_def_id());
718        }
719        hir::ItemKind::Impl { .. } => {
720            tcx.ensure_ok().generics_of(def_id);
721            tcx.ensure_ok().type_of(def_id);
722            tcx.ensure_ok().impl_trait_header(def_id);
723            tcx.ensure_ok().predicates_of(def_id);
724            tcx.ensure_ok().associated_items(def_id);
725        }
726        hir::ItemKind::Trait(..) => {
727            tcx.ensure_ok().generics_of(def_id);
728            tcx.ensure_ok().trait_def(def_id);
729            tcx.at(it.span).explicit_super_predicates_of(def_id);
730            tcx.ensure_ok().predicates_of(def_id);
731            tcx.ensure_ok().associated_items(def_id);
732        }
733        hir::ItemKind::TraitAlias(..) => {
734            tcx.ensure_ok().generics_of(def_id);
735            tcx.at(it.span).explicit_implied_predicates_of(def_id);
736            tcx.at(it.span).explicit_super_predicates_of(def_id);
737            tcx.ensure_ok().predicates_of(def_id);
738        }
739        hir::ItemKind::Struct(_, struct_def, _) | hir::ItemKind::Union(_, struct_def, _) => {
740            tcx.ensure_ok().generics_of(def_id);
741            tcx.ensure_ok().type_of(def_id);
742            tcx.ensure_ok().predicates_of(def_id);
743
744            for f in struct_def.fields() {
745                tcx.ensure_ok().generics_of(f.def_id);
746                tcx.ensure_ok().type_of(f.def_id);
747                tcx.ensure_ok().predicates_of(f.def_id);
748            }
749
750            if let Some(ctor_def_id) = struct_def.ctor_def_id() {
751                lower_variant_ctor(tcx, ctor_def_id);
752            }
753        }
754
755        hir::ItemKind::TyAlias(..) => {
756            tcx.ensure_ok().generics_of(def_id);
757            tcx.ensure_ok().type_of(def_id);
758            tcx.ensure_ok().predicates_of(def_id);
759        }
760
761        hir::ItemKind::Static(_, ty, ..) | hir::ItemKind::Const(_, ty, ..) => {
762            tcx.ensure_ok().generics_of(def_id);
763            tcx.ensure_ok().type_of(def_id);
764            tcx.ensure_ok().predicates_of(def_id);
765            if !ty.is_suggestable_infer_ty() {
766                let mut visitor = HirPlaceholderCollector::default();
767                visitor.visit_item(it);
768                placeholder_type_error(
769                    icx.lowerer(),
770                    None,
771                    visitor.spans,
772                    false,
773                    None,
774                    it.kind.descr(),
775                );
776            }
777        }
778
779        hir::ItemKind::Fn { .. } => {
780            tcx.ensure_ok().generics_of(def_id);
781            tcx.ensure_ok().type_of(def_id);
782            tcx.ensure_ok().predicates_of(def_id);
783            tcx.ensure_ok().fn_sig(def_id);
784            tcx.ensure_ok().codegen_fn_attrs(def_id);
785        }
786    }
787}
788
789fn lower_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
790    let trait_item = tcx.hir_trait_item(trait_item_id);
791    let def_id = trait_item_id.owner_id;
792    tcx.ensure_ok().generics_of(def_id);
793    let icx = ItemCtxt::new(tcx, def_id.def_id);
794
795    match trait_item.kind {
796        hir::TraitItemKind::Fn(..) => {
797            tcx.ensure_ok().codegen_fn_attrs(def_id);
798            tcx.ensure_ok().type_of(def_id);
799            tcx.ensure_ok().fn_sig(def_id);
800        }
801
802        hir::TraitItemKind::Const(ty, body_id) => {
803            tcx.ensure_ok().type_of(def_id);
804            if !tcx.dcx().has_stashed_diagnostic(ty.span, StashKey::ItemNoType)
805                && !(ty.is_suggestable_infer_ty() && body_id.is_some())
806            {
807                // Account for `const C: _;`.
808                let mut visitor = HirPlaceholderCollector::default();
809                visitor.visit_trait_item(trait_item);
810                placeholder_type_error(
811                    icx.lowerer(),
812                    None,
813                    visitor.spans,
814                    false,
815                    None,
816                    "associated constant",
817                );
818            }
819        }
820
821        hir::TraitItemKind::Type(_, Some(_)) => {
822            tcx.ensure_ok().item_bounds(def_id);
823            tcx.ensure_ok().item_self_bounds(def_id);
824            tcx.ensure_ok().type_of(def_id);
825            // Account for `type T = _;`.
826            let mut visitor = HirPlaceholderCollector::default();
827            visitor.visit_trait_item(trait_item);
828            placeholder_type_error(
829                icx.lowerer(),
830                None,
831                visitor.spans,
832                false,
833                None,
834                "associated type",
835            );
836        }
837
838        hir::TraitItemKind::Type(_, None) => {
839            tcx.ensure_ok().item_bounds(def_id);
840            tcx.ensure_ok().item_self_bounds(def_id);
841            // #74612: Visit and try to find bad placeholders
842            // even if there is no concrete type.
843            let mut visitor = HirPlaceholderCollector::default();
844            visitor.visit_trait_item(trait_item);
845
846            placeholder_type_error(
847                icx.lowerer(),
848                None,
849                visitor.spans,
850                false,
851                None,
852                "associated type",
853            );
854        }
855    };
856
857    tcx.ensure_ok().predicates_of(def_id);
858}
859
860fn lower_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
861    let def_id = impl_item_id.owner_id;
862    tcx.ensure_ok().generics_of(def_id);
863    tcx.ensure_ok().type_of(def_id);
864    tcx.ensure_ok().predicates_of(def_id);
865    let impl_item = tcx.hir_impl_item(impl_item_id);
866    let icx = ItemCtxt::new(tcx, def_id.def_id);
867    match impl_item.kind {
868        hir::ImplItemKind::Fn(..) => {
869            tcx.ensure_ok().codegen_fn_attrs(def_id);
870            tcx.ensure_ok().fn_sig(def_id);
871        }
872        hir::ImplItemKind::Type(_) => {
873            // Account for `type T = _;`
874            let mut visitor = HirPlaceholderCollector::default();
875            visitor.visit_impl_item(impl_item);
876
877            placeholder_type_error(
878                icx.lowerer(),
879                None,
880                visitor.spans,
881                false,
882                None,
883                "associated type",
884            );
885        }
886        hir::ImplItemKind::Const(ty, _) => {
887            // Account for `const T: _ = ..;`
888            if !ty.is_suggestable_infer_ty() {
889                let mut visitor = HirPlaceholderCollector::default();
890                visitor.visit_impl_item(impl_item);
891                placeholder_type_error(
892                    icx.lowerer(),
893                    None,
894                    visitor.spans,
895                    false,
896                    None,
897                    "associated constant",
898                );
899            }
900        }
901    }
902}
903
904fn lower_variant_ctor(tcx: TyCtxt<'_>, def_id: LocalDefId) {
905    tcx.ensure_ok().generics_of(def_id);
906    tcx.ensure_ok().type_of(def_id);
907    tcx.ensure_ok().predicates_of(def_id);
908}
909
910fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
911    let def = tcx.adt_def(def_id);
912    let repr_type = def.repr().discr_type();
913    let initial = repr_type.initial_discriminant(tcx);
914    let mut prev_discr = None::<Discr<'_>>;
915
916    // fill the discriminant values and field types
917    for variant in def.variants() {
918        let wrapped_discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
919        prev_discr = Some(
920            if let ty::VariantDiscr::Explicit(const_def_id) = variant.discr {
921                def.eval_explicit_discr(tcx, const_def_id).ok()
922            } else if let Some(discr) = repr_type.disr_incr(tcx, prev_discr) {
923                Some(discr)
924            } else {
925                let span = tcx.def_span(variant.def_id);
926                tcx.dcx().emit_err(errors::EnumDiscriminantOverflowed {
927                    span,
928                    discr: prev_discr.unwrap().to_string(),
929                    item_name: tcx.item_ident(variant.def_id),
930                    wrapped_discr: wrapped_discr.to_string(),
931                });
932                None
933            }
934            .unwrap_or(wrapped_discr),
935        );
936
937        for f in &variant.fields {
938            tcx.ensure_ok().generics_of(f.did);
939            tcx.ensure_ok().type_of(f.did);
940            tcx.ensure_ok().predicates_of(f.did);
941        }
942
943        // Lower the ctor, if any. This also registers the variant as an item.
944        if let Some(ctor_def_id) = variant.ctor_def_id() {
945            lower_variant_ctor(tcx, ctor_def_id.expect_local());
946        }
947    }
948}
949
950#[derive(Clone, Copy)]
951struct NestedSpan {
952    span: Span,
953    nested_field_span: Span,
954}
955
956impl NestedSpan {
957    fn to_field_already_declared_nested_help(&self) -> errors::FieldAlreadyDeclaredNestedHelp {
958        errors::FieldAlreadyDeclaredNestedHelp { span: self.span }
959    }
960}
961
962#[derive(Clone, Copy)]
963enum FieldDeclSpan {
964    NotNested(Span),
965    Nested(NestedSpan),
966}
967
968impl From<Span> for FieldDeclSpan {
969    fn from(span: Span) -> Self {
970        Self::NotNested(span)
971    }
972}
973
974impl From<NestedSpan> for FieldDeclSpan {
975    fn from(span: NestedSpan) -> Self {
976        Self::Nested(span)
977    }
978}
979
980struct FieldUniquenessCheckContext<'tcx> {
981    tcx: TyCtxt<'tcx>,
982    seen_fields: FxIndexMap<Ident, FieldDeclSpan>,
983}
984
985impl<'tcx> FieldUniquenessCheckContext<'tcx> {
986    fn new(tcx: TyCtxt<'tcx>) -> Self {
987        Self { tcx, seen_fields: FxIndexMap::default() }
988    }
989
990    /// Check if a given field `ident` declared at `field_decl` has been declared elsewhere before.
991    fn check_field_decl(&mut self, field_name: Ident, field_decl: FieldDeclSpan) {
992        use FieldDeclSpan::*;
993        let field_name = field_name.normalize_to_macros_2_0();
994        match (field_decl, self.seen_fields.get(&field_name).copied()) {
995            (NotNested(span), Some(NotNested(prev_span))) => {
996                self.tcx.dcx().emit_err(errors::FieldAlreadyDeclared::NotNested {
997                    field_name,
998                    span,
999                    prev_span,
1000                });
1001            }
1002            (NotNested(span), Some(Nested(prev))) => {
1003                self.tcx.dcx().emit_err(errors::FieldAlreadyDeclared::PreviousNested {
1004                    field_name,
1005                    span,
1006                    prev_span: prev.span,
1007                    prev_nested_field_span: prev.nested_field_span,
1008                    prev_help: prev.to_field_already_declared_nested_help(),
1009                });
1010            }
1011            (
1012                Nested(current @ NestedSpan { span, nested_field_span, .. }),
1013                Some(NotNested(prev_span)),
1014            ) => {
1015                self.tcx.dcx().emit_err(errors::FieldAlreadyDeclared::CurrentNested {
1016                    field_name,
1017                    span,
1018                    nested_field_span,
1019                    help: current.to_field_already_declared_nested_help(),
1020                    prev_span,
1021                });
1022            }
1023            (Nested(current @ NestedSpan { span, nested_field_span }), Some(Nested(prev))) => {
1024                self.tcx.dcx().emit_err(errors::FieldAlreadyDeclared::BothNested {
1025                    field_name,
1026                    span,
1027                    nested_field_span,
1028                    help: current.to_field_already_declared_nested_help(),
1029                    prev_span: prev.span,
1030                    prev_nested_field_span: prev.nested_field_span,
1031                    prev_help: prev.to_field_already_declared_nested_help(),
1032                });
1033            }
1034            (field_decl, None) => {
1035                self.seen_fields.insert(field_name, field_decl);
1036            }
1037        }
1038    }
1039}
1040
1041fn lower_variant<'tcx>(
1042    tcx: TyCtxt<'tcx>,
1043    variant_did: Option<LocalDefId>,
1044    ident: Ident,
1045    discr: ty::VariantDiscr,
1046    def: &hir::VariantData<'tcx>,
1047    adt_kind: ty::AdtKind,
1048    parent_did: LocalDefId,
1049) -> ty::VariantDef {
1050    let mut field_uniqueness_check_ctx = FieldUniquenessCheckContext::new(tcx);
1051    let fields = def
1052        .fields()
1053        .iter()
1054        .inspect(|field| {
1055            field_uniqueness_check_ctx.check_field_decl(field.ident, field.span.into());
1056        })
1057        .map(|f| ty::FieldDef {
1058            did: f.def_id.to_def_id(),
1059            name: f.ident.name,
1060            vis: tcx.visibility(f.def_id),
1061            safety: f.safety,
1062            value: f.default.map(|v| v.def_id.to_def_id()),
1063        })
1064        .collect();
1065    let recovered = match def {
1066        hir::VariantData::Struct { recovered: Recovered::Yes(guar), .. } => Some(*guar),
1067        _ => None,
1068    };
1069    ty::VariantDef::new(
1070        ident.name,
1071        variant_did.map(LocalDefId::to_def_id),
1072        def.ctor().map(|(kind, _, def_id)| (kind, def_id.to_def_id())),
1073        discr,
1074        fields,
1075        parent_did.to_def_id(),
1076        recovered,
1077        adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive)
1078            || variant_did
1079                .is_some_and(|variant_did| tcx.has_attr(variant_did, sym::non_exhaustive)),
1080    )
1081}
1082
1083fn adt_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AdtDef<'_> {
1084    use rustc_hir::*;
1085
1086    let Node::Item(item) = tcx.hir_node_by_def_id(def_id) else {
1087        bug!("expected ADT to be an item");
1088    };
1089
1090    let repr = tcx.repr_options_of_def(def_id);
1091    let (kind, variants) = match &item.kind {
1092        ItemKind::Enum(_, def, _) => {
1093            let mut distance_from_explicit = 0;
1094            let variants = def
1095                .variants
1096                .iter()
1097                .map(|v| {
1098                    let discr = if let Some(e) = &v.disr_expr {
1099                        distance_from_explicit = 0;
1100                        ty::VariantDiscr::Explicit(e.def_id.to_def_id())
1101                    } else {
1102                        ty::VariantDiscr::Relative(distance_from_explicit)
1103                    };
1104                    distance_from_explicit += 1;
1105
1106                    lower_variant(
1107                        tcx,
1108                        Some(v.def_id),
1109                        v.ident,
1110                        discr,
1111                        &v.data,
1112                        AdtKind::Enum,
1113                        def_id,
1114                    )
1115                })
1116                .collect();
1117
1118            (AdtKind::Enum, variants)
1119        }
1120        ItemKind::Struct(ident, def, _) | ItemKind::Union(ident, def, _) => {
1121            let adt_kind = match item.kind {
1122                ItemKind::Struct(..) => AdtKind::Struct,
1123                _ => AdtKind::Union,
1124            };
1125            let variants = std::iter::once(lower_variant(
1126                tcx,
1127                None,
1128                *ident,
1129                ty::VariantDiscr::Relative(0),
1130                def,
1131                adt_kind,
1132                def_id,
1133            ))
1134            .collect();
1135
1136            (adt_kind, variants)
1137        }
1138        _ => bug!("{:?} is not an ADT", item.owner_id.def_id),
1139    };
1140    tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr)
1141}
1142
1143fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
1144    let item = tcx.hir_expect_item(def_id);
1145
1146    let (is_alias, is_auto, safety, items) = match item.kind {
1147        hir::ItemKind::Trait(is_auto, safety, .., items) => {
1148            (false, is_auto == hir::IsAuto::Yes, safety, items)
1149        }
1150        hir::ItemKind::TraitAlias(..) => (true, false, hir::Safety::Safe, &[][..]),
1151        _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
1152    };
1153
1154    // Only regular traits can be const.
1155    let constness = if !is_alias && tcx.has_attr(def_id, sym::const_trait) {
1156        hir::Constness::Const
1157    } else {
1158        hir::Constness::NotConst
1159    };
1160
1161    let paren_sugar = tcx.has_attr(def_id, sym::rustc_paren_sugar);
1162    if paren_sugar && !tcx.features().unboxed_closures() {
1163        tcx.dcx().emit_err(errors::ParenSugarAttribute { span: item.span });
1164    }
1165
1166    // Only regular traits can be marker.
1167    let is_marker = !is_alias && tcx.has_attr(def_id, sym::marker);
1168
1169    let rustc_coinductive = tcx.has_attr(def_id, sym::rustc_coinductive);
1170    let is_fundamental = tcx.has_attr(def_id, sym::fundamental);
1171
1172    // FIXME: We could probably do way better attribute validation here.
1173    let mut skip_array_during_method_dispatch = false;
1174    let mut skip_boxed_slice_during_method_dispatch = false;
1175    for attr in tcx.get_attrs(def_id, sym::rustc_skip_during_method_dispatch) {
1176        if let Some(lst) = attr.meta_item_list() {
1177            for item in lst {
1178                if let Some(ident) = item.ident() {
1179                    match ident.as_str() {
1180                        "array" => skip_array_during_method_dispatch = true,
1181                        "boxed_slice" => skip_boxed_slice_during_method_dispatch = true,
1182                        _ => (),
1183                    }
1184                }
1185            }
1186        }
1187    }
1188
1189    let specialization_kind = if tcx.has_attr(def_id, sym::rustc_unsafe_specialization_marker) {
1190        ty::trait_def::TraitSpecializationKind::Marker
1191    } else if tcx.has_attr(def_id, sym::rustc_specialization_trait) {
1192        ty::trait_def::TraitSpecializationKind::AlwaysApplicable
1193    } else {
1194        ty::trait_def::TraitSpecializationKind::None
1195    };
1196    let must_implement_one_of = tcx
1197        .get_attr(def_id, sym::rustc_must_implement_one_of)
1198        // Check that there are at least 2 arguments of `#[rustc_must_implement_one_of]`
1199        // and that they are all identifiers
1200        .and_then(|attr| match attr.meta_item_list() {
1201            Some(items) if items.len() < 2 => {
1202                tcx.dcx().emit_err(errors::MustImplementOneOfAttribute { span: attr.span() });
1203
1204                None
1205            }
1206            Some(items) => items
1207                .into_iter()
1208                .map(|item| item.ident().ok_or(item.span()))
1209                .collect::<Result<Box<[_]>, _>>()
1210                .map_err(|span| {
1211                    tcx.dcx().emit_err(errors::MustBeNameOfAssociatedFunction { span });
1212                })
1213                .ok()
1214                .zip(Some(attr.span())),
1215            // Error is reported by `rustc_attr!`
1216            None => None,
1217        })
1218        // Check that all arguments of `#[rustc_must_implement_one_of]` reference
1219        // functions in the trait with default implementations
1220        .and_then(|(list, attr_span)| {
1221            let errors = list.iter().filter_map(|ident| {
1222                let item = items.iter().find(|item| item.ident == *ident);
1223
1224                match item {
1225                    Some(item) if matches!(item.kind, hir::AssocItemKind::Fn { .. }) => {
1226                        if !tcx.defaultness(item.id.owner_id).has_value() {
1227                            tcx.dcx().emit_err(errors::FunctionNotHaveDefaultImplementation {
1228                                span: item.span,
1229                                note_span: attr_span,
1230                            });
1231
1232                            return Some(());
1233                        }
1234
1235                        return None;
1236                    }
1237                    Some(item) => {
1238                        tcx.dcx().emit_err(errors::MustImplementNotFunction {
1239                            span: item.span,
1240                            span_note: errors::MustImplementNotFunctionSpanNote { span: attr_span },
1241                            note: errors::MustImplementNotFunctionNote {},
1242                        });
1243                    }
1244                    None => {
1245                        tcx.dcx().emit_err(errors::FunctionNotFoundInTrait { span: ident.span });
1246                    }
1247                }
1248
1249                Some(())
1250            });
1251
1252            (errors.count() == 0).then_some(list)
1253        })
1254        // Check for duplicates
1255        .and_then(|list| {
1256            let mut set: UnordMap<Symbol, Span> = Default::default();
1257            let mut no_dups = true;
1258
1259            for ident in &*list {
1260                if let Some(dup) = set.insert(ident.name, ident.span) {
1261                    tcx.dcx()
1262                        .emit_err(errors::FunctionNamesDuplicated { spans: vec![dup, ident.span] });
1263
1264                    no_dups = false;
1265                }
1266            }
1267
1268            no_dups.then_some(list)
1269        });
1270
1271    let deny_explicit_impl = tcx.has_attr(def_id, sym::rustc_deny_explicit_impl);
1272    let implement_via_object = !tcx.has_attr(def_id, sym::rustc_do_not_implement_via_object);
1273
1274    ty::TraitDef {
1275        def_id: def_id.to_def_id(),
1276        safety,
1277        constness,
1278        paren_sugar,
1279        has_auto_impl: is_auto,
1280        is_marker,
1281        is_coinductive: rustc_coinductive || is_auto,
1282        is_fundamental,
1283        skip_array_during_method_dispatch,
1284        skip_boxed_slice_during_method_dispatch,
1285        specialization_kind,
1286        must_implement_one_of,
1287        implement_via_object,
1288        deny_explicit_impl,
1289    }
1290}
1291
1292#[instrument(level = "debug", skip(tcx), ret)]
1293fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFnSig<'_>> {
1294    use rustc_hir::Node::*;
1295    use rustc_hir::*;
1296
1297    let hir_id = tcx.local_def_id_to_hir_id(def_id);
1298
1299    let icx = ItemCtxt::new(tcx, def_id);
1300
1301    let output = match tcx.hir_node(hir_id) {
1302        TraitItem(hir::TraitItem {
1303            kind: TraitItemKind::Fn(sig, TraitFn::Provided(_)),
1304            generics,
1305            ..
1306        })
1307        | Item(hir::Item { kind: ItemKind::Fn { sig, generics, .. }, .. }) => {
1308            lower_fn_sig_recovering_infer_ret_ty(&icx, sig, generics, def_id)
1309        }
1310
1311        ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => {
1312            // Do not try to infer the return type for a impl method coming from a trait
1313            if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = tcx.parent_hir_node(hir_id)
1314                && i.of_trait.is_some()
1315            {
1316                icx.lowerer().lower_fn_ty(
1317                    hir_id,
1318                    sig.header.safety(),
1319                    sig.header.abi,
1320                    sig.decl,
1321                    Some(generics),
1322                    None,
1323                )
1324            } else {
1325                lower_fn_sig_recovering_infer_ret_ty(&icx, sig, generics, def_id)
1326            }
1327        }
1328
1329        TraitItem(hir::TraitItem {
1330            kind: TraitItemKind::Fn(FnSig { header, decl, span: _ }, _),
1331            generics,
1332            ..
1333        }) => icx.lowerer().lower_fn_ty(
1334            hir_id,
1335            header.safety(),
1336            header.abi,
1337            decl,
1338            Some(generics),
1339            None,
1340        ),
1341
1342        ForeignItem(&hir::ForeignItem { kind: ForeignItemKind::Fn(sig, _, _), .. }) => {
1343            let abi = tcx.hir_get_foreign_abi(hir_id);
1344            compute_sig_of_foreign_fn_decl(tcx, def_id, sig.decl, abi, sig.header.safety())
1345        }
1346
1347        Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => {
1348            let adt_def_id = tcx.hir_get_parent_item(hir_id).def_id.to_def_id();
1349            let ty = tcx.type_of(adt_def_id).instantiate_identity();
1350            let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).instantiate_identity());
1351            // constructors for structs with `layout_scalar_valid_range` are unsafe to call
1352            let safety = match tcx.layout_scalar_valid_range(adt_def_id) {
1353                (Bound::Unbounded, Bound::Unbounded) => hir::Safety::Safe,
1354                _ => hir::Safety::Unsafe,
1355            };
1356            ty::Binder::dummy(tcx.mk_fn_sig(inputs, ty, false, safety, ExternAbi::Rust))
1357        }
1358
1359        Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => {
1360            // Closure signatures are not like other function
1361            // signatures and cannot be accessed through `fn_sig`. For
1362            // example, a closure signature excludes the `self`
1363            // argument. In any case they are embedded within the
1364            // closure type as part of the `ClosureArgs`.
1365            //
1366            // To get the signature of a closure, you should use the
1367            // `sig` method on the `ClosureArgs`:
1368            //
1369            //    args.as_closure().sig(def_id, tcx)
1370            bug!("to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",);
1371        }
1372
1373        x => {
1374            bug!("unexpected sort of node in fn_sig(): {:?}", x);
1375        }
1376    };
1377    ty::EarlyBinder::bind(output)
1378}
1379
1380fn lower_fn_sig_recovering_infer_ret_ty<'tcx>(
1381    icx: &ItemCtxt<'tcx>,
1382    sig: &'tcx hir::FnSig<'tcx>,
1383    generics: &'tcx hir::Generics<'tcx>,
1384    def_id: LocalDefId,
1385) -> ty::PolyFnSig<'tcx> {
1386    if let Some(infer_ret_ty) = sig.decl.output.is_suggestable_infer_ty() {
1387        return recover_infer_ret_ty(icx, infer_ret_ty, generics, def_id);
1388    }
1389
1390    icx.lowerer().lower_fn_ty(
1391        icx.tcx().local_def_id_to_hir_id(def_id),
1392        sig.header.safety(),
1393        sig.header.abi,
1394        sig.decl,
1395        Some(generics),
1396        None,
1397    )
1398}
1399
1400fn recover_infer_ret_ty<'tcx>(
1401    icx: &ItemCtxt<'tcx>,
1402    infer_ret_ty: &'tcx hir::Ty<'tcx>,
1403    generics: &'tcx hir::Generics<'tcx>,
1404    def_id: LocalDefId,
1405) -> ty::PolyFnSig<'tcx> {
1406    let tcx = icx.tcx;
1407    let hir_id = tcx.local_def_id_to_hir_id(def_id);
1408
1409    let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id];
1410
1411    // Typeck doesn't expect erased regions to be returned from `type_of`.
1412    // This is a heuristic approach. If the scope has region parameters,
1413    // we should change fn_sig's lifetime from `ReErased` to `ReError`,
1414    // otherwise to `ReStatic`.
1415    let has_region_params = generics.params.iter().any(|param| match param.kind {
1416        GenericParamKind::Lifetime { .. } => true,
1417        _ => false,
1418    });
1419    let fn_sig = fold_regions(tcx, fn_sig, |r, _| match *r {
1420        ty::ReErased => {
1421            if has_region_params {
1422                ty::Region::new_error_with_message(
1423                    tcx,
1424                    DUMMY_SP,
1425                    "erased region is not allowed here in return type",
1426                )
1427            } else {
1428                tcx.lifetimes.re_static
1429            }
1430        }
1431        _ => r,
1432    });
1433
1434    let mut visitor = HirPlaceholderCollector::default();
1435    visitor.visit_ty_unambig(infer_ret_ty);
1436
1437    let mut diag = bad_placeholder(icx.lowerer(), visitor.spans, "return type");
1438    let ret_ty = fn_sig.output();
1439
1440    // Don't leak types into signatures unless they're nameable!
1441    // For example, if a function returns itself, we don't want that
1442    // recursive function definition to leak out into the fn sig.
1443    let mut recovered_ret_ty = None;
1444    if let Some(suggestable_ret_ty) = ret_ty.make_suggestable(tcx, false, None) {
1445        diag.span_suggestion(
1446            infer_ret_ty.span,
1447            "replace with the correct return type",
1448            suggestable_ret_ty,
1449            Applicability::MachineApplicable,
1450        );
1451        recovered_ret_ty = Some(suggestable_ret_ty);
1452    } else if let Some(sugg) = suggest_impl_trait(
1453        &tcx.infer_ctxt().build(TypingMode::non_body_analysis()),
1454        tcx.param_env(def_id),
1455        ret_ty,
1456    ) {
1457        diag.span_suggestion(
1458            infer_ret_ty.span,
1459            "replace with an appropriate return type",
1460            sugg,
1461            Applicability::MachineApplicable,
1462        );
1463    } else if ret_ty.is_closure() {
1464        diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
1465    }
1466
1467    // Also note how `Fn` traits work just in case!
1468    if ret_ty.is_closure() {
1469        diag.note(
1470            "for more information on `Fn` traits and closure types, see \
1471                     https://doc.rust-lang.org/book/ch13-01-closures.html",
1472        );
1473    }
1474    let guar = diag.emit();
1475    ty::Binder::dummy(tcx.mk_fn_sig(
1476        fn_sig.inputs().iter().copied(),
1477        recovered_ret_ty.unwrap_or_else(|| Ty::new_error(tcx, guar)),
1478        fn_sig.c_variadic,
1479        fn_sig.safety,
1480        fn_sig.abi,
1481    ))
1482}
1483
1484pub fn suggest_impl_trait<'tcx>(
1485    infcx: &InferCtxt<'tcx>,
1486    param_env: ty::ParamEnv<'tcx>,
1487    ret_ty: Ty<'tcx>,
1488) -> Option<String> {
1489    let format_as_assoc: fn(_, _, _, _, _) -> _ =
1490        |tcx: TyCtxt<'tcx>,
1491         _: ty::GenericArgsRef<'tcx>,
1492         trait_def_id: DefId,
1493         assoc_item_def_id: DefId,
1494         item_ty: Ty<'tcx>| {
1495            let trait_name = tcx.item_name(trait_def_id);
1496            let assoc_name = tcx.item_name(assoc_item_def_id);
1497            Some(format!("impl {trait_name}<{assoc_name} = {item_ty}>"))
1498        };
1499    let format_as_parenthesized: fn(_, _, _, _, _) -> _ =
1500        |tcx: TyCtxt<'tcx>,
1501         args: ty::GenericArgsRef<'tcx>,
1502         trait_def_id: DefId,
1503         _: DefId,
1504         item_ty: Ty<'tcx>| {
1505            let trait_name = tcx.item_name(trait_def_id);
1506            let args_tuple = args.type_at(1);
1507            let ty::Tuple(types) = *args_tuple.kind() else {
1508                return None;
1509            };
1510            let types = types.make_suggestable(tcx, false, None)?;
1511            let maybe_ret =
1512                if item_ty.is_unit() { String::new() } else { format!(" -> {item_ty}") };
1513            Some(format!(
1514                "impl {trait_name}({}){maybe_ret}",
1515                types.iter().map(|ty| ty.to_string()).collect::<Vec<_>>().join(", ")
1516            ))
1517        };
1518
1519    for (trait_def_id, assoc_item_def_id, formatter) in [
1520        (
1521            infcx.tcx.get_diagnostic_item(sym::Iterator),
1522            infcx.tcx.get_diagnostic_item(sym::IteratorItem),
1523            format_as_assoc,
1524        ),
1525        (
1526            infcx.tcx.lang_items().future_trait(),
1527            infcx.tcx.lang_items().future_output(),
1528            format_as_assoc,
1529        ),
1530        (
1531            infcx.tcx.lang_items().fn_trait(),
1532            infcx.tcx.lang_items().fn_once_output(),
1533            format_as_parenthesized,
1534        ),
1535        (
1536            infcx.tcx.lang_items().fn_mut_trait(),
1537            infcx.tcx.lang_items().fn_once_output(),
1538            format_as_parenthesized,
1539        ),
1540        (
1541            infcx.tcx.lang_items().fn_once_trait(),
1542            infcx.tcx.lang_items().fn_once_output(),
1543            format_as_parenthesized,
1544        ),
1545    ] {
1546        let Some(trait_def_id) = trait_def_id else {
1547            continue;
1548        };
1549        let Some(assoc_item_def_id) = assoc_item_def_id else {
1550            continue;
1551        };
1552        if infcx.tcx.def_kind(assoc_item_def_id) != DefKind::AssocTy {
1553            continue;
1554        }
1555        let sugg = infcx.probe(|_| {
1556            let args = ty::GenericArgs::for_item(infcx.tcx, trait_def_id, |param, _| {
1557                if param.index == 0 { ret_ty.into() } else { infcx.var_for_def(DUMMY_SP, param) }
1558            });
1559            if !infcx
1560                .type_implements_trait(trait_def_id, args, param_env)
1561                .must_apply_modulo_regions()
1562            {
1563                return None;
1564            }
1565            let ocx = ObligationCtxt::new(&infcx);
1566            let item_ty = ocx.normalize(
1567                &ObligationCause::dummy(),
1568                param_env,
1569                Ty::new_projection_from_args(infcx.tcx, assoc_item_def_id, args),
1570            );
1571            // FIXME(compiler-errors): We may benefit from resolving regions here.
1572            if ocx.select_where_possible().is_empty()
1573                && let item_ty = infcx.resolve_vars_if_possible(item_ty)
1574                && let Some(item_ty) = item_ty.make_suggestable(infcx.tcx, false, None)
1575                && let Some(sugg) = formatter(
1576                    infcx.tcx,
1577                    infcx.resolve_vars_if_possible(args),
1578                    trait_def_id,
1579                    assoc_item_def_id,
1580                    item_ty,
1581                )
1582            {
1583                return Some(sugg);
1584            }
1585
1586            None
1587        });
1588
1589        if sugg.is_some() {
1590            return sugg;
1591        }
1592    }
1593    None
1594}
1595
1596fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTraitHeader<'_>> {
1597    let icx = ItemCtxt::new(tcx, def_id);
1598    let item = tcx.hir_expect_item(def_id);
1599    let impl_ = item.expect_impl();
1600    impl_.of_trait.as_ref().map(|ast_trait_ref| {
1601        let selfty = tcx.type_of(def_id).instantiate_identity();
1602
1603        check_impl_constness(tcx, impl_.constness, ast_trait_ref);
1604
1605        let trait_ref = icx.lowerer().lower_impl_trait_ref(ast_trait_ref, selfty);
1606
1607        ty::ImplTraitHeader {
1608            trait_ref: ty::EarlyBinder::bind(trait_ref),
1609            safety: impl_.safety,
1610            polarity: polarity_of_impl(tcx, def_id, impl_, item.span),
1611            constness: impl_.constness,
1612        }
1613    })
1614}
1615
1616fn check_impl_constness(
1617    tcx: TyCtxt<'_>,
1618    constness: hir::Constness,
1619    hir_trait_ref: &hir::TraitRef<'_>,
1620) {
1621    if let hir::Constness::NotConst = constness {
1622        return;
1623    }
1624
1625    let Some(trait_def_id) = hir_trait_ref.trait_def_id() else { return };
1626    if tcx.is_const_trait(trait_def_id) {
1627        return;
1628    }
1629
1630    let trait_name = tcx.item_name(trait_def_id).to_string();
1631    let (local_trait_span, suggestion_pre) =
1632        match (trait_def_id.is_local(), tcx.sess.is_nightly_build()) {
1633            (true, true) => (
1634                Some(tcx.def_span(trait_def_id).shrink_to_lo()),
1635                if tcx.features().const_trait_impl() {
1636                    ""
1637                } else {
1638                    "enable `#![feature(const_trait_impl)]` in your crate and "
1639                },
1640            ),
1641            (false, _) | (_, false) => (None, ""),
1642        };
1643    tcx.dcx().emit_err(errors::ConstImplForNonConstTrait {
1644        trait_ref_span: hir_trait_ref.path.span,
1645        trait_name,
1646        local_trait_span,
1647        suggestion_pre,
1648        marking: (),
1649        adding: (),
1650    });
1651}
1652
1653fn polarity_of_impl(
1654    tcx: TyCtxt<'_>,
1655    def_id: LocalDefId,
1656    impl_: &hir::Impl<'_>,
1657    span: Span,
1658) -> ty::ImplPolarity {
1659    let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
1660    match &impl_ {
1661        hir::Impl { polarity: hir::ImplPolarity::Negative(span), of_trait, .. } => {
1662            if is_rustc_reservation {
1663                let span = span.to(of_trait.as_ref().map_or(*span, |t| t.path.span));
1664                tcx.dcx().span_err(span, "reservation impls can't be negative");
1665            }
1666            ty::ImplPolarity::Negative
1667        }
1668        hir::Impl { polarity: hir::ImplPolarity::Positive, of_trait: None, .. } => {
1669            if is_rustc_reservation {
1670                tcx.dcx().span_err(span, "reservation impls can't be inherent");
1671            }
1672            ty::ImplPolarity::Positive
1673        }
1674        hir::Impl { polarity: hir::ImplPolarity::Positive, of_trait: Some(_), .. } => {
1675            if is_rustc_reservation {
1676                ty::ImplPolarity::Reservation
1677            } else {
1678                ty::ImplPolarity::Positive
1679            }
1680        }
1681    }
1682}
1683
1684/// Returns the early-bound lifetimes declared in this generics
1685/// listing. For anything other than fns/methods, this is just all
1686/// the lifetimes that are declared. For fns or methods, we have to
1687/// screen out those that do not appear in any where-clauses etc using
1688/// `resolve_lifetime::early_bound_lifetimes`.
1689fn early_bound_lifetimes_from_generics<'a, 'tcx>(
1690    tcx: TyCtxt<'tcx>,
1691    generics: &'a hir::Generics<'a>,
1692) -> impl Iterator<Item = &'a hir::GenericParam<'a>> {
1693    generics.params.iter().filter(move |param| match param.kind {
1694        GenericParamKind::Lifetime { .. } => !tcx.is_late_bound(param.hir_id),
1695        _ => false,
1696    })
1697}
1698
1699fn compute_sig_of_foreign_fn_decl<'tcx>(
1700    tcx: TyCtxt<'tcx>,
1701    def_id: LocalDefId,
1702    decl: &'tcx hir::FnDecl<'tcx>,
1703    abi: ExternAbi,
1704    safety: hir::Safety,
1705) -> ty::PolyFnSig<'tcx> {
1706    let safety = if abi == ExternAbi::RustIntrinsic {
1707        intrinsic_operation_unsafety(tcx, def_id)
1708    } else {
1709        safety
1710    };
1711    let hir_id = tcx.local_def_id_to_hir_id(def_id);
1712    let fty =
1713        ItemCtxt::new(tcx, def_id).lowerer().lower_fn_ty(hir_id, safety, abi, decl, None, None);
1714
1715    // Feature gate SIMD types in FFI, since I am not sure that the
1716    // ABIs are handled at all correctly. -huonw
1717    if abi != ExternAbi::RustIntrinsic && !tcx.features().simd_ffi() {
1718        let check = |hir_ty: &hir::Ty<'_>, ty: Ty<'_>| {
1719            if ty.is_simd() {
1720                let snip = tcx
1721                    .sess
1722                    .source_map()
1723                    .span_to_snippet(hir_ty.span)
1724                    .map_or_else(|_| String::new(), |s| format!(" `{s}`"));
1725                tcx.dcx().emit_err(errors::SIMDFFIHighlyExperimental { span: hir_ty.span, snip });
1726            }
1727        };
1728        for (input, ty) in iter::zip(decl.inputs, fty.inputs().skip_binder()) {
1729            check(input, *ty)
1730        }
1731        if let hir::FnRetTy::Return(ty) = decl.output {
1732            check(ty, fty.output().skip_binder())
1733        }
1734    }
1735
1736    fty
1737}
1738
1739fn coroutine_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineKind> {
1740    match tcx.hir_node_by_def_id(def_id) {
1741        Node::Expr(&hir::Expr {
1742            kind:
1743                hir::ExprKind::Closure(&rustc_hir::Closure {
1744                    kind: hir::ClosureKind::Coroutine(kind),
1745                    ..
1746                }),
1747            ..
1748        }) => Some(kind),
1749        _ => None,
1750    }
1751}
1752
1753fn coroutine_for_closure(tcx: TyCtxt<'_>, def_id: LocalDefId) -> DefId {
1754    let &rustc_hir::Closure { kind: hir::ClosureKind::CoroutineClosure(_), body, .. } =
1755        tcx.hir_node_by_def_id(def_id).expect_closure()
1756    else {
1757        bug!()
1758    };
1759
1760    let &hir::Expr {
1761        kind:
1762            hir::ExprKind::Closure(&rustc_hir::Closure {
1763                def_id,
1764                kind: hir::ClosureKind::Coroutine(_),
1765                ..
1766            }),
1767        ..
1768    } = tcx.hir_body(body).value
1769    else {
1770        bug!()
1771    };
1772
1773    def_id.to_def_id()
1774}
1775
1776fn opaque_ty_origin<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> hir::OpaqueTyOrigin<DefId> {
1777    match tcx.hir_node_by_def_id(def_id).expect_opaque_ty().origin {
1778        hir::OpaqueTyOrigin::FnReturn { parent, in_trait_or_impl } => {
1779            hir::OpaqueTyOrigin::FnReturn { parent: parent.to_def_id(), in_trait_or_impl }
1780        }
1781        hir::OpaqueTyOrigin::AsyncFn { parent, in_trait_or_impl } => {
1782            hir::OpaqueTyOrigin::AsyncFn { parent: parent.to_def_id(), in_trait_or_impl }
1783        }
1784        hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty } => {
1785            hir::OpaqueTyOrigin::TyAlias { parent: parent.to_def_id(), in_assoc_ty }
1786        }
1787    }
1788}
1789
1790fn rendered_precise_capturing_args<'tcx>(
1791    tcx: TyCtxt<'tcx>,
1792    def_id: LocalDefId,
1793) -> Option<&'tcx [PreciseCapturingArgKind<Symbol, Symbol>]> {
1794    if let Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) =
1795        tcx.opt_rpitit_info(def_id.to_def_id())
1796    {
1797        return tcx.rendered_precise_capturing_args(opaque_def_id);
1798    }
1799
1800    tcx.hir_node_by_def_id(def_id).expect_opaque_ty().bounds.iter().find_map(|bound| match bound {
1801        hir::GenericBound::Use(args, ..) => {
1802            Some(&*tcx.arena.alloc_from_iter(args.iter().map(|arg| match arg {
1803                PreciseCapturingArgKind::Lifetime(_) => {
1804                    PreciseCapturingArgKind::Lifetime(arg.name())
1805                }
1806                PreciseCapturingArgKind::Param(_) => PreciseCapturingArgKind::Param(arg.name()),
1807            })))
1808        }
1809        _ => None,
1810    })
1811}
1812
1813fn const_param_default<'tcx>(
1814    tcx: TyCtxt<'tcx>,
1815    def_id: LocalDefId,
1816) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
1817    let default_ct = match tcx.hir_node_by_def_id(def_id) {
1818        hir::Node::GenericParam(hir::GenericParam {
1819            kind: hir::GenericParamKind::Const { default: Some(ct), .. },
1820            ..
1821        }) => ct,
1822        _ => span_bug!(
1823            tcx.def_span(def_id),
1824            "`const_param_default` expected a generic parameter with a constant"
1825        ),
1826    };
1827    let icx = ItemCtxt::new(tcx, def_id);
1828    let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
1829    let ct = icx
1830        .lowerer()
1831        .lower_const_arg(default_ct, FeedConstTy::Param(def_id.to_def_id(), identity_args));
1832    ty::EarlyBinder::bind(ct)
1833}