rustc_hir_analysis/hir_ty_lowering/
mod.rs

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