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