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