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