rustc_hir_analysis/hir_ty_lowering/
mod.rs

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