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