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