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