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