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