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