rustc_hir_analysis/hir_ty_lowering/
mod.rs

1//! HIR ty lowering: Lowers type-system entities[^1] from the [HIR][hir] to
2//! the [`rustc_middle::ty`] representation.
3//!
4//! Not to be confused with *AST lowering* which lowers AST constructs to HIR ones
5//! or with *THIR* / *MIR* *lowering* / *building* which lowers HIR *bodies*
6//! (i.e., “executable code”) to THIR / MIR.
7//!
8//! Most lowering routines are defined on [`dyn HirTyLowerer`](HirTyLowerer) directly,
9//! like the main routine of this module, `lower_ty`.
10//!
11//! This module used to be called `astconv`.
12//!
13//! [^1]: This includes types, lifetimes / regions, constants in type positions,
14//! trait references and bounds.
15
16mod bounds;
17mod cmse;
18mod dyn_trait;
19pub mod errors;
20pub mod generics;
21
22use std::assert_matches::assert_matches;
23use std::slice;
24
25use rustc_ast::LitKind;
26use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
27use rustc_errors::codes::*;
28use rustc_errors::{
29    Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, struct_span_code_err,
30};
31use rustc_hir::attrs::AttributeKind;
32use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
33use rustc_hir::def_id::{DefId, LocalDefId};
34use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId, find_attr};
35use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
36use rustc_infer::traits::DynCompatibilityViolation;
37use rustc_macros::{TypeFoldable, TypeVisitable};
38use rustc_middle::middle::stability::AllowUnstable;
39use rustc_middle::mir::interpret::LitToConstInput;
40use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
41use rustc_middle::ty::{
42    self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, Ty, TyCtxt,
43    TypeSuperFoldable, TypeVisitableExt, TypingMode, Upcast, fold_regions,
44};
45use rustc_middle::{bug, span_bug};
46use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
47use rustc_session::parse::feature_err;
48use rustc_span::{DUMMY_SP, Ident, Span, kw, sym};
49use rustc_trait_selection::infer::InferCtxtExt;
50use rustc_trait_selection::traits::wf::object_region_bounds;
51use rustc_trait_selection::traits::{self, FulfillmentError};
52use tracing::{debug, instrument};
53
54use crate::check::check_abi;
55use crate::check_c_variadic_abi;
56use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation};
57use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
58use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
59use crate::middle::resolve_bound_vars as rbv;
60
61/// The context in which an implied bound is being added to a item being lowered (i.e. a sizedness
62/// trait or a default trait)
63#[derive(Clone, Copy)]
64pub(crate) enum ImpliedBoundsContext<'tcx> {
65    /// An implied bound is added to a trait definition (i.e. a new supertrait), used when adding
66    /// a default `MetaSized` supertrait
67    TraitDef(LocalDefId),
68    /// An implied bound is added to a type parameter
69    TyParam(LocalDefId, &'tcx [hir::WherePredicate<'tcx>]),
70    /// An implied bound being added in any other context
71    AssociatedTypeOrImplTrait,
72}
73
74/// A path segment that is semantically allowed to have generic arguments.
75#[derive(Debug)]
76pub struct GenericPathSegment(pub DefId, pub usize);
77
78#[derive(Copy, Clone, Debug)]
79pub enum PredicateFilter {
80    /// All predicates may be implied by the trait.
81    All,
82
83    /// Only traits that reference `Self: ..` are implied by the trait.
84    SelfOnly,
85
86    /// Only traits that reference `Self: ..` and define an associated type
87    /// with the given ident are implied by the trait. This mode exists to
88    /// side-step query cycles when lowering associated types.
89    SelfTraitThatDefines(Ident),
90
91    /// Only traits that reference `Self: ..` and their associated type bounds.
92    /// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr`
93    /// and `<Self as Tr>::A: B`.
94    SelfAndAssociatedTypeBounds,
95
96    /// Filter only the `[const]` bounds, which are lowered into `HostEffect` clauses.
97    ConstIfConst,
98
99    /// Filter only the `[const]` bounds which are *also* in the supertrait position.
100    SelfConstIfConst,
101}
102
103#[derive(Debug)]
104pub enum RegionInferReason<'a> {
105    /// Lifetime on a trait object that is spelled explicitly, e.g. `+ 'a` or `+ '_`.
106    ExplicitObjectLifetime,
107    /// A trait object's lifetime when it is elided, e.g. `dyn Any`.
108    ObjectLifetimeDefault,
109    /// Generic lifetime parameter
110    Param(&'a ty::GenericParamDef),
111    RegionPredicate,
112    Reference,
113    OutlivesBound,
114}
115
116#[derive(Copy, Clone, TypeFoldable, TypeVisitable, Debug)]
117pub struct InherentAssocCandidate {
118    pub impl_: DefId,
119    pub assoc_item: DefId,
120    pub scope: DefId,
121}
122
123/// A context which can lower type-system entities from the [HIR][hir] to
124/// the [`rustc_middle::ty`] representation.
125///
126/// This trait used to be called `AstConv`.
127pub trait HirTyLowerer<'tcx> {
128    fn tcx(&self) -> TyCtxt<'tcx>;
129
130    fn dcx(&self) -> DiagCtxtHandle<'_>;
131
132    /// Returns the [`LocalDefId`] of the overarching item whose constituents get lowered.
133    fn item_def_id(&self) -> LocalDefId;
134
135    /// Returns the region to use when a lifetime is omitted (and not elided).
136    fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx>;
137
138    /// Returns the type to use when a type is omitted.
139    fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
140
141    /// Returns the const to use when a const is omitted.
142    fn ct_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx>;
143
144    fn register_trait_ascription_bounds(
145        &self,
146        bounds: Vec<(ty::Clause<'tcx>, Span)>,
147        hir_id: HirId,
148        span: Span,
149    );
150
151    /// Probe bounds in scope where the bounded type coincides with the given type parameter.
152    ///
153    /// Rephrased, this returns bounds of the form `T: Trait`, where `T` is a type parameter
154    /// with the given `def_id`. This is a subset of the full set of bounds.
155    ///
156    /// This method may use the given `assoc_name` to disregard bounds whose trait reference
157    /// doesn't define an associated item with the provided name.
158    ///
159    /// This is used for one specific purpose: Resolving “short-hand” associated type references
160    /// like `T::Item` where `T` is a type parameter. In principle, we would do that by first
161    /// getting the full set of predicates in scope and then filtering down to find those that
162    /// apply to `T`, but this can lead to cycle errors. The problem is that we have to do this
163    /// resolution *in order to create the predicates in the first place*.
164    /// Hence, we have this “special pass”.
165    fn probe_ty_param_bounds(
166        &self,
167        span: Span,
168        def_id: LocalDefId,
169        assoc_ident: Ident,
170    ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]>;
171
172    fn select_inherent_assoc_candidates(
173        &self,
174        span: Span,
175        self_ty: Ty<'tcx>,
176        candidates: Vec<InherentAssocCandidate>,
177    ) -> (Vec<InherentAssocCandidate>, Vec<FulfillmentError<'tcx>>);
178
179    /// Lower a path to an associated item (of a trait) to a projection.
180    ///
181    /// This method has to be defined by the concrete lowering context because
182    /// dealing with higher-ranked trait references depends on its capabilities:
183    ///
184    /// If the context can make use of type inference, it can simply instantiate
185    /// any late-bound vars bound by the trait reference with inference variables.
186    /// If it doesn't support type inference, there is nothing reasonable it can
187    /// do except reject the associated type.
188    ///
189    /// The canonical example of this is associated type `T::P` where `T` is a type
190    /// param constrained by `T: for<'a> Trait<'a>` and where `Trait` defines `P`.
191    fn lower_assoc_item_path(
192        &self,
193        span: Span,
194        item_def_id: DefId,
195        item_segment: &hir::PathSegment<'tcx>,
196        poly_trait_ref: ty::PolyTraitRef<'tcx>,
197    ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed>;
198
199    fn lower_fn_sig(
200        &self,
201        decl: &hir::FnDecl<'tcx>,
202        generics: Option<&hir::Generics<'_>>,
203        hir_id: HirId,
204        hir_ty: Option<&hir::Ty<'_>>,
205    ) -> (Vec<Ty<'tcx>>, Ty<'tcx>);
206
207    /// Returns `AdtDef` if `ty` is an ADT.
208    ///
209    /// Note that `ty` might be a alias type that needs normalization.
210    /// This used to get the enum variants in scope of the type.
211    /// For example, `Self::A` could refer to an associated type
212    /// or to an enum variant depending on the result of this function.
213    fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>>;
214
215    /// Record the lowered type of a HIR node in this context.
216    fn record_ty(&self, hir_id: HirId, ty: Ty<'tcx>, span: Span);
217
218    /// The inference context of the lowering context if applicable.
219    fn infcx(&self) -> Option<&InferCtxt<'tcx>>;
220
221    /// Convenience method for coercing the lowering context into a trait object type.
222    ///
223    /// Most lowering routines are defined on the trait object type directly
224    /// necessitating a coercion step from the concrete lowering context.
225    fn lowerer(&self) -> &dyn HirTyLowerer<'tcx>
226    where
227        Self: Sized,
228    {
229        self
230    }
231
232    /// Performs minimalistic dyn compat checks outside of bodies, but full within bodies.
233    /// Outside of bodies we could end up in cycles, so we delay most checks to later phases.
234    fn dyn_compatibility_violations(&self, trait_def_id: DefId) -> Vec<DynCompatibilityViolation>;
235}
236
237/// The "qualified self" of an associated item path.
238///
239/// For diagnostic purposes only.
240enum AssocItemQSelf {
241    Trait(DefId),
242    TyParam(LocalDefId, Span),
243    SelfTyAlias,
244}
245
246impl AssocItemQSelf {
247    fn to_string(&self, tcx: TyCtxt<'_>) -> String {
248        match *self {
249            Self::Trait(def_id) => tcx.def_path_str(def_id),
250            Self::TyParam(def_id, _) => tcx.hir_ty_param_name(def_id).to_string(),
251            Self::SelfTyAlias => kw::SelfUpper.to_string(),
252        }
253    }
254}
255
256/// In some cases, [`hir::ConstArg`]s that are being used in the type system
257/// through const generics need to have their type "fed" to them
258/// using the query system.
259///
260/// Use this enum with `<dyn HirTyLowerer>::lower_const_arg` to instruct it with the
261/// desired behavior.
262#[derive(Debug, Clone, Copy)]
263pub enum FeedConstTy<'tcx> {
264    /// Feed the type to the (anno) const arg.
265    WithTy(Ty<'tcx>),
266    /// Don't feed the type.
267    No,
268}
269
270impl<'tcx> FeedConstTy<'tcx> {
271    /// The `DefId` belongs to the const param that we are supplying
272    /// this (anon) const arg to.
273    ///
274    /// The list of generic args is used to instantiate the parameters
275    /// used by the type of the const param specified by `DefId`.
276    pub fn with_type_of(
277        tcx: TyCtxt<'tcx>,
278        def_id: DefId,
279        generic_args: &[ty::GenericArg<'tcx>],
280    ) -> Self {
281        Self::WithTy(tcx.type_of(def_id).instantiate(tcx, generic_args))
282    }
283}
284
285#[derive(Debug, Clone, Copy)]
286enum LowerTypeRelativePathMode {
287    Type(PermitVariants),
288    Const,
289}
290
291impl LowerTypeRelativePathMode {
292    fn assoc_tag(self) -> ty::AssocTag {
293        match self {
294            Self::Type(_) => ty::AssocTag::Type,
295            Self::Const => ty::AssocTag::Const,
296        }
297    }
298
299    fn def_kind(self) -> DefKind {
300        match self {
301            Self::Type(_) => DefKind::AssocTy,
302            Self::Const => DefKind::AssocConst,
303        }
304    }
305
306    fn permit_variants(self) -> PermitVariants {
307        match self {
308            Self::Type(permit_variants) => permit_variants,
309            // FIXME(mgca): Support paths like `Option::<T>::None` or `Option::<T>::Some` which
310            // resolve to const ctors/fn items respectively.
311            Self::Const => PermitVariants::No,
312        }
313    }
314}
315
316/// Whether to permit a path to resolve to an enum variant.
317#[derive(Debug, Clone, Copy)]
318pub enum PermitVariants {
319    Yes,
320    No,
321}
322
323#[derive(Debug, Clone, Copy)]
324enum TypeRelativePath<'tcx> {
325    AssocItem(DefId, GenericArgsRef<'tcx>),
326    Variant { adt: Ty<'tcx>, variant_did: DefId },
327    Ctor { ctor_def_id: DefId, args: GenericArgsRef<'tcx> },
328}
329
330/// New-typed boolean indicating whether explicit late-bound lifetimes
331/// are present in a set of generic arguments.
332///
333/// For example if we have some method `fn f<'a>(&'a self)` implemented
334/// for some type `T`, although `f` is generic in the lifetime `'a`, `'a`
335/// is late-bound so should not be provided explicitly. Thus, if `f` is
336/// instantiated with some generic arguments providing `'a` explicitly,
337/// we taint those arguments with `ExplicitLateBound::Yes` so that we
338/// can provide an appropriate diagnostic later.
339#[derive(Copy, Clone, PartialEq, Debug)]
340pub enum ExplicitLateBound {
341    Yes,
342    No,
343}
344
345#[derive(Copy, Clone, PartialEq)]
346pub enum IsMethodCall {
347    Yes,
348    No,
349}
350
351/// Denotes the "position" of a generic argument, indicating if it is a generic type,
352/// generic function or generic method call.
353#[derive(Copy, Clone, PartialEq)]
354pub(crate) enum GenericArgPosition {
355    Type,
356    Value, // e.g., functions
357    MethodCall,
358}
359
360/// Whether to allow duplicate associated iten constraints in a trait ref, e.g.
361/// `Trait<Assoc = Ty, Assoc = Ty>`. This is forbidden in `dyn Trait<...>`
362/// but allowed everywhere else.
363#[derive(Clone, Copy, Debug, PartialEq)]
364pub(crate) enum OverlappingAsssocItemConstraints {
365    Allowed,
366    Forbidden,
367}
368
369/// A marker denoting that the generic arguments that were
370/// provided did not match the respective generic parameters.
371#[derive(Clone, Debug)]
372pub struct GenericArgCountMismatch {
373    pub reported: ErrorGuaranteed,
374    /// A list of indices of arguments provided that were not valid.
375    pub invalid_args: Vec<usize>,
376}
377
378/// Decorates the result of a generic argument count mismatch
379/// check with whether explicit late bounds were provided.
380#[derive(Clone, Debug)]
381pub struct GenericArgCountResult {
382    pub explicit_late_bound: ExplicitLateBound,
383    pub correct: Result<(), GenericArgCountMismatch>,
384}
385
386/// A context which can lower HIR's [`GenericArg`] to `rustc_middle`'s [`ty::GenericArg`].
387///
388/// Its only consumer is [`generics::lower_generic_args`].
389/// Read its documentation to learn more.
390pub trait GenericArgsLowerer<'a, 'tcx> {
391    fn args_for_def_id(&mut self, def_id: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool);
392
393    fn provided_kind(
394        &mut self,
395        preceding_args: &[ty::GenericArg<'tcx>],
396        param: &ty::GenericParamDef,
397        arg: &GenericArg<'tcx>,
398    ) -> ty::GenericArg<'tcx>;
399
400    fn inferred_kind(
401        &mut self,
402        preceding_args: &[ty::GenericArg<'tcx>],
403        param: &ty::GenericParamDef,
404        infer_args: bool,
405    ) -> ty::GenericArg<'tcx>;
406}
407
408struct ForbidMCGParamUsesFolder<'tcx> {
409    tcx: TyCtxt<'tcx>,
410    anon_const_def_id: LocalDefId,
411    span: Span,
412    is_self_alias: bool,
413}
414
415impl<'tcx> ForbidMCGParamUsesFolder<'tcx> {
416    fn error(&self) -> ErrorGuaranteed {
417        let msg = if self.is_self_alias {
418            "generic `Self` types are currently not permitted in anonymous constants"
419        } else {
420            "generic parameters may not be used in const operations"
421        };
422        let mut diag = self.tcx.dcx().struct_span_err(self.span, msg);
423        if self.is_self_alias {
424            let anon_const_hir_id: HirId = HirId::make_owner(self.anon_const_def_id);
425            let parent_impl = self.tcx.hir_parent_owner_iter(anon_const_hir_id).find_map(
426                |(_, node)| match node {
427                    hir::OwnerNode::Item(hir::Item {
428                        kind: hir::ItemKind::Impl(impl_), ..
429                    }) => Some(impl_),
430                    _ => None,
431                },
432            );
433            if let Some(impl_) = parent_impl {
434                diag.span_note(impl_.self_ty.span, "not a concrete type");
435            }
436        }
437        diag.emit()
438    }
439}
440
441impl<'tcx> ty::TypeFolder<TyCtxt<'tcx>> for ForbidMCGParamUsesFolder<'tcx> {
442    fn cx(&self) -> TyCtxt<'tcx> {
443        self.tcx
444    }
445
446    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
447        if matches!(t.kind(), ty::Param(..)) {
448            return Ty::new_error(self.tcx, self.error());
449        }
450        t.super_fold_with(self)
451    }
452
453    fn fold_const(&mut self, c: Const<'tcx>) -> Const<'tcx> {
454        if matches!(c.kind(), ty::ConstKind::Param(..)) {
455            return Const::new_error(self.tcx, self.error());
456        }
457        c.super_fold_with(self)
458    }
459
460    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
461        if matches!(r.kind(), ty::RegionKind::ReEarlyParam(..) | ty::RegionKind::ReLateParam(..)) {
462            return ty::Region::new_error(self.tcx, self.error());
463        }
464        r
465    }
466}
467
468impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
469    /// See `check_param_uses_if_mcg`.
470    ///
471    /// FIXME(mgca): this is pub only for instantiate_value_path and would be nice to avoid altogether
472    pub fn check_param_res_if_mcg_for_instantiate_value_path(
473        &self,
474        res: Res,
475        span: Span,
476    ) -> Result<(), ErrorGuaranteed> {
477        let tcx = self.tcx();
478        let parent_def_id = self.item_def_id();
479        if let Res::Def(DefKind::ConstParam, _) = res
480            && tcx.def_kind(parent_def_id) == DefKind::AnonConst
481            && let ty::AnonConstKind::MCG = tcx.anon_const_kind(parent_def_id)
482        {
483            let folder = ForbidMCGParamUsesFolder {
484                tcx,
485                anon_const_def_id: parent_def_id,
486                span,
487                is_self_alias: false,
488            };
489            return Err(folder.error());
490        }
491        Ok(())
492    }
493
494    /// Check for uses of generic parameters that are not in scope due to this being
495    /// in a non-generic anon const context.
496    #[must_use = "need to use transformed output"]
497    fn check_param_uses_if_mcg<T>(&self, term: T, span: Span, is_self_alias: bool) -> T
498    where
499        T: ty::TypeFoldable<TyCtxt<'tcx>>,
500    {
501        let tcx = self.tcx();
502        let parent_def_id = self.item_def_id();
503        if tcx.def_kind(parent_def_id) == DefKind::AnonConst
504            && let ty::AnonConstKind::MCG = tcx.anon_const_kind(parent_def_id)
505            // Fast path if contains no params/escaping bound vars.
506            && (term.has_param() || term.has_escaping_bound_vars())
507        {
508            let mut folder = ForbidMCGParamUsesFolder {
509                tcx,
510                anon_const_def_id: parent_def_id,
511                span,
512                is_self_alias,
513            };
514            term.fold_with(&mut folder)
515        } else {
516            term
517        }
518    }
519
520    /// Lower a lifetime from the HIR to our internal notion of a lifetime called a *region*.
521    #[instrument(level = "debug", skip(self), ret)]
522    pub fn lower_lifetime(
523        &self,
524        lifetime: &hir::Lifetime,
525        reason: RegionInferReason<'_>,
526    ) -> ty::Region<'tcx> {
527        if let Some(resolved) = self.tcx().named_bound_var(lifetime.hir_id) {
528            let region = self.lower_resolved_lifetime(resolved);
529            self.check_param_uses_if_mcg(region, lifetime.ident.span, false)
530        } else {
531            self.re_infer(lifetime.ident.span, reason)
532        }
533    }
534
535    /// Lower a lifetime from the HIR to our internal notion of a lifetime called a *region*.
536    #[instrument(level = "debug", skip(self), ret)]
537    fn lower_resolved_lifetime(&self, resolved: rbv::ResolvedArg) -> ty::Region<'tcx> {
538        let tcx = self.tcx();
539
540        match resolved {
541            rbv::ResolvedArg::StaticLifetime => tcx.lifetimes.re_static,
542
543            rbv::ResolvedArg::LateBound(debruijn, index, def_id) => {
544                let br = ty::BoundRegion {
545                    var: ty::BoundVar::from_u32(index),
546                    kind: ty::BoundRegionKind::Named(def_id.to_def_id()),
547                };
548                ty::Region::new_bound(tcx, debruijn, br)
549            }
550
551            rbv::ResolvedArg::EarlyBound(def_id) => {
552                let name = tcx.hir_ty_param_name(def_id);
553                let item_def_id = tcx.hir_ty_param_owner(def_id);
554                let generics = tcx.generics_of(item_def_id);
555                let index = generics.param_def_id_to_index[&def_id.to_def_id()];
556                ty::Region::new_early_param(tcx, ty::EarlyParamRegion { index, name })
557            }
558
559            rbv::ResolvedArg::Free(scope, id) => {
560                ty::Region::new_late_param(
561                    tcx,
562                    scope.to_def_id(),
563                    ty::LateParamRegionKind::Named(id.to_def_id()),
564                )
565
566                // (*) -- not late-bound, won't change
567            }
568
569            rbv::ResolvedArg::Error(guar) => ty::Region::new_error(tcx, guar),
570        }
571    }
572
573    pub fn lower_generic_args_of_path_segment(
574        &self,
575        span: Span,
576        def_id: DefId,
577        item_segment: &hir::PathSegment<'tcx>,
578    ) -> GenericArgsRef<'tcx> {
579        let (args, _) = self.lower_generic_args_of_path(span, def_id, &[], item_segment, None);
580        if let Some(c) = item_segment.args().constraints.first() {
581            prohibit_assoc_item_constraint(self, c, Some((def_id, item_segment, span)));
582        }
583        args
584    }
585
586    /// Lower the generic arguments provided to some path.
587    ///
588    /// If this is a trait reference, you also need to pass the self type `self_ty`.
589    /// The lowering process may involve applying defaulted type parameters.
590    ///
591    /// Associated item constraints are not handled here! They are either lowered via
592    /// `lower_assoc_item_constraint` or rejected via `prohibit_assoc_item_constraint`.
593    ///
594    /// ### Example
595    ///
596    /// ```ignore (illustrative)
597    ///    T: std::ops::Index<usize, Output = u32>
598    /// // ^1 ^^^^^^^^^^^^^^2 ^^^^3  ^^^^^^^^^^^4
599    /// ```
600    ///
601    /// 1. The `self_ty` here would refer to the type `T`.
602    /// 2. The path in question is the path to the trait `std::ops::Index`,
603    ///    which will have been resolved to a `def_id`
604    /// 3. The `generic_args` contains info on the `<...>` contents. The `usize` type
605    ///    parameters are returned in the `GenericArgsRef`
606    /// 4. Associated item constraints like `Output = u32` are contained in `generic_args.constraints`.
607    ///
608    /// Note that the type listing given here is *exactly* what the user provided.
609    ///
610    /// For (generic) associated types
611    ///
612    /// ```ignore (illustrative)
613    /// <Vec<u8> as Iterable<u8>>::Iter::<'a>
614    /// ```
615    ///
616    /// We have the parent args are the args for the parent trait:
617    /// `[Vec<u8>, u8]` and `generic_args` are the arguments for the associated
618    /// type itself: `['a]`. The returned `GenericArgsRef` concatenates these two
619    /// lists: `[Vec<u8>, u8, 'a]`.
620    #[instrument(level = "debug", skip(self, span), ret)]
621    fn lower_generic_args_of_path(
622        &self,
623        span: Span,
624        def_id: DefId,
625        parent_args: &[ty::GenericArg<'tcx>],
626        segment: &hir::PathSegment<'tcx>,
627        self_ty: Option<Ty<'tcx>>,
628    ) -> (GenericArgsRef<'tcx>, GenericArgCountResult) {
629        // If the type is parameterized by this region, then replace this
630        // region with the current anon region binding (in other words,
631        // whatever & would get replaced with).
632
633        let tcx = self.tcx();
634        let generics = tcx.generics_of(def_id);
635        debug!(?generics);
636
637        if generics.has_self {
638            if generics.parent.is_some() {
639                // The parent is a trait so it should have at least one
640                // generic parameter for the `Self` type.
641                assert!(!parent_args.is_empty())
642            } else {
643                // This item (presumably a trait) needs a self-type.
644                assert!(self_ty.is_some());
645            }
646        } else {
647            assert!(self_ty.is_none());
648        }
649
650        let arg_count = check_generic_arg_count(
651            self,
652            def_id,
653            segment,
654            generics,
655            GenericArgPosition::Type,
656            self_ty.is_some(),
657        );
658
659        // Skip processing if type has no generic parameters.
660        // Traits always have `Self` as a generic parameter, which means they will not return early
661        // here and so associated item constraints will be handled regardless of whether there are
662        // any non-`Self` generic parameters.
663        if generics.is_own_empty() {
664            return (tcx.mk_args(parent_args), arg_count);
665        }
666
667        struct GenericArgsCtxt<'a, 'tcx> {
668            lowerer: &'a dyn HirTyLowerer<'tcx>,
669            def_id: DefId,
670            generic_args: &'a GenericArgs<'tcx>,
671            span: Span,
672            infer_args: bool,
673            incorrect_args: &'a Result<(), GenericArgCountMismatch>,
674        }
675
676        impl<'a, 'tcx> GenericArgsLowerer<'a, 'tcx> for GenericArgsCtxt<'a, 'tcx> {
677            fn args_for_def_id(&mut self, did: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool) {
678                if did == self.def_id {
679                    (Some(self.generic_args), self.infer_args)
680                } else {
681                    // The last component of this tuple is unimportant.
682                    (None, false)
683                }
684            }
685
686            fn provided_kind(
687                &mut self,
688                preceding_args: &[ty::GenericArg<'tcx>],
689                param: &ty::GenericParamDef,
690                arg: &GenericArg<'tcx>,
691            ) -> ty::GenericArg<'tcx> {
692                let tcx = self.lowerer.tcx();
693
694                if let Err(incorrect) = self.incorrect_args {
695                    if incorrect.invalid_args.contains(&(param.index as usize)) {
696                        return param.to_error(tcx);
697                    }
698                }
699
700                let handle_ty_args = |has_default, ty: &hir::Ty<'tcx>| {
701                    if has_default {
702                        tcx.check_optional_stability(
703                            param.def_id,
704                            Some(arg.hir_id()),
705                            arg.span(),
706                            None,
707                            AllowUnstable::No,
708                            |_, _| {
709                                // Default generic parameters may not be marked
710                                // with stability attributes, i.e. when the
711                                // default parameter was defined at the same time
712                                // as the rest of the type. As such, we ignore missing
713                                // stability attributes.
714                            },
715                        );
716                    }
717                    self.lowerer.lower_ty(ty).into()
718                };
719
720                match (&param.kind, arg) {
721                    (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
722                        self.lowerer.lower_lifetime(lt, RegionInferReason::Param(param)).into()
723                    }
724                    (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
725                        // We handle the other parts of `Ty` in the match arm below
726                        handle_ty_args(has_default, ty.as_unambig_ty())
727                    }
728                    (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Infer(inf)) => {
729                        handle_ty_args(has_default, &inf.to_ty())
730                    }
731                    (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
732                        .lowerer
733                        // Ambig portions of `ConstArg` are handled in the match arm below
734                        .lower_const_arg(
735                            ct.as_unambig_ct(),
736                            FeedConstTy::with_type_of(tcx, param.def_id, preceding_args),
737                        )
738                        .into(),
739                    (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
740                        self.lowerer.ct_infer(Some(param), inf.span).into()
741                    }
742                    (kind, arg) => span_bug!(
743                        self.span,
744                        "mismatched path argument for kind {kind:?}: found arg {arg:?}"
745                    ),
746                }
747            }
748
749            fn inferred_kind(
750                &mut self,
751                preceding_args: &[ty::GenericArg<'tcx>],
752                param: &ty::GenericParamDef,
753                infer_args: bool,
754            ) -> ty::GenericArg<'tcx> {
755                let tcx = self.lowerer.tcx();
756
757                if let Err(incorrect) = self.incorrect_args {
758                    if incorrect.invalid_args.contains(&(param.index as usize)) {
759                        return param.to_error(tcx);
760                    }
761                }
762                match param.kind {
763                    GenericParamDefKind::Lifetime => {
764                        self.lowerer.re_infer(self.span, RegionInferReason::Param(param)).into()
765                    }
766                    GenericParamDefKind::Type { has_default, .. } => {
767                        if !infer_args && has_default {
768                            // No type parameter provided, but a default exists.
769                            if let Some(prev) =
770                                preceding_args.iter().find_map(|arg| match arg.kind() {
771                                    GenericArgKind::Type(ty) => ty.error_reported().err(),
772                                    _ => None,
773                                })
774                            {
775                                // Avoid ICE #86756 when type error recovery goes awry.
776                                return Ty::new_error(tcx, prev).into();
777                            }
778                            tcx.at(self.span)
779                                .type_of(param.def_id)
780                                .instantiate(tcx, preceding_args)
781                                .into()
782                        } else if infer_args {
783                            self.lowerer.ty_infer(Some(param), self.span).into()
784                        } else {
785                            // We've already errored above about the mismatch.
786                            Ty::new_misc_error(tcx).into()
787                        }
788                    }
789                    GenericParamDefKind::Const { has_default, .. } => {
790                        let ty = tcx
791                            .at(self.span)
792                            .type_of(param.def_id)
793                            .instantiate(tcx, preceding_args);
794                        if let Err(guar) = ty.error_reported() {
795                            return ty::Const::new_error(tcx, guar).into();
796                        }
797                        if !infer_args && has_default {
798                            tcx.const_param_default(param.def_id)
799                                .instantiate(tcx, preceding_args)
800                                .into()
801                        } else if infer_args {
802                            self.lowerer.ct_infer(Some(param), self.span).into()
803                        } else {
804                            // We've already errored above about the mismatch.
805                            ty::Const::new_misc_error(tcx).into()
806                        }
807                    }
808                }
809            }
810        }
811
812        let mut args_ctx = GenericArgsCtxt {
813            lowerer: self,
814            def_id,
815            span,
816            generic_args: segment.args(),
817            infer_args: segment.infer_args,
818            incorrect_args: &arg_count.correct,
819        };
820        let args = lower_generic_args(
821            self,
822            def_id,
823            parent_args,
824            self_ty.is_some(),
825            self_ty,
826            &arg_count,
827            &mut args_ctx,
828        );
829
830        (args, arg_count)
831    }
832
833    #[instrument(level = "debug", skip(self))]
834    pub fn lower_generic_args_of_assoc_item(
835        &self,
836        span: Span,
837        item_def_id: DefId,
838        item_segment: &hir::PathSegment<'tcx>,
839        parent_args: GenericArgsRef<'tcx>,
840    ) -> GenericArgsRef<'tcx> {
841        let (args, _) =
842            self.lower_generic_args_of_path(span, item_def_id, parent_args, item_segment, None);
843        if let Some(c) = item_segment.args().constraints.first() {
844            prohibit_assoc_item_constraint(self, c, Some((item_def_id, item_segment, span)));
845        }
846        args
847    }
848
849    /// Lower a trait reference as found in an impl header as the implementee.
850    ///
851    /// The self type `self_ty` is the implementer of the trait.
852    pub fn lower_impl_trait_ref(
853        &self,
854        trait_ref: &hir::TraitRef<'tcx>,
855        self_ty: Ty<'tcx>,
856    ) -> ty::TraitRef<'tcx> {
857        let [leading_segments @ .., segment] = trait_ref.path.segments else { bug!() };
858
859        let _ = self.prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
860
861        self.lower_mono_trait_ref(
862            trait_ref.path.span,
863            trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()),
864            self_ty,
865            segment,
866            true,
867        )
868    }
869
870    /// Lower a polymorphic trait reference given a self type into `bounds`.
871    ///
872    /// *Polymorphic* in the sense that it may bind late-bound vars.
873    ///
874    /// This may generate auxiliary bounds iff the trait reference contains associated item constraints.
875    ///
876    /// ### Example
877    ///
878    /// Given the trait ref `Iterator<Item = u32>` and the self type `Ty`, this will add the
879    ///
880    /// 1. *trait predicate* `<Ty as Iterator>` (known as `Ty: Iterator` in the surface syntax) and the
881    /// 2. *projection predicate* `<Ty as Iterator>::Item = u32`
882    ///
883    /// to `bounds`.
884    ///
885    /// ### A Note on Binders
886    ///
887    /// Against our usual convention, there is an implied binder around the `self_ty` and the
888    /// `trait_ref` here. So they may reference late-bound vars.
889    ///
890    /// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>`
891    /// where `'a` is a bound region at depth 0. Similarly, the `trait_ref` would be `Bar<'a>`.
892    /// The lowered poly-trait-ref will track this binder explicitly, however.
893    #[instrument(level = "debug", skip(self, bounds))]
894    pub(crate) fn lower_poly_trait_ref(
895        &self,
896        &hir::PolyTraitRef {
897            bound_generic_params,
898            modifiers: hir::TraitBoundModifiers { constness, polarity },
899            trait_ref,
900            span,
901        }: &hir::PolyTraitRef<'tcx>,
902        self_ty: Ty<'tcx>,
903        bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
904        predicate_filter: PredicateFilter,
905        overlapping_assoc_item_constraints: OverlappingAsssocItemConstraints,
906    ) -> GenericArgCountResult {
907        let tcx = self.tcx();
908
909        // We use the *resolved* bound vars later instead of the HIR ones since the former
910        // also include the bound vars of the overarching predicate if applicable.
911        let _ = bound_generic_params;
912
913        let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
914
915        // Relaxed bounds `?Trait` and `PointeeSized` bounds aren't represented in the middle::ty IR
916        // as they denote the *absence* of a default bound. However, we can't bail out early here since
917        // we still need to perform several validation steps (see below). Instead, simply "pour" all
918        // resulting bounds "down the drain", i.e., into a new `Vec` that just gets dropped at the end.
919        let transient = match polarity {
920            hir::BoundPolarity::Positive => {
921                // To elaborate on the comment directly above, regarding `PointeeSized` specifically,
922                // we don't "reify" such bounds to avoid trait system limitations -- namely,
923                // non-global where-clauses being preferred over item bounds (where `PointeeSized`
924                // bounds would be proven) -- which can result in errors when a `PointeeSized`
925                // supertrait / bound / predicate is added to some items.
926                tcx.is_lang_item(trait_def_id, hir::LangItem::PointeeSized)
927            }
928            hir::BoundPolarity::Negative(_) => false,
929            hir::BoundPolarity::Maybe(_) => {
930                self.require_bound_to_relax_default_trait(trait_ref, span);
931                true
932            }
933        };
934        let bounds = if transient { &mut Vec::new() } else { bounds };
935
936        let polarity = match polarity {
937            hir::BoundPolarity::Positive | hir::BoundPolarity::Maybe(_) => {
938                ty::PredicatePolarity::Positive
939            }
940            hir::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
941        };
942
943        let [leading_segments @ .., segment] = trait_ref.path.segments else { bug!() };
944
945        let _ = self.prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
946        self.report_internal_fn_trait(span, trait_def_id, segment, false);
947
948        let (generic_args, arg_count) = self.lower_generic_args_of_path(
949            trait_ref.path.span,
950            trait_def_id,
951            &[],
952            segment,
953            Some(self_ty),
954        );
955
956        let constraints = segment.args().constraints;
957
958        if transient && (!generic_args[1..].is_empty() || !constraints.is_empty()) {
959            // Since the bound won't be present in the middle::ty IR as established above, any
960            // arguments or constraints won't be checked for well-formedness in later passes.
961            //
962            // This is only an issue if the trait ref is otherwise valid which can only happen if
963            // the corresponding default trait has generic parameters or associated items. Such a
964            // trait would be degenerate. We delay a bug to detect and guard us against these.
965            //
966            // E.g: Given `/*default*/ trait Bound<'a: 'static, T, const N: usize> {}`,
967            // `?Bound<Vec<str>, { panic!() }>` won't be wfchecked.
968            self.dcx()
969                .span_delayed_bug(span, "transient bound should not have args or constraints");
970        }
971
972        let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
973        debug!(?bound_vars);
974
975        let poly_trait_ref = ty::Binder::bind_with_vars(
976            ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args),
977            bound_vars,
978        );
979
980        debug!(?poly_trait_ref);
981
982        // We deal with const conditions later.
983        match predicate_filter {
984            PredicateFilter::All
985            | PredicateFilter::SelfOnly
986            | PredicateFilter::SelfTraitThatDefines(..)
987            | PredicateFilter::SelfAndAssociatedTypeBounds => {
988                let bound = poly_trait_ref.map_bound(|trait_ref| {
989                    ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity })
990                });
991                let bound = (bound.upcast(tcx), span);
992                // FIXME(-Znext-solver): We can likely remove this hack once the
993                // new trait solver lands. This fixed an overflow in the old solver.
994                // This may have performance implications, so please check perf when
995                // removing it.
996                // This was added in <https://github.com/rust-lang/rust/pull/123302>.
997                if tcx.is_lang_item(trait_def_id, rustc_hir::LangItem::Sized) {
998                    bounds.insert(0, bound);
999                } else {
1000                    bounds.push(bound);
1001                }
1002            }
1003            PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
1004        }
1005
1006        if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness
1007            && !tcx.is_const_trait(trait_def_id)
1008        {
1009            let (def_span, suggestion, suggestion_pre) =
1010                match (trait_def_id.as_local(), tcx.sess.is_nightly_build()) {
1011                    (Some(trait_def_id), true) => {
1012                        let span = tcx.hir_expect_item(trait_def_id).vis_span;
1013                        let span = tcx.sess.source_map().span_extend_while_whitespace(span);
1014
1015                        (
1016                            None,
1017                            Some(span.shrink_to_hi()),
1018                            if self.tcx().features().const_trait_impl() {
1019                                ""
1020                            } else {
1021                                "enable `#![feature(const_trait_impl)]` in your crate and "
1022                            },
1023                        )
1024                    }
1025                    (None, _) | (_, false) => (Some(tcx.def_span(trait_def_id)), None, ""),
1026                };
1027            self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
1028                span,
1029                modifier: constness.as_str(),
1030                def_span,
1031                trait_name: tcx.def_path_str(trait_def_id),
1032                suggestion,
1033                suggestion_pre,
1034            });
1035        } else {
1036            match predicate_filter {
1037                // This is only concerned with trait predicates.
1038                PredicateFilter::SelfTraitThatDefines(..) => {}
1039                PredicateFilter::All
1040                | PredicateFilter::SelfOnly
1041                | PredicateFilter::SelfAndAssociatedTypeBounds => {
1042                    match constness {
1043                        hir::BoundConstness::Always(_) => {
1044                            if polarity == ty::PredicatePolarity::Positive {
1045                                bounds.push((
1046                                    poly_trait_ref
1047                                        .to_host_effect_clause(tcx, ty::BoundConstness::Const),
1048                                    span,
1049                                ));
1050                            }
1051                        }
1052                        hir::BoundConstness::Maybe(_) => {
1053                            // We don't emit a const bound here, since that would mean that we
1054                            // unconditionally need to prove a `HostEffect` predicate, even when
1055                            // the predicates are being instantiated in a non-const context. This
1056                            // is instead handled in the `const_conditions` query.
1057                        }
1058                        hir::BoundConstness::Never => {}
1059                    }
1060                }
1061                // On the flip side, when filtering `ConstIfConst` bounds, we only need to convert
1062                // `[const]` bounds. All other predicates are handled in their respective queries.
1063                //
1064                // Note that like `PredicateFilter::SelfOnly`, we don't need to do any filtering
1065                // here because we only call this on self bounds, and deal with the recursive case
1066                // in `lower_assoc_item_constraint`.
1067                PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {
1068                    match constness {
1069                        hir::BoundConstness::Maybe(_) => {
1070                            if polarity == ty::PredicatePolarity::Positive {
1071                                bounds.push((
1072                                    poly_trait_ref
1073                                        .to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
1074                                    span,
1075                                ));
1076                            }
1077                        }
1078                        hir::BoundConstness::Always(_) | hir::BoundConstness::Never => {}
1079                    }
1080                }
1081            }
1082        }
1083
1084        let mut dup_constraints = (overlapping_assoc_item_constraints
1085            == OverlappingAsssocItemConstraints::Forbidden)
1086            .then_some(FxIndexMap::default());
1087
1088        for constraint in constraints {
1089            // Don't register any associated item constraints for negative bounds,
1090            // since we should have emitted an error for them earlier, and they
1091            // would not be well-formed!
1092            if polarity == ty::PredicatePolarity::Negative {
1093                self.dcx().span_delayed_bug(
1094                    constraint.span,
1095                    "negative trait bounds should not have assoc item constraints",
1096                );
1097                break;
1098            }
1099
1100            // Specify type to assert that error was already reported in `Err` case.
1101            let _: Result<_, ErrorGuaranteed> = self.lower_assoc_item_constraint(
1102                trait_ref.hir_ref_id,
1103                poly_trait_ref,
1104                constraint,
1105                bounds,
1106                dup_constraints.as_mut(),
1107                constraint.span,
1108                predicate_filter,
1109            );
1110            // Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
1111        }
1112
1113        arg_count
1114    }
1115
1116    /// Lower a monomorphic trait reference given a self type while prohibiting associated item bindings.
1117    ///
1118    /// *Monomorphic* in the sense that it doesn't bind any late-bound vars.
1119    fn lower_mono_trait_ref(
1120        &self,
1121        span: Span,
1122        trait_def_id: DefId,
1123        self_ty: Ty<'tcx>,
1124        trait_segment: &hir::PathSegment<'tcx>,
1125        is_impl: bool,
1126    ) -> ty::TraitRef<'tcx> {
1127        self.report_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
1128
1129        let (generic_args, _) =
1130            self.lower_generic_args_of_path(span, trait_def_id, &[], trait_segment, Some(self_ty));
1131        if let Some(c) = trait_segment.args().constraints.first() {
1132            prohibit_assoc_item_constraint(self, c, Some((trait_def_id, trait_segment, span)));
1133        }
1134        ty::TraitRef::new_from_args(self.tcx(), trait_def_id, generic_args)
1135    }
1136
1137    fn probe_trait_that_defines_assoc_item(
1138        &self,
1139        trait_def_id: DefId,
1140        assoc_tag: ty::AssocTag,
1141        assoc_ident: Ident,
1142    ) -> bool {
1143        self.tcx()
1144            .associated_items(trait_def_id)
1145            .find_by_ident_and_kind(self.tcx(), assoc_ident, assoc_tag, trait_def_id)
1146            .is_some()
1147    }
1148
1149    fn lower_path_segment(
1150        &self,
1151        span: Span,
1152        did: DefId,
1153        item_segment: &hir::PathSegment<'tcx>,
1154    ) -> Ty<'tcx> {
1155        let tcx = self.tcx();
1156        let args = self.lower_generic_args_of_path_segment(span, did, item_segment);
1157
1158        if let DefKind::TyAlias = tcx.def_kind(did)
1159            && tcx.type_alias_is_lazy(did)
1160        {
1161            // Type aliases defined in crates that have the
1162            // feature `lazy_type_alias` enabled get encoded as a type alias that normalization will
1163            // then actually instantiate the where bounds of.
1164            let alias_ty = ty::AliasTy::new_from_args(tcx, did, args);
1165            Ty::new_alias(tcx, ty::Free, alias_ty)
1166        } else {
1167            tcx.at(span).type_of(did).instantiate(tcx, args)
1168        }
1169    }
1170
1171    /// Search for a trait bound on a type parameter whose trait defines the associated item
1172    /// given by `assoc_ident` and `kind`.
1173    ///
1174    /// This fails if there is no such bound in the list of candidates or if there are multiple
1175    /// candidates in which case it reports ambiguity.
1176    ///
1177    /// `ty_param_def_id` is the `LocalDefId` of the type parameter.
1178    #[instrument(level = "debug", skip_all, ret)]
1179    fn probe_single_ty_param_bound_for_assoc_item(
1180        &self,
1181        ty_param_def_id: LocalDefId,
1182        ty_param_span: Span,
1183        assoc_tag: ty::AssocTag,
1184        assoc_ident: Ident,
1185        span: Span,
1186    ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
1187        debug!(?ty_param_def_id, ?assoc_ident, ?span);
1188        let tcx = self.tcx();
1189
1190        let predicates = &self.probe_ty_param_bounds(span, ty_param_def_id, assoc_ident);
1191        debug!("predicates={:#?}", predicates);
1192
1193        self.probe_single_bound_for_assoc_item(
1194            || {
1195                let trait_refs = predicates
1196                    .iter_identity_copied()
1197                    .filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref)));
1198                traits::transitive_bounds_that_define_assoc_item(tcx, trait_refs, assoc_ident)
1199            },
1200            AssocItemQSelf::TyParam(ty_param_def_id, ty_param_span),
1201            assoc_tag,
1202            assoc_ident,
1203            span,
1204            None,
1205        )
1206    }
1207
1208    /// Search for a single trait bound whose trait defines the associated item given by
1209    /// `assoc_ident`.
1210    ///
1211    /// This fails if there is no such bound in the list of candidates or if there are multiple
1212    /// candidates in which case it reports ambiguity.
1213    #[instrument(level = "debug", skip(self, all_candidates, qself, constraint), ret)]
1214    fn probe_single_bound_for_assoc_item<I>(
1215        &self,
1216        all_candidates: impl Fn() -> I,
1217        qself: AssocItemQSelf,
1218        assoc_tag: ty::AssocTag,
1219        assoc_ident: Ident,
1220        span: Span,
1221        constraint: Option<&hir::AssocItemConstraint<'tcx>>,
1222    ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
1223    where
1224        I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
1225    {
1226        let tcx = self.tcx();
1227
1228        let mut matching_candidates = all_candidates().filter(|r| {
1229            self.probe_trait_that_defines_assoc_item(r.def_id(), assoc_tag, assoc_ident)
1230        });
1231
1232        let Some(bound) = matching_candidates.next() else {
1233            return Err(self.report_unresolved_assoc_item(
1234                all_candidates,
1235                qself,
1236                assoc_tag,
1237                assoc_ident,
1238                span,
1239                constraint,
1240            ));
1241        };
1242        debug!(?bound);
1243
1244        if let Some(bound2) = matching_candidates.next() {
1245            debug!(?bound2);
1246
1247            let assoc_kind_str = errors::assoc_tag_str(assoc_tag);
1248            let qself_str = qself.to_string(tcx);
1249            let mut err = self.dcx().create_err(crate::errors::AmbiguousAssocItem {
1250                span,
1251                assoc_kind: assoc_kind_str,
1252                assoc_ident,
1253                qself: &qself_str,
1254            });
1255            // Provide a more specific error code index entry for equality bindings.
1256            err.code(
1257                if let Some(constraint) = constraint
1258                    && let hir::AssocItemConstraintKind::Equality { .. } = constraint.kind
1259                {
1260                    E0222
1261                } else {
1262                    E0221
1263                },
1264            );
1265
1266            // FIXME(#97583): Print associated item bindings properly (i.e., not as equality
1267            // predicates!).
1268            // FIXME: Turn this into a structured, translatable & more actionable suggestion.
1269            let mut where_bounds = vec![];
1270            for bound in [bound, bound2].into_iter().chain(matching_candidates) {
1271                let bound_id = bound.def_id();
1272                let bound_span = tcx
1273                    .associated_items(bound_id)
1274                    .find_by_ident_and_kind(tcx, assoc_ident, assoc_tag, bound_id)
1275                    .and_then(|item| tcx.hir_span_if_local(item.def_id));
1276
1277                if let Some(bound_span) = bound_span {
1278                    err.span_label(
1279                        bound_span,
1280                        format!("ambiguous `{assoc_ident}` from `{}`", bound.print_trait_sugared(),),
1281                    );
1282                    if let Some(constraint) = constraint {
1283                        match constraint.kind {
1284                            hir::AssocItemConstraintKind::Equality { term } => {
1285                                let term: ty::Term<'_> = match term {
1286                                    hir::Term::Ty(ty) => self.lower_ty(ty).into(),
1287                                    hir::Term::Const(ct) => {
1288                                        self.lower_const_arg(ct, FeedConstTy::No).into()
1289                                    }
1290                                };
1291                                if term.references_error() {
1292                                    continue;
1293                                }
1294                                // FIXME(#97583): This isn't syntactically well-formed!
1295                                where_bounds.push(format!(
1296                                    "        T: {trait}::{assoc_ident} = {term}",
1297                                    trait = bound.print_only_trait_path(),
1298                                ));
1299                            }
1300                            // FIXME: Provide a suggestion.
1301                            hir::AssocItemConstraintKind::Bound { bounds: _ } => {}
1302                        }
1303                    } else {
1304                        err.span_suggestion_verbose(
1305                            span.with_hi(assoc_ident.span.lo()),
1306                            "use fully-qualified syntax to disambiguate",
1307                            format!("<{qself_str} as {}>::", bound.print_only_trait_path()),
1308                            Applicability::MaybeIncorrect,
1309                        );
1310                    }
1311                } else {
1312                    let trait_ =
1313                        tcx.short_string(bound.print_only_trait_path(), err.long_ty_path());
1314                    err.note(format!(
1315                        "associated {assoc_kind_str} `{assoc_ident}` could derive from `{trait_}`",
1316                    ));
1317                }
1318            }
1319            if !where_bounds.is_empty() {
1320                err.help(format!(
1321                    "consider introducing a new type parameter `T` and adding `where` constraints:\
1322                     \n    where\n        T: {qself_str},\n{}",
1323                    where_bounds.join(",\n"),
1324                ));
1325                let reported = err.emit();
1326                return Err(reported);
1327            }
1328            err.emit();
1329        }
1330
1331        Ok(bound)
1332    }
1333
1334    /// Lower a [type-relative](hir::QPath::TypeRelative) path in type position to a type.
1335    ///
1336    /// If the path refers to an enum variant and `permit_variants` holds,
1337    /// the returned type is simply the provided self type `qself_ty`.
1338    ///
1339    /// A path like `A::B::C::D` is understood as `<A::B::C>::D`. I.e.,
1340    /// `qself_ty` / `qself` is `A::B::C` and `assoc_segment` is `D`.
1341    /// We return the lowered type and the `DefId` for the whole path.
1342    ///
1343    /// We only support associated type paths whose self type is a type parameter or a `Self`
1344    /// type alias (in a trait impl) like `T::Ty` (where `T` is a ty param) or `Self::Ty`.
1345    /// We **don't** support paths whose self type is an arbitrary type like `Struct::Ty` where
1346    /// struct `Struct` impls an in-scope trait that defines an associated type called `Ty`.
1347    /// For the latter case, we report ambiguity.
1348    /// While desirable to support, the implementation would be non-trivial. Tracked in [#22519].
1349    ///
1350    /// At the time of writing, *inherent associated types* are also resolved here. This however
1351    /// is [problematic][iat]. A proper implementation would be as non-trivial as the one
1352    /// described in the previous paragraph and their modeling of projections would likely be
1353    /// very similar in nature.
1354    ///
1355    /// [#22519]: https://github.com/rust-lang/rust/issues/22519
1356    /// [iat]: https://github.com/rust-lang/rust/issues/8995#issuecomment-1569208403
1357    //
1358    // NOTE: When this function starts resolving `Trait::AssocTy` successfully
1359    // it should also start reporting the `BARE_TRAIT_OBJECTS` lint.
1360    #[instrument(level = "debug", skip_all, ret)]
1361    pub fn lower_type_relative_ty_path(
1362        &self,
1363        self_ty: Ty<'tcx>,
1364        hir_self_ty: &'tcx hir::Ty<'tcx>,
1365        segment: &'tcx hir::PathSegment<'tcx>,
1366        qpath_hir_id: HirId,
1367        span: Span,
1368        permit_variants: PermitVariants,
1369    ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> {
1370        let tcx = self.tcx();
1371        match self.lower_type_relative_path(
1372            self_ty,
1373            hir_self_ty,
1374            segment,
1375            qpath_hir_id,
1376            span,
1377            LowerTypeRelativePathMode::Type(permit_variants),
1378        )? {
1379            TypeRelativePath::AssocItem(def_id, args) => {
1380                let alias_ty = ty::AliasTy::new_from_args(tcx, def_id, args);
1381                let ty = Ty::new_alias(tcx, alias_ty.kind(tcx), alias_ty);
1382                let ty = self.check_param_uses_if_mcg(ty, span, false);
1383                Ok((ty, tcx.def_kind(def_id), def_id))
1384            }
1385            TypeRelativePath::Variant { adt, variant_did } => {
1386                let adt = self.check_param_uses_if_mcg(adt, span, false);
1387                Ok((adt, DefKind::Variant, variant_did))
1388            }
1389            TypeRelativePath::Ctor { .. } => {
1390                let e = tcx.dcx().span_err(span, "expected type, found tuple constructor");
1391                Err(e)
1392            }
1393        }
1394    }
1395
1396    /// Lower a [type-relative][hir::QPath::TypeRelative] path to a (type-level) constant.
1397    #[instrument(level = "debug", skip_all, ret)]
1398    fn lower_type_relative_const_path(
1399        &self,
1400        self_ty: Ty<'tcx>,
1401        hir_self_ty: &'tcx hir::Ty<'tcx>,
1402        segment: &'tcx hir::PathSegment<'tcx>,
1403        qpath_hir_id: HirId,
1404        span: Span,
1405    ) -> Result<Const<'tcx>, ErrorGuaranteed> {
1406        let tcx = self.tcx();
1407        match self.lower_type_relative_path(
1408            self_ty,
1409            hir_self_ty,
1410            segment,
1411            qpath_hir_id,
1412            span,
1413            LowerTypeRelativePathMode::Const,
1414        )? {
1415            TypeRelativePath::AssocItem(def_id, args) => {
1416                if !find_attr!(self.tcx().get_all_attrs(def_id), AttributeKind::TypeConst(_)) {
1417                    let mut err = self.dcx().struct_span_err(
1418                        span,
1419                        "use of trait associated const without `#[type_const]`",
1420                    );
1421                    err.note("the declaration in the trait must be marked with `#[type_const]`");
1422                    return Err(err.emit());
1423                }
1424                let ct = Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(def_id, args));
1425                let ct = self.check_param_uses_if_mcg(ct, span, false);
1426                Ok(ct)
1427            }
1428            TypeRelativePath::Ctor { ctor_def_id, args } => match tcx.def_kind(ctor_def_id) {
1429                DefKind::Ctor(_, CtorKind::Fn) => {
1430                    Ok(ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, ctor_def_id, args)))
1431                }
1432                DefKind::Ctor(ctor_of, CtorKind::Const) => {
1433                    Ok(self.construct_const_ctor_value(ctor_def_id, ctor_of, args))
1434                }
1435                _ => unreachable!(),
1436            },
1437            // FIXME(mgca): implement support for this once ready to support all adt ctor expressions,
1438            // not just const ctors
1439            TypeRelativePath::Variant { .. } => {
1440                span_bug!(span, "unexpected variant res for type associated const path")
1441            }
1442        }
1443    }
1444
1445    /// Lower a [type-relative][hir::QPath::TypeRelative] (and type-level) path.
1446    #[instrument(level = "debug", skip_all, ret)]
1447    fn lower_type_relative_path(
1448        &self,
1449        self_ty: Ty<'tcx>,
1450        hir_self_ty: &'tcx hir::Ty<'tcx>,
1451        segment: &'tcx hir::PathSegment<'tcx>,
1452        qpath_hir_id: HirId,
1453        span: Span,
1454        mode: LowerTypeRelativePathMode,
1455    ) -> Result<TypeRelativePath<'tcx>, ErrorGuaranteed> {
1456        debug!(%self_ty, ?segment.ident);
1457        let tcx = self.tcx();
1458
1459        // Check if we have an enum variant or an inherent associated type.
1460        let mut variant_def_id = None;
1461        if let Some(adt_def) = self.probe_adt(span, self_ty) {
1462            if adt_def.is_enum() {
1463                let variant_def = adt_def
1464                    .variants()
1465                    .iter()
1466                    .find(|vd| tcx.hygienic_eq(segment.ident, vd.ident(tcx), adt_def.did()));
1467                if let Some(variant_def) = variant_def {
1468                    // FIXME(mgca): do we want constructor resolutions to take priority over
1469                    // other possible resolutions?
1470                    if matches!(mode, LowerTypeRelativePathMode::Const)
1471                        && let Some((_, ctor_def_id)) = variant_def.ctor
1472                    {
1473                        tcx.check_stability(variant_def.def_id, Some(qpath_hir_id), span, None);
1474                        let _ = self.prohibit_generic_args(
1475                            slice::from_ref(segment).iter(),
1476                            GenericsArgsErrExtend::EnumVariant {
1477                                qself: hir_self_ty,
1478                                assoc_segment: segment,
1479                                adt_def,
1480                            },
1481                        );
1482                        let ty::Adt(_, enum_args) = self_ty.kind() else { unreachable!() };
1483                        return Ok(TypeRelativePath::Ctor { ctor_def_id, args: enum_args });
1484                    }
1485                    if let PermitVariants::Yes = mode.permit_variants() {
1486                        tcx.check_stability(variant_def.def_id, Some(qpath_hir_id), span, None);
1487                        let _ = self.prohibit_generic_args(
1488                            slice::from_ref(segment).iter(),
1489                            GenericsArgsErrExtend::EnumVariant {
1490                                qself: hir_self_ty,
1491                                assoc_segment: segment,
1492                                adt_def,
1493                            },
1494                        );
1495                        return Ok(TypeRelativePath::Variant {
1496                            adt: self_ty,
1497                            variant_did: variant_def.def_id,
1498                        });
1499                    } else {
1500                        variant_def_id = Some(variant_def.def_id);
1501                    }
1502                }
1503            }
1504
1505            // FIXME(inherent_associated_types, #106719): Support self types other than ADTs.
1506            if let Some((did, args)) = self.probe_inherent_assoc_item(
1507                segment,
1508                adt_def.did(),
1509                self_ty,
1510                qpath_hir_id,
1511                span,
1512                mode.assoc_tag(),
1513            )? {
1514                return Ok(TypeRelativePath::AssocItem(did, args));
1515            }
1516        }
1517
1518        let (item_def_id, bound) = self.resolve_type_relative_path(
1519            self_ty,
1520            hir_self_ty,
1521            mode.assoc_tag(),
1522            segment,
1523            qpath_hir_id,
1524            span,
1525            variant_def_id,
1526        )?;
1527
1528        let (item_def_id, args) = self.lower_assoc_item_path(span, item_def_id, segment, bound)?;
1529
1530        if let Some(variant_def_id) = variant_def_id {
1531            tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, qpath_hir_id, span, |lint| {
1532                lint.primary_message("ambiguous associated item");
1533                let mut could_refer_to = |kind: DefKind, def_id, also| {
1534                    let note_msg = format!(
1535                        "`{}` could{} refer to the {} defined here",
1536                        segment.ident,
1537                        also,
1538                        tcx.def_kind_descr(kind, def_id)
1539                    );
1540                    lint.span_note(tcx.def_span(def_id), note_msg);
1541                };
1542
1543                could_refer_to(DefKind::Variant, variant_def_id, "");
1544                could_refer_to(mode.def_kind(), item_def_id, " also");
1545
1546                lint.span_suggestion(
1547                    span,
1548                    "use fully-qualified syntax",
1549                    format!(
1550                        "<{} as {}>::{}",
1551                        self_ty,
1552                        tcx.item_name(bound.def_id()),
1553                        segment.ident
1554                    ),
1555                    Applicability::MachineApplicable,
1556                );
1557            });
1558        }
1559
1560        Ok(TypeRelativePath::AssocItem(item_def_id, args))
1561    }
1562
1563    /// Resolve a [type-relative](hir::QPath::TypeRelative) (and type-level) path.
1564    fn resolve_type_relative_path(
1565        &self,
1566        self_ty: Ty<'tcx>,
1567        hir_self_ty: &'tcx hir::Ty<'tcx>,
1568        assoc_tag: ty::AssocTag,
1569        segment: &'tcx hir::PathSegment<'tcx>,
1570        qpath_hir_id: HirId,
1571        span: Span,
1572        variant_def_id: Option<DefId>,
1573    ) -> Result<(DefId, ty::PolyTraitRef<'tcx>), ErrorGuaranteed> {
1574        let tcx = self.tcx();
1575
1576        let self_ty_res = match hir_self_ty.kind {
1577            hir::TyKind::Path(hir::QPath::Resolved(_, path)) => path.res,
1578            _ => Res::Err,
1579        };
1580
1581        // Find the type of the assoc item, and the trait where the associated item is declared.
1582        let bound = match (self_ty.kind(), self_ty_res) {
1583            (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
1584                // `Self` in an impl of a trait -- we have a concrete self type and a
1585                // trait reference.
1586                let trait_ref = tcx.impl_trait_ref(impl_def_id);
1587
1588                self.probe_single_bound_for_assoc_item(
1589                    || {
1590                        let trait_ref = ty::Binder::dummy(trait_ref.instantiate_identity());
1591                        traits::supertraits(tcx, trait_ref)
1592                    },
1593                    AssocItemQSelf::SelfTyAlias,
1594                    assoc_tag,
1595                    segment.ident,
1596                    span,
1597                    None,
1598                )?
1599            }
1600            (
1601                &ty::Param(_),
1602                Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
1603            ) => self.probe_single_ty_param_bound_for_assoc_item(
1604                param_did.expect_local(),
1605                hir_self_ty.span,
1606                assoc_tag,
1607                segment.ident,
1608                span,
1609            )?,
1610            _ => {
1611                return Err(self.report_unresolved_type_relative_path(
1612                    self_ty,
1613                    hir_self_ty,
1614                    assoc_tag,
1615                    segment.ident,
1616                    qpath_hir_id,
1617                    span,
1618                    variant_def_id,
1619                ));
1620            }
1621        };
1622
1623        let assoc_item = self
1624            .probe_assoc_item(segment.ident, assoc_tag, qpath_hir_id, span, bound.def_id())
1625            .expect("failed to find associated item");
1626
1627        Ok((assoc_item.def_id, bound))
1628    }
1629
1630    /// Search for inherent associated items for use at the type level.
1631    fn probe_inherent_assoc_item(
1632        &self,
1633        segment: &hir::PathSegment<'tcx>,
1634        adt_did: DefId,
1635        self_ty: Ty<'tcx>,
1636        block: HirId,
1637        span: Span,
1638        assoc_tag: ty::AssocTag,
1639    ) -> Result<Option<(DefId, GenericArgsRef<'tcx>)>, ErrorGuaranteed> {
1640        let tcx = self.tcx();
1641
1642        if !tcx.features().inherent_associated_types() {
1643            match assoc_tag {
1644                // Don't attempt to look up inherent associated types when the feature is not
1645                // enabled. Theoretically it'd be fine to do so since we feature-gate their
1646                // definition site. However, the current implementation of inherent associated
1647                // items is somewhat brittle, so let's not run it by default.
1648                ty::AssocTag::Type => return Ok(None),
1649                ty::AssocTag::Const => {
1650                    // We also gate the mgca codepath for type-level uses of inherent consts
1651                    // with the inherent_associated_types feature gate since it relies on the
1652                    // same machinery and has similar rough edges.
1653                    return Err(feature_err(
1654                        &tcx.sess,
1655                        sym::inherent_associated_types,
1656                        span,
1657                        "inherent associated types are unstable",
1658                    )
1659                    .emit());
1660                }
1661                ty::AssocTag::Fn => unreachable!(),
1662            }
1663        }
1664
1665        let name = segment.ident;
1666        let candidates: Vec<_> = tcx
1667            .inherent_impls(adt_did)
1668            .iter()
1669            .filter_map(|&impl_| {
1670                let (item, scope) =
1671                    self.probe_assoc_item_unchecked(name, assoc_tag, block, impl_)?;
1672                Some(InherentAssocCandidate { impl_, assoc_item: item.def_id, scope })
1673            })
1674            .collect();
1675
1676        // At the moment, we actually bail out with a hard error if the selection of an inherent
1677        // associated item fails (see below). This means we never consider trait associated items
1678        // as potential fallback candidates (#142006). To temporarily mask that issue, let's not
1679        // select at all if there are no early inherent candidates.
1680        if candidates.is_empty() {
1681            return Ok(None);
1682        }
1683
1684        let (applicable_candidates, fulfillment_errors) =
1685            self.select_inherent_assoc_candidates(span, self_ty, candidates.clone());
1686
1687        // FIXME(#142006): Don't eagerly error here, there might be applicable trait candidates.
1688        let InherentAssocCandidate { impl_, assoc_item, scope: def_scope } =
1689            match &applicable_candidates[..] {
1690                &[] => Err(self.report_unresolved_inherent_assoc_item(
1691                    name,
1692                    self_ty,
1693                    candidates,
1694                    fulfillment_errors,
1695                    span,
1696                    assoc_tag,
1697                )),
1698
1699                &[applicable_candidate] => Ok(applicable_candidate),
1700
1701                &[_, ..] => Err(self.report_ambiguous_inherent_assoc_item(
1702                    name,
1703                    candidates.into_iter().map(|cand| cand.assoc_item).collect(),
1704                    span,
1705                )),
1706            }?;
1707
1708        // FIXME(#142006): Don't eagerly validate here, there might be trait candidates that are
1709        // accessible (visible and stable) contrary to the inherent candidate.
1710        self.check_assoc_item(assoc_item, name, def_scope, block, span);
1711
1712        // FIXME(fmease): Currently creating throwaway `parent_args` to please
1713        // `lower_generic_args_of_assoc_item`. Modify the latter instead (or sth. similar) to
1714        // not require the parent args logic.
1715        let parent_args = ty::GenericArgs::identity_for_item(tcx, impl_);
1716        let args = self.lower_generic_args_of_assoc_item(span, assoc_item, segment, parent_args);
1717        let args = tcx.mk_args_from_iter(
1718            std::iter::once(ty::GenericArg::from(self_ty))
1719                .chain(args.into_iter().skip(parent_args.len())),
1720        );
1721
1722        Ok(Some((assoc_item, args)))
1723    }
1724
1725    /// Given name and kind search for the assoc item in the provided scope and check if it's accessible[^1].
1726    ///
1727    /// [^1]: I.e., accessible in the provided scope wrt. visibility and stability.
1728    fn probe_assoc_item(
1729        &self,
1730        ident: Ident,
1731        assoc_tag: ty::AssocTag,
1732        block: HirId,
1733        span: Span,
1734        scope: DefId,
1735    ) -> Option<ty::AssocItem> {
1736        let (item, scope) = self.probe_assoc_item_unchecked(ident, assoc_tag, block, scope)?;
1737        self.check_assoc_item(item.def_id, ident, scope, block, span);
1738        Some(item)
1739    }
1740
1741    /// Given name and kind search for the assoc item in the provided scope
1742    /// *without* checking if it's accessible[^1].
1743    ///
1744    /// [^1]: I.e., accessible in the provided scope wrt. visibility and stability.
1745    fn probe_assoc_item_unchecked(
1746        &self,
1747        ident: Ident,
1748        assoc_tag: ty::AssocTag,
1749        block: HirId,
1750        scope: DefId,
1751    ) -> Option<(ty::AssocItem, /*scope*/ DefId)> {
1752        let tcx = self.tcx();
1753
1754        let (ident, def_scope) = tcx.adjust_ident_and_get_scope(ident, scope, block);
1755        // We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()`
1756        // instead of calling `filter_by_name_and_kind` which would needlessly normalize the
1757        // `ident` again and again.
1758        let item = tcx
1759            .associated_items(scope)
1760            .filter_by_name_unhygienic(ident.name)
1761            .find(|i| i.as_tag() == assoc_tag && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
1762
1763        Some((*item, def_scope))
1764    }
1765
1766    /// Check if the given assoc item is accessible in the provided scope wrt. visibility and stability.
1767    fn check_assoc_item(
1768        &self,
1769        item_def_id: DefId,
1770        ident: Ident,
1771        scope: DefId,
1772        block: HirId,
1773        span: Span,
1774    ) {
1775        let tcx = self.tcx();
1776
1777        if !tcx.visibility(item_def_id).is_accessible_from(scope, tcx) {
1778            self.dcx().emit_err(crate::errors::AssocItemIsPrivate {
1779                span,
1780                kind: tcx.def_descr(item_def_id),
1781                name: ident,
1782                defined_here_label: tcx.def_span(item_def_id),
1783            });
1784        }
1785
1786        tcx.check_stability(item_def_id, Some(block), span, None);
1787    }
1788
1789    fn probe_traits_that_match_assoc_ty(
1790        &self,
1791        qself_ty: Ty<'tcx>,
1792        assoc_ident: Ident,
1793    ) -> Vec<String> {
1794        let tcx = self.tcx();
1795
1796        // In contexts that have no inference context, just make a new one.
1797        // We do need a local variable to store it, though.
1798        let infcx_;
1799        let infcx = if let Some(infcx) = self.infcx() {
1800            infcx
1801        } else {
1802            assert!(!qself_ty.has_infer());
1803            infcx_ = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
1804            &infcx_
1805        };
1806
1807        tcx.all_traits_including_private()
1808            .filter(|trait_def_id| {
1809                // Consider only traits with the associated type
1810                tcx.associated_items(*trait_def_id)
1811                        .in_definition_order()
1812                        .any(|i| {
1813                            i.is_type()
1814                                && !i.is_impl_trait_in_trait()
1815                                && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
1816                        })
1817                    // Consider only accessible traits
1818                    && tcx.visibility(*trait_def_id)
1819                        .is_accessible_from(self.item_def_id(), tcx)
1820                    && tcx.all_impls(*trait_def_id)
1821                        .any(|impl_def_id| {
1822                            let header = tcx.impl_trait_header(impl_def_id);
1823                            let trait_ref = header.trait_ref.instantiate(
1824                                tcx,
1825                                infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
1826                            );
1827
1828                            let value = fold_regions(tcx, qself_ty, |_, _| tcx.lifetimes.re_erased);
1829                            // FIXME: Don't bother dealing with non-lifetime binders here...
1830                            if value.has_escaping_bound_vars() {
1831                                return false;
1832                            }
1833                            infcx
1834                                .can_eq(
1835                                    ty::ParamEnv::empty(),
1836                                    trait_ref.self_ty(),
1837                                    value,
1838                                ) && header.polarity != ty::ImplPolarity::Negative
1839                        })
1840            })
1841            .map(|trait_def_id| tcx.def_path_str(trait_def_id))
1842            .collect()
1843    }
1844
1845    /// Lower a [resolved][hir::QPath::Resolved] associated type path to a projection.
1846    #[instrument(level = "debug", skip_all)]
1847    fn lower_resolved_assoc_ty_path(
1848        &self,
1849        span: Span,
1850        opt_self_ty: Option<Ty<'tcx>>,
1851        item_def_id: DefId,
1852        trait_segment: Option<&hir::PathSegment<'tcx>>,
1853        item_segment: &hir::PathSegment<'tcx>,
1854    ) -> Ty<'tcx> {
1855        match self.lower_resolved_assoc_item_path(
1856            span,
1857            opt_self_ty,
1858            item_def_id,
1859            trait_segment,
1860            item_segment,
1861            ty::AssocTag::Type,
1862        ) {
1863            Ok((item_def_id, item_args)) => {
1864                Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
1865            }
1866            Err(guar) => Ty::new_error(self.tcx(), guar),
1867        }
1868    }
1869
1870    /// Lower a [resolved][hir::QPath::Resolved] associated const path to a (type-level) constant.
1871    #[instrument(level = "debug", skip_all)]
1872    fn lower_resolved_assoc_const_path(
1873        &self,
1874        span: Span,
1875        opt_self_ty: Option<Ty<'tcx>>,
1876        item_def_id: DefId,
1877        trait_segment: Option<&hir::PathSegment<'tcx>>,
1878        item_segment: &hir::PathSegment<'tcx>,
1879    ) -> Const<'tcx> {
1880        match self.lower_resolved_assoc_item_path(
1881            span,
1882            opt_self_ty,
1883            item_def_id,
1884            trait_segment,
1885            item_segment,
1886            ty::AssocTag::Const,
1887        ) {
1888            Ok((item_def_id, item_args)) => {
1889                if !find_attr!(self.tcx().get_all_attrs(item_def_id), AttributeKind::TypeConst(_)) {
1890                    let mut err = self.dcx().struct_span_err(
1891                        span,
1892                        "use of `const` in the type system without `#[type_const]`",
1893                    );
1894                    err.note("the declaration must be marked with `#[type_const]`");
1895                    return Const::new_error(self.tcx(), err.emit());
1896                }
1897
1898                let uv = ty::UnevaluatedConst::new(item_def_id, item_args);
1899                Const::new_unevaluated(self.tcx(), uv)
1900            }
1901            Err(guar) => Const::new_error(self.tcx(), guar),
1902        }
1903    }
1904
1905    /// Lower a [resolved][hir::QPath::Resolved] (type-level) associated item path.
1906    #[instrument(level = "debug", skip_all)]
1907    fn lower_resolved_assoc_item_path(
1908        &self,
1909        span: Span,
1910        opt_self_ty: Option<Ty<'tcx>>,
1911        item_def_id: DefId,
1912        trait_segment: Option<&hir::PathSegment<'tcx>>,
1913        item_segment: &hir::PathSegment<'tcx>,
1914        assoc_tag: ty::AssocTag,
1915    ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed> {
1916        let tcx = self.tcx();
1917
1918        let trait_def_id = tcx.parent(item_def_id);
1919        debug!(?trait_def_id);
1920
1921        let Some(self_ty) = opt_self_ty else {
1922            return Err(self.report_missing_self_ty_for_resolved_path(
1923                trait_def_id,
1924                span,
1925                item_segment,
1926                assoc_tag,
1927            ));
1928        };
1929        debug!(?self_ty);
1930
1931        let trait_ref =
1932            self.lower_mono_trait_ref(span, trait_def_id, self_ty, trait_segment.unwrap(), false);
1933        debug!(?trait_ref);
1934
1935        let item_args =
1936            self.lower_generic_args_of_assoc_item(span, item_def_id, item_segment, trait_ref.args);
1937
1938        Ok((item_def_id, item_args))
1939    }
1940
1941    pub fn prohibit_generic_args<'a>(
1942        &self,
1943        segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
1944        err_extend: GenericsArgsErrExtend<'a>,
1945    ) -> Result<(), ErrorGuaranteed> {
1946        let args_visitors = segments.clone().flat_map(|segment| segment.args().args);
1947        let mut result = Ok(());
1948        if let Some(_) = args_visitors.clone().next() {
1949            result = Err(self.report_prohibited_generic_args(
1950                segments.clone(),
1951                args_visitors,
1952                err_extend,
1953            ));
1954        }
1955
1956        for segment in segments {
1957            // Only emit the first error to avoid overloading the user with error messages.
1958            if let Some(c) = segment.args().constraints.first() {
1959                return Err(prohibit_assoc_item_constraint(self, c, None));
1960            }
1961        }
1962
1963        result
1964    }
1965
1966    /// Probe path segments that are semantically allowed to have generic arguments.
1967    ///
1968    /// ### Example
1969    ///
1970    /// ```ignore (illustrative)
1971    ///    Option::None::<()>
1972    /// //         ^^^^ permitted to have generic args
1973    ///
1974    /// // ==> [GenericPathSegment(Option_def_id, 1)]
1975    ///
1976    ///    Option::<()>::None
1977    /// // ^^^^^^        ^^^^ *not* permitted to have generic args
1978    /// // permitted to have generic args
1979    ///
1980    /// // ==> [GenericPathSegment(Option_def_id, 0)]
1981    /// ```
1982    // FIXME(eddyb, varkor) handle type paths here too, not just value ones.
1983    pub fn probe_generic_path_segments(
1984        &self,
1985        segments: &[hir::PathSegment<'_>],
1986        self_ty: Option<Ty<'tcx>>,
1987        kind: DefKind,
1988        def_id: DefId,
1989        span: Span,
1990    ) -> Vec<GenericPathSegment> {
1991        // We need to extract the generic arguments supplied by the user in
1992        // the path `path`. Due to the current setup, this is a bit of a
1993        // tricky process; the problem is that resolve only tells us the
1994        // end-point of the path resolution, and not the intermediate steps.
1995        // Luckily, we can (at least for now) deduce the intermediate steps
1996        // just from the end-point.
1997        //
1998        // There are basically five cases to consider:
1999        //
2000        // 1. Reference to a constructor of a struct:
2001        //
2002        //        struct Foo<T>(...)
2003        //
2004        //    In this case, the generic arguments are declared in the type space.
2005        //
2006        // 2. Reference to a constructor of an enum variant:
2007        //
2008        //        enum E<T> { Foo(...) }
2009        //
2010        //    In this case, the generic arguments are defined in the type space,
2011        //    but may be specified either on the type or the variant.
2012        //
2013        // 3. Reference to a free function or constant:
2014        //
2015        //        fn foo<T>() {}
2016        //
2017        //    In this case, the path will again always have the form
2018        //    `a::b::foo::<T>` where only the final segment should have generic
2019        //    arguments. However, in this case, those arguments are declared on
2020        //    a value, and hence are in the value space.
2021        //
2022        // 4. Reference to an associated function or constant:
2023        //
2024        //        impl<A> SomeStruct<A> {
2025        //            fn foo<B>(...) {}
2026        //        }
2027        //
2028        //    Here we can have a path like `a::b::SomeStruct::<A>::foo::<B>`,
2029        //    in which case generic arguments may appear in two places. The
2030        //    penultimate segment, `SomeStruct::<A>`, contains generic arguments
2031        //    in the type space, and the final segment, `foo::<B>` contains
2032        //    generic arguments in value space.
2033        //
2034        // The first step then is to categorize the segments appropriately.
2035
2036        let tcx = self.tcx();
2037
2038        assert!(!segments.is_empty());
2039        let last = segments.len() - 1;
2040
2041        let mut generic_segments = vec![];
2042
2043        match kind {
2044            // Case 1. Reference to a struct constructor.
2045            DefKind::Ctor(CtorOf::Struct, ..) => {
2046                // Everything but the final segment should have no
2047                // parameters at all.
2048                let generics = tcx.generics_of(def_id);
2049                // Variant and struct constructors use the
2050                // generics of their parent type definition.
2051                let generics_def_id = generics.parent.unwrap_or(def_id);
2052                generic_segments.push(GenericPathSegment(generics_def_id, last));
2053            }
2054
2055            // Case 2. Reference to a variant constructor.
2056            DefKind::Ctor(CtorOf::Variant, ..) | DefKind::Variant => {
2057                let (generics_def_id, index) = if let Some(self_ty) = self_ty {
2058                    let adt_def = self.probe_adt(span, self_ty).unwrap();
2059                    debug_assert!(adt_def.is_enum());
2060                    (adt_def.did(), last)
2061                } else if last >= 1 && segments[last - 1].args.is_some() {
2062                    // Everything but the penultimate segment should have no
2063                    // parameters at all.
2064                    let mut def_id = def_id;
2065
2066                    // `DefKind::Ctor` -> `DefKind::Variant`
2067                    if let DefKind::Ctor(..) = kind {
2068                        def_id = tcx.parent(def_id);
2069                    }
2070
2071                    // `DefKind::Variant` -> `DefKind::Enum`
2072                    let enum_def_id = tcx.parent(def_id);
2073                    (enum_def_id, last - 1)
2074                } else {
2075                    // FIXME: lint here recommending `Enum::<...>::Variant` form
2076                    // instead of `Enum::Variant::<...>` form.
2077
2078                    // Everything but the final segment should have no
2079                    // parameters at all.
2080                    let generics = tcx.generics_of(def_id);
2081                    // Variant and struct constructors use the
2082                    // generics of their parent type definition.
2083                    (generics.parent.unwrap_or(def_id), last)
2084                };
2085                generic_segments.push(GenericPathSegment(generics_def_id, index));
2086            }
2087
2088            // Case 3. Reference to a top-level value.
2089            DefKind::Fn | DefKind::Const | DefKind::ConstParam | DefKind::Static { .. } => {
2090                generic_segments.push(GenericPathSegment(def_id, last));
2091            }
2092
2093            // Case 4. Reference to a method or associated const.
2094            DefKind::AssocFn | DefKind::AssocConst => {
2095                if segments.len() >= 2 {
2096                    let generics = tcx.generics_of(def_id);
2097                    generic_segments.push(GenericPathSegment(generics.parent.unwrap(), last - 1));
2098                }
2099                generic_segments.push(GenericPathSegment(def_id, last));
2100            }
2101
2102            kind => bug!("unexpected definition kind {:?} for {:?}", kind, def_id),
2103        }
2104
2105        debug!(?generic_segments);
2106
2107        generic_segments
2108    }
2109
2110    /// Lower a [resolved][hir::QPath::Resolved] path to a type.
2111    #[instrument(level = "debug", skip_all)]
2112    pub fn lower_resolved_ty_path(
2113        &self,
2114        opt_self_ty: Option<Ty<'tcx>>,
2115        path: &hir::Path<'tcx>,
2116        hir_id: HirId,
2117        permit_variants: PermitVariants,
2118    ) -> Ty<'tcx> {
2119        debug!(?path.res, ?opt_self_ty, ?path.segments);
2120        let tcx = self.tcx();
2121
2122        let span = path.span;
2123        match path.res {
2124            Res::Def(DefKind::OpaqueTy, did) => {
2125                // Check for desugared `impl Trait`.
2126                assert_matches!(tcx.opaque_ty_origin(did), hir::OpaqueTyOrigin::TyAlias { .. });
2127                let [leading_segments @ .., segment] = path.segments else { bug!() };
2128                let _ = self.prohibit_generic_args(
2129                    leading_segments.iter(),
2130                    GenericsArgsErrExtend::OpaqueTy,
2131                );
2132                let args = self.lower_generic_args_of_path_segment(span, did, segment);
2133                Ty::new_opaque(tcx, did, args)
2134            }
2135            Res::Def(
2136                DefKind::Enum
2137                | DefKind::TyAlias
2138                | DefKind::Struct
2139                | DefKind::Union
2140                | DefKind::ForeignTy,
2141                did,
2142            ) => {
2143                assert_eq!(opt_self_ty, None);
2144                let [leading_segments @ .., segment] = path.segments else { bug!() };
2145                let _ = self
2146                    .prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
2147                self.lower_path_segment(span, did, segment)
2148            }
2149            Res::Def(kind @ DefKind::Variant, def_id)
2150                if let PermitVariants::Yes = permit_variants =>
2151            {
2152                // Lower "variant type" as if it were a real type.
2153                // The resulting `Ty` is type of the variant's enum for now.
2154                assert_eq!(opt_self_ty, None);
2155
2156                let generic_segments =
2157                    self.probe_generic_path_segments(path.segments, None, kind, def_id, span);
2158                let indices: FxHashSet<_> =
2159                    generic_segments.iter().map(|GenericPathSegment(_, index)| index).collect();
2160                let _ = self.prohibit_generic_args(
2161                    path.segments.iter().enumerate().filter_map(|(index, seg)| {
2162                        if !indices.contains(&index) { Some(seg) } else { None }
2163                    }),
2164                    GenericsArgsErrExtend::DefVariant(&path.segments),
2165                );
2166
2167                let &GenericPathSegment(def_id, index) = generic_segments.last().unwrap();
2168                self.lower_path_segment(span, def_id, &path.segments[index])
2169            }
2170            Res::Def(DefKind::TyParam, def_id) => {
2171                assert_eq!(opt_self_ty, None);
2172                let _ = self.prohibit_generic_args(
2173                    path.segments.iter(),
2174                    GenericsArgsErrExtend::Param(def_id),
2175                );
2176                self.lower_ty_param(hir_id)
2177            }
2178            Res::SelfTyParam { .. } => {
2179                // `Self` in trait or type alias.
2180                assert_eq!(opt_self_ty, None);
2181                let _ = self.prohibit_generic_args(
2182                    path.segments.iter(),
2183                    if let [hir::PathSegment { args: Some(args), ident, .. }] = &path.segments {
2184                        GenericsArgsErrExtend::SelfTyParam(
2185                            ident.span.shrink_to_hi().to(args.span_ext),
2186                        )
2187                    } else {
2188                        GenericsArgsErrExtend::None
2189                    },
2190                );
2191                self.check_param_uses_if_mcg(tcx.types.self_param, span, false)
2192            }
2193            Res::SelfTyAlias { alias_to: def_id, .. } => {
2194                // `Self` in impl (we know the concrete type).
2195                assert_eq!(opt_self_ty, None);
2196                // Try to evaluate any array length constants.
2197                let ty = tcx.at(span).type_of(def_id).instantiate_identity();
2198                let _ = self.prohibit_generic_args(
2199                    path.segments.iter(),
2200                    GenericsArgsErrExtend::SelfTyAlias { def_id, span },
2201                );
2202                self.check_param_uses_if_mcg(ty, span, true)
2203            }
2204            Res::Def(DefKind::AssocTy, def_id) => {
2205                let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
2206                    let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
2207                    Some(trait_)
2208                } else {
2209                    None
2210                };
2211                self.lower_resolved_assoc_ty_path(
2212                    span,
2213                    opt_self_ty,
2214                    def_id,
2215                    trait_segment,
2216                    path.segments.last().unwrap(),
2217                )
2218            }
2219            Res::PrimTy(prim_ty) => {
2220                assert_eq!(opt_self_ty, None);
2221                let _ = self.prohibit_generic_args(
2222                    path.segments.iter(),
2223                    GenericsArgsErrExtend::PrimTy(prim_ty),
2224                );
2225                match prim_ty {
2226                    hir::PrimTy::Bool => tcx.types.bool,
2227                    hir::PrimTy::Char => tcx.types.char,
2228                    hir::PrimTy::Int(it) => Ty::new_int(tcx, it),
2229                    hir::PrimTy::Uint(uit) => Ty::new_uint(tcx, uit),
2230                    hir::PrimTy::Float(ft) => Ty::new_float(tcx, ft),
2231                    hir::PrimTy::Str => tcx.types.str_,
2232                }
2233            }
2234            Res::Err => {
2235                let e = self
2236                    .tcx()
2237                    .dcx()
2238                    .span_delayed_bug(path.span, "path with `Res::Err` but no error emitted");
2239                Ty::new_error(tcx, e)
2240            }
2241            Res::Def(..) => {
2242                assert_eq!(
2243                    path.segments.get(0).map(|seg| seg.ident.name),
2244                    Some(kw::SelfUpper),
2245                    "only expected incorrect resolution for `Self`"
2246                );
2247                Ty::new_error(
2248                    self.tcx(),
2249                    self.dcx().span_delayed_bug(span, "incorrect resolution for `Self`"),
2250                )
2251            }
2252            _ => span_bug!(span, "unexpected resolution: {:?}", path.res),
2253        }
2254    }
2255
2256    /// Lower a type parameter from the HIR to our internal notion of a type.
2257    ///
2258    /// Early-bound type parameters get lowered to [`ty::Param`]
2259    /// and late-bound ones to [`ty::Bound`].
2260    pub(crate) fn lower_ty_param(&self, hir_id: HirId) -> Ty<'tcx> {
2261        let tcx = self.tcx();
2262
2263        let ty = match tcx.named_bound_var(hir_id) {
2264            Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => {
2265                let br = ty::BoundTy {
2266                    var: ty::BoundVar::from_u32(index),
2267                    kind: ty::BoundTyKind::Param(def_id.to_def_id()),
2268                };
2269                Ty::new_bound(tcx, debruijn, br)
2270            }
2271            Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
2272                let item_def_id = tcx.hir_ty_param_owner(def_id);
2273                let generics = tcx.generics_of(item_def_id);
2274                let index = generics.param_def_id_to_index[&def_id.to_def_id()];
2275                Ty::new_param(tcx, index, tcx.hir_ty_param_name(def_id))
2276            }
2277            Some(rbv::ResolvedArg::Error(guar)) => Ty::new_error(tcx, guar),
2278            arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"),
2279        };
2280        self.check_param_uses_if_mcg(ty, tcx.hir_span(hir_id), false)
2281    }
2282
2283    /// Lower a const parameter from the HIR to our internal notion of a constant.
2284    ///
2285    /// Early-bound const parameters get lowered to [`ty::ConstKind::Param`]
2286    /// and late-bound ones to [`ty::ConstKind::Bound`].
2287    pub(crate) fn lower_const_param(&self, param_def_id: DefId, path_hir_id: HirId) -> Const<'tcx> {
2288        let tcx = self.tcx();
2289
2290        let ct = match tcx.named_bound_var(path_hir_id) {
2291            Some(rbv::ResolvedArg::EarlyBound(_)) => {
2292                // Find the name and index of the const parameter by indexing the generics of
2293                // the parent item and construct a `ParamConst`.
2294                let item_def_id = tcx.parent(param_def_id);
2295                let generics = tcx.generics_of(item_def_id);
2296                let index = generics.param_def_id_to_index[&param_def_id];
2297                let name = tcx.item_name(param_def_id);
2298                ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
2299            }
2300            Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => ty::Const::new_bound(
2301                tcx,
2302                debruijn,
2303                ty::BoundConst { var: ty::BoundVar::from_u32(index) },
2304            ),
2305            Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
2306            arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", path_hir_id),
2307        };
2308        self.check_param_uses_if_mcg(ct, tcx.hir_span(path_hir_id), false)
2309    }
2310
2311    /// Lower a [`hir::ConstArg`] to a (type-level) [`ty::Const`](Const).
2312    #[instrument(skip(self), level = "debug")]
2313    pub fn lower_const_arg(
2314        &self,
2315        const_arg: &hir::ConstArg<'tcx>,
2316        feed: FeedConstTy<'tcx>,
2317    ) -> Const<'tcx> {
2318        let tcx = self.tcx();
2319
2320        if let FeedConstTy::WithTy(anon_const_type) = feed
2321            && let hir::ConstArgKind::Anon(anon) = &const_arg.kind
2322        {
2323            // FIXME(generic_const_parameter_types): Ideally we remove these errors below when
2324            // we have the ability to intermix typeck of anon const const args with the parent
2325            // bodies typeck.
2326
2327            // We also error if the type contains any regions as effectively any region will wind
2328            // up as a region variable in mir borrowck. It would also be somewhat concerning if
2329            // hir typeck was using equality but mir borrowck wound up using subtyping as that could
2330            // result in a non-infer in hir typeck but a region variable in borrowck.
2331            if tcx.features().generic_const_parameter_types()
2332                && (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions())
2333            {
2334                let e = self.dcx().span_err(
2335                    const_arg.span,
2336                    "anonymous constants with lifetimes in their type are not yet supported",
2337                );
2338                tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2339                return ty::Const::new_error(tcx, e);
2340            }
2341            // We must error if the instantiated type has any inference variables as we will
2342            // use this type to feed the `type_of` and query results must not contain inference
2343            // variables otherwise we will ICE.
2344            if anon_const_type.has_non_region_infer() {
2345                let e = self.dcx().span_err(
2346                    const_arg.span,
2347                    "anonymous constants with inferred types are not yet supported",
2348                );
2349                tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2350                return ty::Const::new_error(tcx, e);
2351            }
2352            // We error when the type contains unsubstituted generics since we do not currently
2353            // give the anon const any of the generics from the parent.
2354            if anon_const_type.has_non_region_param() {
2355                let e = self.dcx().span_err(
2356                    const_arg.span,
2357                    "anonymous constants referencing generics are not yet supported",
2358                );
2359                tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2360                return ty::Const::new_error(tcx, e);
2361            }
2362
2363            tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(anon_const_type));
2364        }
2365
2366        let hir_id = const_arg.hir_id;
2367        match const_arg.kind {
2368            hir::ConstArgKind::Tup(exprs) => self.lower_const_arg_tup(exprs, feed, const_arg.span),
2369            hir::ConstArgKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2370                debug!(?maybe_qself, ?path);
2371                let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2372                self.lower_resolved_const_path(opt_self_ty, path, hir_id)
2373            }
2374            hir::ConstArgKind::Path(hir::QPath::TypeRelative(hir_self_ty, segment)) => {
2375                debug!(?hir_self_ty, ?segment);
2376                let self_ty = self.lower_ty(hir_self_ty);
2377                self.lower_type_relative_const_path(
2378                    self_ty,
2379                    hir_self_ty,
2380                    segment,
2381                    hir_id,
2382                    const_arg.span,
2383                )
2384                .unwrap_or_else(|guar| Const::new_error(tcx, guar))
2385            }
2386            hir::ConstArgKind::Struct(qpath, inits) => {
2387                self.lower_const_arg_struct(hir_id, qpath, inits, const_arg.span)
2388            }
2389            hir::ConstArgKind::TupleCall(qpath, args) => {
2390                self.lower_const_arg_tuple_call(hir_id, qpath, args, const_arg.span)
2391            }
2392            hir::ConstArgKind::Array(array_expr) => self.lower_const_arg_array(array_expr, feed),
2393            hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon),
2394            hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span),
2395            hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e),
2396            hir::ConstArgKind::Literal(kind) if let FeedConstTy::WithTy(anon_const_type) = feed => {
2397                self.lower_const_arg_literal(&kind, anon_const_type, const_arg.span)
2398            }
2399            hir::ConstArgKind::Literal(..) => {
2400                let e = self.dcx().span_err(const_arg.span, "literal of unknown type");
2401                ty::Const::new_error(tcx, e)
2402            }
2403        }
2404    }
2405
2406    fn lower_const_arg_array(
2407        &self,
2408        array_expr: &'tcx hir::ConstArgArrayExpr<'tcx>,
2409        feed: FeedConstTy<'tcx>,
2410    ) -> Const<'tcx> {
2411        let tcx = self.tcx();
2412
2413        let FeedConstTy::WithTy(ty) = feed else {
2414            return Const::new_error_with_message(tcx, array_expr.span, "unsupported const array");
2415        };
2416
2417        let ty::Array(elem_ty, _) = ty.kind() else {
2418            return Const::new_error_with_message(
2419                tcx,
2420                array_expr.span,
2421                "const array must have an array type",
2422            );
2423        };
2424
2425        let elems = array_expr
2426            .elems
2427            .iter()
2428            .map(|elem| self.lower_const_arg(elem, FeedConstTy::WithTy(*elem_ty)))
2429            .collect::<Vec<_>>();
2430
2431        let valtree = ty::ValTree::from_branches(tcx, elems);
2432
2433        ty::Const::new_value(tcx, valtree, ty)
2434    }
2435
2436    fn lower_const_arg_tuple_call(
2437        &self,
2438        hir_id: HirId,
2439        qpath: hir::QPath<'tcx>,
2440        args: &'tcx [&'tcx hir::ConstArg<'tcx>],
2441        span: Span,
2442    ) -> Const<'tcx> {
2443        let tcx = self.tcx();
2444
2445        let non_adt_or_variant_res = || {
2446            let e = tcx.dcx().span_err(span, "tuple constructor with invalid base path");
2447            ty::Const::new_error(tcx, e)
2448        };
2449
2450        let ctor_const = match qpath {
2451            hir::QPath::Resolved(maybe_qself, path) => {
2452                let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2453                self.lower_resolved_const_path(opt_self_ty, path, hir_id)
2454            }
2455            hir::QPath::TypeRelative(hir_self_ty, segment) => {
2456                let self_ty = self.lower_ty(hir_self_ty);
2457                match self.lower_type_relative_const_path(
2458                    self_ty,
2459                    hir_self_ty,
2460                    segment,
2461                    hir_id,
2462                    span,
2463                ) {
2464                    Ok(c) => c,
2465                    Err(_) => return non_adt_or_variant_res(),
2466                }
2467            }
2468        };
2469
2470        let Some(value) = ctor_const.try_to_value() else {
2471            return non_adt_or_variant_res();
2472        };
2473
2474        let (adt_def, adt_args, variant_did) = match value.ty.kind() {
2475            ty::FnDef(def_id, fn_args)
2476                if let DefKind::Ctor(CtorOf::Variant, _) = tcx.def_kind(*def_id) =>
2477            {
2478                let parent_did = tcx.parent(*def_id);
2479                let enum_did = tcx.parent(parent_did);
2480                (tcx.adt_def(enum_did), fn_args, parent_did)
2481            }
2482            ty::FnDef(def_id, fn_args)
2483                if let DefKind::Ctor(CtorOf::Struct, _) = tcx.def_kind(*def_id) =>
2484            {
2485                let parent_did = tcx.parent(*def_id);
2486                (tcx.adt_def(parent_did), fn_args, parent_did)
2487            }
2488            _ => return non_adt_or_variant_res(),
2489        };
2490
2491        let variant_def = adt_def.variant_with_id(variant_did);
2492        let variant_idx = adt_def.variant_index_with_id(variant_did).as_u32();
2493
2494        if args.len() != variant_def.fields.len() {
2495            let e = tcx.dcx().span_err(
2496                span,
2497                format!(
2498                    "tuple constructor has {} arguments but {} were provided",
2499                    variant_def.fields.len(),
2500                    args.len()
2501                ),
2502            );
2503            return ty::Const::new_error(tcx, e);
2504        }
2505
2506        let fields = variant_def
2507            .fields
2508            .iter()
2509            .zip(args)
2510            .map(|(field_def, arg)| {
2511                self.lower_const_arg(arg, FeedConstTy::with_type_of(tcx, field_def.did, adt_args))
2512            })
2513            .collect::<Vec<_>>();
2514
2515        let opt_discr_const = if adt_def.is_enum() {
2516            let valtree = ty::ValTree::from_scalar_int(tcx, variant_idx.into());
2517            Some(ty::Const::new_value(tcx, valtree, tcx.types.u32))
2518        } else {
2519            None
2520        };
2521
2522        let valtree = ty::ValTree::from_branches(tcx, opt_discr_const.into_iter().chain(fields));
2523        let adt_ty = Ty::new_adt(tcx, adt_def, adt_args);
2524        ty::Const::new_value(tcx, valtree, adt_ty)
2525    }
2526
2527    fn lower_const_arg_tup(
2528        &self,
2529        exprs: &'tcx [&'tcx hir::ConstArg<'tcx>],
2530        feed: FeedConstTy<'tcx>,
2531        span: Span,
2532    ) -> Const<'tcx> {
2533        let tcx = self.tcx();
2534
2535        let FeedConstTy::WithTy(ty) = feed else {
2536            return Const::new_error_with_message(tcx, span, "const tuple lack type information");
2537        };
2538
2539        let ty::Tuple(tys) = ty.kind() else {
2540            let e = tcx.dcx().span_err(span, format!("expected `{}`, found const tuple", ty));
2541            return Const::new_error(tcx, e);
2542        };
2543
2544        let exprs = exprs
2545            .iter()
2546            .zip(tys.iter())
2547            .map(|(expr, ty)| self.lower_const_arg(expr, FeedConstTy::WithTy(ty)))
2548            .collect::<Vec<_>>();
2549
2550        let valtree = ty::ValTree::from_branches(tcx, exprs);
2551        ty::Const::new_value(tcx, valtree, ty)
2552    }
2553
2554    fn lower_const_arg_struct(
2555        &self,
2556        hir_id: HirId,
2557        qpath: hir::QPath<'tcx>,
2558        inits: &'tcx [&'tcx hir::ConstArgExprField<'tcx>],
2559        span: Span,
2560    ) -> Const<'tcx> {
2561        // FIXME(mgca): try to deduplicate this function with
2562        // the equivalent HIR typeck logic.
2563        let tcx = self.tcx();
2564
2565        let non_adt_or_variant_res = || {
2566            let e = tcx.dcx().span_err(span, "struct expression with invalid base path");
2567            ty::Const::new_error(tcx, e)
2568        };
2569
2570        let (ty, variant_did) = match qpath {
2571            hir::QPath::Resolved(maybe_qself, path) => {
2572                debug!(?maybe_qself, ?path);
2573                let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2574                let ty =
2575                    self.lower_resolved_ty_path(opt_self_ty, path, hir_id, PermitVariants::Yes);
2576                let variant_did = match path.res {
2577                    Res::Def(DefKind::Variant | DefKind::Struct, did) => did,
2578                    _ => return non_adt_or_variant_res(),
2579                };
2580
2581                (ty, variant_did)
2582            }
2583            hir::QPath::TypeRelative(hir_self_ty, segment) => {
2584                debug!(?hir_self_ty, ?segment);
2585                let self_ty = self.lower_ty(hir_self_ty);
2586                let opt_res = self.lower_type_relative_ty_path(
2587                    self_ty,
2588                    hir_self_ty,
2589                    segment,
2590                    hir_id,
2591                    span,
2592                    PermitVariants::Yes,
2593                );
2594
2595                let (ty, _, res_def_id) = match opt_res {
2596                    Ok(r @ (_, DefKind::Variant | DefKind::Struct, _)) => r,
2597                    Ok(_) => return non_adt_or_variant_res(),
2598                    Err(e) => return ty::Const::new_error(tcx, e),
2599                };
2600
2601                (ty, res_def_id)
2602            }
2603        };
2604
2605        let ty::Adt(adt_def, adt_args) = ty.kind() else { unreachable!() };
2606
2607        let variant_def = adt_def.variant_with_id(variant_did);
2608        let variant_idx = adt_def.variant_index_with_id(variant_did).as_u32();
2609
2610        let fields = variant_def
2611            .fields
2612            .iter()
2613            .map(|field_def| {
2614                // FIXME(mgca): we aren't really handling privacy, stability,
2615                // or macro hygeniene but we should.
2616                let mut init_expr =
2617                    inits.iter().filter(|init_expr| init_expr.field.name == field_def.name);
2618
2619                match init_expr.next() {
2620                    Some(expr) => {
2621                        if let Some(expr) = init_expr.next() {
2622                            let e = tcx.dcx().span_err(
2623                                expr.span,
2624                                format!(
2625                                    "struct expression with multiple initialisers for `{}`",
2626                                    field_def.name,
2627                                ),
2628                            );
2629                            return ty::Const::new_error(tcx, e);
2630                        }
2631
2632                        self.lower_const_arg(
2633                            expr.expr,
2634                            FeedConstTy::with_type_of(tcx, field_def.did, adt_args),
2635                        )
2636                    }
2637                    None => {
2638                        let e = tcx.dcx().span_err(
2639                            span,
2640                            format!(
2641                                "struct expression with missing field initialiser for `{}`",
2642                                field_def.name
2643                            ),
2644                        );
2645                        ty::Const::new_error(tcx, e)
2646                    }
2647                }
2648            })
2649            .collect::<Vec<_>>();
2650
2651        let opt_discr_const = if adt_def.is_enum() {
2652            let valtree = ty::ValTree::from_scalar_int(tcx, variant_idx.into());
2653            Some(ty::Const::new_value(tcx, valtree, tcx.types.u32))
2654        } else {
2655            None
2656        };
2657
2658        let valtree = ty::ValTree::from_branches(tcx, opt_discr_const.into_iter().chain(fields));
2659        ty::Const::new_value(tcx, valtree, ty)
2660    }
2661
2662    /// Lower a [resolved][hir::QPath::Resolved] path to a (type-level) constant.
2663    fn lower_resolved_const_path(
2664        &self,
2665        opt_self_ty: Option<Ty<'tcx>>,
2666        path: &hir::Path<'tcx>,
2667        hir_id: HirId,
2668    ) -> Const<'tcx> {
2669        let tcx = self.tcx();
2670        let span = path.span;
2671        let ct = match path.res {
2672            Res::Def(DefKind::ConstParam, def_id) => {
2673                assert_eq!(opt_self_ty, None);
2674                let _ = self.prohibit_generic_args(
2675                    path.segments.iter(),
2676                    GenericsArgsErrExtend::Param(def_id),
2677                );
2678                self.lower_const_param(def_id, hir_id)
2679            }
2680            Res::Def(DefKind::Const, did) => {
2681                assert_eq!(opt_self_ty, None);
2682                let [leading_segments @ .., segment] = path.segments else { bug!() };
2683                let _ = self
2684                    .prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
2685                let args = self.lower_generic_args_of_path_segment(span, did, segment);
2686                ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
2687            }
2688            Res::Def(DefKind::Ctor(ctor_of, CtorKind::Const), did) => {
2689                assert_eq!(opt_self_ty, None);
2690                let [leading_segments @ .., segment] = path.segments else { bug!() };
2691                let _ = self
2692                    .prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
2693
2694                let parent_did = tcx.parent(did);
2695                let generics_did = match ctor_of {
2696                    CtorOf::Variant => tcx.parent(parent_did),
2697                    CtorOf::Struct => parent_did,
2698                };
2699                let args = self.lower_generic_args_of_path_segment(span, generics_did, segment);
2700
2701                self.construct_const_ctor_value(did, ctor_of, args)
2702            }
2703            Res::Def(DefKind::Ctor(_, CtorKind::Fn), did) => {
2704                assert_eq!(opt_self_ty, None);
2705                let [leading_segments @ .., segment] = path.segments else { bug!() };
2706                let _ = self
2707                    .prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
2708                let parent_did = tcx.parent(did);
2709                let generics_did = if let DefKind::Ctor(CtorOf::Variant, _) = tcx.def_kind(did) {
2710                    tcx.parent(parent_did)
2711                } else {
2712                    parent_did
2713                };
2714                let args = self.lower_generic_args_of_path_segment(span, generics_did, segment);
2715                ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, did, args))
2716            }
2717            Res::Def(DefKind::AssocConst, did) => {
2718                let trait_segment = if let [modules @ .., trait_, _item] = path.segments {
2719                    let _ = self.prohibit_generic_args(modules.iter(), GenericsArgsErrExtend::None);
2720                    Some(trait_)
2721                } else {
2722                    None
2723                };
2724                self.lower_resolved_assoc_const_path(
2725                    span,
2726                    opt_self_ty,
2727                    did,
2728                    trait_segment,
2729                    path.segments.last().unwrap(),
2730                )
2731            }
2732            Res::Def(DefKind::Static { .. }, _) => {
2733                span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported")
2734            }
2735            // FIXME(const_generics): create real const to allow fn items as const paths
2736            Res::Def(DefKind::Fn | DefKind::AssocFn, did) => {
2737                self.dcx().span_delayed_bug(span, "function items cannot be used as const args");
2738                let args = self.lower_generic_args_of_path_segment(
2739                    span,
2740                    did,
2741                    path.segments.last().unwrap(),
2742                );
2743                ty::Const::zero_sized(tcx, Ty::new_fn_def(tcx, did, args))
2744            }
2745
2746            // Exhaustive match to be clear about what exactly we're considering to be
2747            // an invalid Res for a const path.
2748            res @ (Res::Def(
2749                DefKind::Mod
2750                | DefKind::Enum
2751                | DefKind::Variant
2752                | DefKind::Struct
2753                | DefKind::OpaqueTy
2754                | DefKind::TyAlias
2755                | DefKind::TraitAlias
2756                | DefKind::AssocTy
2757                | DefKind::Union
2758                | DefKind::Trait
2759                | DefKind::ForeignTy
2760                | DefKind::TyParam
2761                | DefKind::Macro(_)
2762                | DefKind::LifetimeParam
2763                | DefKind::Use
2764                | DefKind::ForeignMod
2765                | DefKind::AnonConst
2766                | DefKind::InlineConst
2767                | DefKind::Field
2768                | DefKind::Impl { .. }
2769                | DefKind::Closure
2770                | DefKind::ExternCrate
2771                | DefKind::GlobalAsm
2772                | DefKind::SyntheticCoroutineBody,
2773                _,
2774            )
2775            | Res::PrimTy(_)
2776            | Res::SelfTyParam { .. }
2777            | Res::SelfTyAlias { .. }
2778            | Res::SelfCtor(_)
2779            | Res::Local(_)
2780            | Res::ToolMod
2781            | Res::NonMacroAttr(_)
2782            | Res::Err) => Const::new_error_with_message(
2783                tcx,
2784                span,
2785                format!("invalid Res {res:?} for const path"),
2786            ),
2787        };
2788        self.check_param_uses_if_mcg(ct, span, false)
2789    }
2790
2791    /// Literals are eagerly converted to a constant, everything else becomes `Unevaluated`.
2792    #[instrument(skip(self), level = "debug")]
2793    fn lower_const_arg_anon(&self, anon: &AnonConst) -> Const<'tcx> {
2794        let tcx = self.tcx();
2795
2796        let expr = &tcx.hir_body(anon.body).value;
2797        debug!(?expr);
2798
2799        // FIXME(generic_const_parameter_types): We should use the proper generic args
2800        // here. It's only used as a hint for literals so doesn't matter too much to use the right
2801        // generic arguments, just weaker type inference.
2802        let ty = tcx.type_of(anon.def_id).instantiate_identity();
2803
2804        match self.try_lower_anon_const_lit(ty, expr) {
2805            Some(v) => v,
2806            None => ty::Const::new_unevaluated(
2807                tcx,
2808                ty::UnevaluatedConst {
2809                    def: anon.def_id.to_def_id(),
2810                    args: ty::GenericArgs::identity_for_item(tcx, anon.def_id.to_def_id()),
2811                },
2812            ),
2813        }
2814    }
2815
2816    #[instrument(skip(self), level = "debug")]
2817    fn lower_const_arg_literal(&self, kind: &LitKind, ty: Ty<'tcx>, span: Span) -> Const<'tcx> {
2818        let tcx = self.tcx();
2819        let input = LitToConstInput { lit: *kind, ty, neg: false };
2820        tcx.at(span).lit_to_const(input)
2821    }
2822
2823    #[instrument(skip(self), level = "debug")]
2824    fn try_lower_anon_const_lit(
2825        &self,
2826        ty: Ty<'tcx>,
2827        expr: &'tcx hir::Expr<'tcx>,
2828    ) -> Option<Const<'tcx>> {
2829        let tcx = self.tcx();
2830
2831        // Unwrap a block, so that e.g. `{ 1 }` is recognised as a literal. This makes the
2832        // performance optimisation of directly lowering anon consts occur more often.
2833        let expr = match &expr.kind {
2834            hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
2835                block.expr.as_ref().unwrap()
2836            }
2837            _ => expr,
2838        };
2839
2840        let lit_input = match expr.kind {
2841            hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: lit.node, ty, neg: false }),
2842            hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind {
2843                hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: lit.node, ty, neg: true }),
2844                _ => None,
2845            },
2846            _ => None,
2847        };
2848
2849        lit_input
2850            // Allow the `ty` to be an alias type, though we cannot handle it here, we just go through
2851            // the more expensive anon const code path.
2852            .filter(|l| !l.ty.has_aliases())
2853            .map(|l| tcx.at(expr.span).lit_to_const(l))
2854    }
2855
2856    fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
2857        let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id());
2858        match idx {
2859            hir::InferDelegationKind::Input(idx) => delegation_sig[idx],
2860            hir::InferDelegationKind::Output => *delegation_sig.last().unwrap(),
2861        }
2862    }
2863
2864    /// Lower a type from the HIR to our internal notion of a type.
2865    #[instrument(level = "debug", skip(self), ret)]
2866    pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
2867        let tcx = self.tcx();
2868
2869        let result_ty = match &hir_ty.kind {
2870            hir::TyKind::InferDelegation(_, idx) => self.lower_delegation_ty(*idx),
2871            hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.lower_ty(ty)),
2872            hir::TyKind::Ptr(mt) => Ty::new_ptr(tcx, self.lower_ty(mt.ty), mt.mutbl),
2873            hir::TyKind::Ref(region, mt) => {
2874                let r = self.lower_lifetime(region, RegionInferReason::Reference);
2875                debug!(?r);
2876                let t = self.lower_ty(mt.ty);
2877                Ty::new_ref(tcx, r, t, mt.mutbl)
2878            }
2879            hir::TyKind::Never => tcx.types.never,
2880            hir::TyKind::Tup(fields) => {
2881                Ty::new_tup_from_iter(tcx, fields.iter().map(|t| self.lower_ty(t)))
2882            }
2883            hir::TyKind::FnPtr(bf) => {
2884                check_c_variadic_abi(tcx, bf.decl, bf.abi, hir_ty.span);
2885
2886                Ty::new_fn_ptr(
2887                    tcx,
2888                    self.lower_fn_ty(hir_ty.hir_id, bf.safety, bf.abi, bf.decl, None, Some(hir_ty)),
2889                )
2890            }
2891            hir::TyKind::UnsafeBinder(binder) => Ty::new_unsafe_binder(
2892                tcx,
2893                ty::Binder::bind_with_vars(
2894                    self.lower_ty(binder.inner_ty),
2895                    tcx.late_bound_vars(hir_ty.hir_id),
2896                ),
2897            ),
2898            hir::TyKind::TraitObject(bounds, tagged_ptr) => {
2899                let lifetime = tagged_ptr.pointer();
2900                let syntax = tagged_ptr.tag();
2901                self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, syntax)
2902            }
2903            // If we encounter a fully qualified path with RTN generics, then it must have
2904            // *not* gone through `lower_ty_maybe_return_type_notation`, and therefore
2905            // it's certainly in an illegal position.
2906            hir::TyKind::Path(hir::QPath::Resolved(_, path))
2907                if path.segments.last().and_then(|segment| segment.args).is_some_and(|args| {
2908                    matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
2909                }) =>
2910            {
2911                let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
2912                Ty::new_error(tcx, guar)
2913            }
2914            hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2915                debug!(?maybe_qself, ?path);
2916                let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
2917                self.lower_resolved_ty_path(opt_self_ty, path, hir_ty.hir_id, PermitVariants::No)
2918            }
2919            &hir::TyKind::OpaqueDef(opaque_ty) => {
2920                // If this is an RPITIT and we are using the new RPITIT lowering scheme, we
2921                // generate the def_id of an associated type for the trait and return as
2922                // type a projection.
2923                let in_trait = match opaque_ty.origin {
2924                    hir::OpaqueTyOrigin::FnReturn {
2925                        parent,
2926                        in_trait_or_impl: Some(hir::RpitContext::Trait),
2927                        ..
2928                    }
2929                    | hir::OpaqueTyOrigin::AsyncFn {
2930                        parent,
2931                        in_trait_or_impl: Some(hir::RpitContext::Trait),
2932                        ..
2933                    } => Some(parent),
2934                    hir::OpaqueTyOrigin::FnReturn {
2935                        in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
2936                        ..
2937                    }
2938                    | hir::OpaqueTyOrigin::AsyncFn {
2939                        in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl),
2940                        ..
2941                    }
2942                    | hir::OpaqueTyOrigin::TyAlias { .. } => None,
2943                };
2944
2945                self.lower_opaque_ty(opaque_ty.def_id, in_trait)
2946            }
2947            hir::TyKind::TraitAscription(hir_bounds) => {
2948                // Impl trait in bindings lower as an infer var with additional
2949                // set of type bounds.
2950                let self_ty = self.ty_infer(None, hir_ty.span);
2951                let mut bounds = Vec::new();
2952                self.lower_bounds(
2953                    self_ty,
2954                    hir_bounds.iter(),
2955                    &mut bounds,
2956                    ty::List::empty(),
2957                    PredicateFilter::All,
2958                    OverlappingAsssocItemConstraints::Allowed,
2959                );
2960                self.add_implicit_sizedness_bounds(
2961                    &mut bounds,
2962                    self_ty,
2963                    hir_bounds,
2964                    ImpliedBoundsContext::AssociatedTypeOrImplTrait,
2965                    hir_ty.span,
2966                );
2967                self.register_trait_ascription_bounds(bounds, hir_ty.hir_id, hir_ty.span);
2968                self_ty
2969            }
2970            // If we encounter a type relative path with RTN generics, then it must have
2971            // *not* gone through `lower_ty_maybe_return_type_notation`, and therefore
2972            // it's certainly in an illegal position.
2973            hir::TyKind::Path(hir::QPath::TypeRelative(_, segment))
2974                if segment.args.is_some_and(|args| {
2975                    matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
2976                }) =>
2977            {
2978                let guar = self.dcx().emit_err(BadReturnTypeNotation { span: hir_ty.span });
2979                Ty::new_error(tcx, guar)
2980            }
2981            hir::TyKind::Path(hir::QPath::TypeRelative(hir_self_ty, segment)) => {
2982                debug!(?hir_self_ty, ?segment);
2983                let self_ty = self.lower_ty(hir_self_ty);
2984                self.lower_type_relative_ty_path(
2985                    self_ty,
2986                    hir_self_ty,
2987                    segment,
2988                    hir_ty.hir_id,
2989                    hir_ty.span,
2990                    PermitVariants::No,
2991                )
2992                .map(|(ty, _, _)| ty)
2993                .unwrap_or_else(|guar| Ty::new_error(tcx, guar))
2994            }
2995            hir::TyKind::Array(ty, length) => {
2996                let length = self.lower_const_arg(length, FeedConstTy::No);
2997                Ty::new_array_with_const_len(tcx, self.lower_ty(ty), length)
2998            }
2999            hir::TyKind::Infer(()) => {
3000                // Infer also appears as the type of arguments or return
3001                // values in an ExprKind::Closure, or as
3002                // the type of local variables. Both of these cases are
3003                // handled specially and will not descend into this routine.
3004                self.ty_infer(None, hir_ty.span)
3005            }
3006            hir::TyKind::Pat(ty, pat) => {
3007                let ty_span = ty.span;
3008                let ty = self.lower_ty(ty);
3009                let pat_ty = match self.lower_pat_ty_pat(ty, ty_span, pat) {
3010                    Ok(kind) => Ty::new_pat(tcx, ty, tcx.mk_pat(kind)),
3011                    Err(guar) => Ty::new_error(tcx, guar),
3012                };
3013                self.record_ty(pat.hir_id, ty, pat.span);
3014                pat_ty
3015            }
3016            hir::TyKind::Err(guar) => Ty::new_error(tcx, *guar),
3017        };
3018
3019        self.record_ty(hir_ty.hir_id, result_ty, hir_ty.span);
3020        result_ty
3021    }
3022
3023    fn lower_pat_ty_pat(
3024        &self,
3025        ty: Ty<'tcx>,
3026        ty_span: Span,
3027        pat: &hir::TyPat<'tcx>,
3028    ) -> Result<ty::PatternKind<'tcx>, ErrorGuaranteed> {
3029        let tcx = self.tcx();
3030        match pat.kind {
3031            hir::TyPatKind::Range(start, end) => {
3032                match ty.kind() {
3033                    // Keep this list of types in sync with the list of types that
3034                    // the `RangePattern` trait is implemented for.
3035                    ty::Int(_) | ty::Uint(_) | ty::Char => {
3036                        let start = self.lower_const_arg(start, FeedConstTy::No);
3037                        let end = self.lower_const_arg(end, FeedConstTy::No);
3038                        Ok(ty::PatternKind::Range { start, end })
3039                    }
3040                    _ => Err(self
3041                        .dcx()
3042                        .span_delayed_bug(ty_span, "invalid base type for range pattern")),
3043                }
3044            }
3045            hir::TyPatKind::NotNull => Ok(ty::PatternKind::NotNull),
3046            hir::TyPatKind::Or(patterns) => {
3047                self.tcx()
3048                    .mk_patterns_from_iter(patterns.iter().map(|pat| {
3049                        self.lower_pat_ty_pat(ty, ty_span, pat).map(|pat| tcx.mk_pat(pat))
3050                    }))
3051                    .map(ty::PatternKind::Or)
3052            }
3053            hir::TyPatKind::Err(e) => Err(e),
3054        }
3055    }
3056
3057    /// Lower an opaque type (i.e., an existential impl-Trait type) from the HIR.
3058    #[instrument(level = "debug", skip(self), ret)]
3059    fn lower_opaque_ty(&self, def_id: LocalDefId, in_trait: Option<LocalDefId>) -> Ty<'tcx> {
3060        let tcx = self.tcx();
3061
3062        let lifetimes = tcx.opaque_captured_lifetimes(def_id);
3063        debug!(?lifetimes);
3064
3065        // If this is an RPITIT and we are using the new RPITIT lowering scheme,
3066        // do a linear search to map this to the synthetic associated type that
3067        // it will be lowered to.
3068        let def_id = if let Some(parent_def_id) = in_trait {
3069            *tcx.associated_types_for_impl_traits_in_associated_fn(parent_def_id.to_def_id())
3070                .iter()
3071                .find(|rpitit| match tcx.opt_rpitit_info(**rpitit) {
3072                    Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
3073                        opaque_def_id.expect_local() == def_id
3074                    }
3075                    _ => unreachable!(),
3076                })
3077                .unwrap()
3078        } else {
3079            def_id.to_def_id()
3080        };
3081
3082        let generics = tcx.generics_of(def_id);
3083        debug!(?generics);
3084
3085        // We use `generics.count() - lifetimes.len()` here instead of `generics.parent_count`
3086        // since return-position impl trait in trait squashes all of the generics from its source fn
3087        // into its own generics, so the opaque's "own" params isn't always just lifetimes.
3088        let offset = generics.count() - lifetimes.len();
3089
3090        let args = ty::GenericArgs::for_item(tcx, def_id, |param, _| {
3091            if let Some(i) = (param.index as usize).checked_sub(offset) {
3092                let (lifetime, _) = lifetimes[i];
3093                // FIXME(mgca): should we be calling self.check_params_use_if_mcg here too?
3094                self.lower_resolved_lifetime(lifetime).into()
3095            } else {
3096                tcx.mk_param_from_def(param)
3097            }
3098        });
3099        debug!(?args);
3100
3101        if in_trait.is_some() {
3102            Ty::new_projection_from_args(tcx, def_id, args)
3103        } else {
3104            Ty::new_opaque(tcx, def_id, args)
3105        }
3106    }
3107
3108    /// Lower a function type from the HIR to our internal notion of a function signature.
3109    #[instrument(level = "debug", skip(self, hir_id, safety, abi, decl, generics, hir_ty), ret)]
3110    pub fn lower_fn_ty(
3111        &self,
3112        hir_id: HirId,
3113        safety: hir::Safety,
3114        abi: rustc_abi::ExternAbi,
3115        decl: &hir::FnDecl<'tcx>,
3116        generics: Option<&hir::Generics<'_>>,
3117        hir_ty: Option<&hir::Ty<'_>>,
3118    ) -> ty::PolyFnSig<'tcx> {
3119        let tcx = self.tcx();
3120        let bound_vars = tcx.late_bound_vars(hir_id);
3121        debug!(?bound_vars);
3122
3123        let (input_tys, output_ty) = self.lower_fn_sig(decl, generics, hir_id, hir_ty);
3124
3125        debug!(?output_ty);
3126
3127        let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, safety, abi);
3128        let fn_ptr_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
3129
3130        if let hir::Node::Ty(hir::Ty { kind: hir::TyKind::FnPtr(fn_ptr_ty), span, .. }) =
3131            tcx.hir_node(hir_id)
3132        {
3133            check_abi(tcx, hir_id, *span, fn_ptr_ty.abi);
3134        }
3135
3136        // reject function types that violate cmse ABI requirements
3137        cmse::validate_cmse_abi(self.tcx(), self.dcx(), hir_id, abi, fn_ptr_ty);
3138
3139        if !fn_ptr_ty.references_error() {
3140            // Find any late-bound regions declared in return type that do
3141            // not appear in the arguments. These are not well-formed.
3142            //
3143            // Example:
3144            //     for<'a> fn() -> &'a str <-- 'a is bad
3145            //     for<'a> fn(&'a String) -> &'a str <-- 'a is ok
3146            let inputs = fn_ptr_ty.inputs();
3147            let late_bound_in_args =
3148                tcx.collect_constrained_late_bound_regions(inputs.map_bound(|i| i.to_owned()));
3149            let output = fn_ptr_ty.output();
3150            let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(output);
3151
3152            self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| {
3153                struct_span_code_err!(
3154                    self.dcx(),
3155                    decl.output.span(),
3156                    E0581,
3157                    "return type references {}, which is not constrained by the fn input types",
3158                    br_name
3159                )
3160            });
3161        }
3162
3163        fn_ptr_ty
3164    }
3165
3166    /// Given a fn_hir_id for a impl function, suggest the type that is found on the
3167    /// corresponding function in the trait that the impl implements, if it exists.
3168    /// If arg_idx is Some, then it corresponds to an input type index, otherwise it
3169    /// corresponds to the return type.
3170    pub(super) fn suggest_trait_fn_ty_for_impl_fn_infer(
3171        &self,
3172        fn_hir_id: HirId,
3173        arg_idx: Option<usize>,
3174    ) -> Option<Ty<'tcx>> {
3175        let tcx = self.tcx();
3176        let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) =
3177            tcx.hir_node(fn_hir_id)
3178        else {
3179            return None;
3180        };
3181        let i = tcx.parent_hir_node(fn_hir_id).expect_item().expect_impl();
3182
3183        let trait_ref = self.lower_impl_trait_ref(&i.of_trait?.trait_ref, self.lower_ty(i.self_ty));
3184
3185        let assoc = tcx.associated_items(trait_ref.def_id).find_by_ident_and_kind(
3186            tcx,
3187            *ident,
3188            ty::AssocTag::Fn,
3189            trait_ref.def_id,
3190        )?;
3191
3192        let fn_sig = tcx.fn_sig(assoc.def_id).instantiate(
3193            tcx,
3194            trait_ref.args.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)),
3195        );
3196        let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig);
3197
3198        Some(if let Some(arg_idx) = arg_idx {
3199            *fn_sig.inputs().get(arg_idx)?
3200        } else {
3201            fn_sig.output()
3202        })
3203    }
3204
3205    #[instrument(level = "trace", skip(self, generate_err))]
3206    fn validate_late_bound_regions<'cx>(
3207        &'cx self,
3208        constrained_regions: FxIndexSet<ty::BoundRegionKind>,
3209        referenced_regions: FxIndexSet<ty::BoundRegionKind>,
3210        generate_err: impl Fn(&str) -> Diag<'cx>,
3211    ) {
3212        for br in referenced_regions.difference(&constrained_regions) {
3213            let br_name = if let Some(name) = br.get_name(self.tcx()) {
3214                format!("lifetime `{name}`")
3215            } else {
3216                "an anonymous lifetime".to_string()
3217            };
3218
3219            let mut err = generate_err(&br_name);
3220
3221            if !br.is_named(self.tcx()) {
3222                // The only way for an anonymous lifetime to wind up
3223                // in the return type but **also** be unconstrained is
3224                // if it only appears in "associated types" in the
3225                // input. See #47511 and #62200 for examples. In this case,
3226                // though we can easily give a hint that ought to be
3227                // relevant.
3228                err.note(
3229                    "lifetimes appearing in an associated or opaque type are not considered constrained",
3230                );
3231                err.note("consider introducing a named lifetime parameter");
3232            }
3233
3234            err.emit();
3235        }
3236    }
3237
3238    /// Given the bounds on an object, determines what single region bound (if any) we can
3239    /// use to summarize this type.
3240    ///
3241    /// The basic idea is that we will use the bound the user
3242    /// provided, if they provided one, and otherwise search the supertypes of trait bounds
3243    /// for region bounds. It may be that we can derive no bound at all, in which case
3244    /// we return `None`.
3245    #[instrument(level = "debug", skip(self, span), ret)]
3246    fn compute_object_lifetime_bound(
3247        &self,
3248        span: Span,
3249        existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
3250    ) -> Option<ty::Region<'tcx>> // if None, use the default
3251    {
3252        let tcx = self.tcx();
3253
3254        // No explicit region bound specified. Therefore, examine trait
3255        // bounds and see if we can derive region bounds from those.
3256        let derived_region_bounds = object_region_bounds(tcx, existential_predicates);
3257
3258        // If there are no derived region bounds, then report back that we
3259        // can find no region bound. The caller will use the default.
3260        if derived_region_bounds.is_empty() {
3261            return None;
3262        }
3263
3264        // If any of the derived region bounds are 'static, that is always
3265        // the best choice.
3266        if derived_region_bounds.iter().any(|r| r.is_static()) {
3267            return Some(tcx.lifetimes.re_static);
3268        }
3269
3270        // Determine whether there is exactly one unique region in the set
3271        // of derived region bounds. If so, use that. Otherwise, report an
3272        // error.
3273        let r = derived_region_bounds[0];
3274        if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
3275            self.dcx().emit_err(AmbiguousLifetimeBound { span });
3276        }
3277        Some(r)
3278    }
3279
3280    fn construct_const_ctor_value(
3281        &self,
3282        ctor_def_id: DefId,
3283        ctor_of: CtorOf,
3284        args: GenericArgsRef<'tcx>,
3285    ) -> Const<'tcx> {
3286        let tcx = self.tcx();
3287        let parent_did = tcx.parent(ctor_def_id);
3288
3289        let adt_def = tcx.adt_def(match ctor_of {
3290            CtorOf::Variant => tcx.parent(parent_did),
3291            CtorOf::Struct => parent_did,
3292        });
3293
3294        let variant_idx = adt_def.variant_index_with_id(parent_did);
3295
3296        let valtree = if adt_def.is_enum() {
3297            let discr = ty::ValTree::from_scalar_int(tcx, variant_idx.as_u32().into());
3298            ty::ValTree::from_branches(tcx, [ty::Const::new_value(tcx, discr, tcx.types.u32)])
3299        } else {
3300            ty::ValTree::zst(tcx)
3301        };
3302
3303        let adt_ty = Ty::new_adt(tcx, adt_def, args);
3304        ty::Const::new_value(tcx, valtree, adt_ty)
3305    }
3306}