rustc_hir_analysis/hir_ty_lowering/
mod.rs

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