Skip to main content

hir_ty/
lower.rs

1//! Methods for lowering the HIR to types. There are two main cases here:
2//!
3//!  - Lowering a type reference like `&usize` or `Option<foo::bar::Baz>` to a
4//!    type: The entry point for this is `TyLoweringContext::lower_ty`.
5//!  - Building the type for an item: This happens through the `ty` query.
6//!
7//! This usually involves resolving names, collecting generic arguments etc.
8pub(crate) mod diagnostics;
9pub(crate) mod path;
10
11use std::{cell::OnceCell, iter, mem, sync::OnceLock};
12
13use base_db::salsa::update_fallback_db;
14use either::Either;
15use hir_def::{
16    AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, EnumId, EnumVariantId,
17    ExpressionStoreOwnerId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId,
18    ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
19    TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, VariantId,
20    builtin_type::BuiltinType,
21    expr_store::{ExpressionStore, path::Path},
22    hir::{
23        ExprId, PatId,
24        generics::{
25            GenericParamDataRef, GenericParams, LocalTypeOrConstParamId, TypeOrConstParamData,
26            TypeParamProvenance, WherePredicate,
27        },
28    },
29    item_tree::FieldsShape,
30    lang_item::LangItems,
31    resolver::{HasResolver, LifetimeNs, Resolver, TypeNs},
32    signatures::{
33        ConstSignature, FunctionSignature, ImplSignature, StaticSignature, StructSignature,
34        TraitFlags, TraitSignature, TypeAliasFlags, TypeAliasSignature,
35    },
36    type_ref::{
37        ConstRef, FnType, LifetimeRef, LifetimeRefId, PathId, TraitBoundModifier,
38        TraitRef as HirTraitRef, TypeBound, TypeRef, TypeRefId,
39    },
40};
41use hir_expand::name::Name;
42use la_arena::{Arena, ArenaMap, Idx};
43use path::{PathDiagnosticCallback, PathLoweringContext};
44use rustc_abi::ExternAbi;
45use rustc_ast_ir::Mutability;
46use rustc_hash::FxHashSet;
47use rustc_type_ir::{
48    AliasTyKind, BoundRegion, BoundRegionKind, BoundTyKind, BoundVar, BoundVariableKind,
49    DebruijnIndex, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig,
50    Interner, OutlivesPredicate, TermKind, TyKind, TypeFoldable, TypeVisitableExt, Upcast,
51    UpcastFrom, elaborate,
52    inherent::{Clause as _, GenericArgs as _, IntoKind as _, Region as _, Ty as _},
53};
54use salsa::Update;
55use smallvec::SmallVec;
56use stdx::{impl_from, never};
57use thin_vec::ThinVec;
58use tracing::debug;
59
60pub use hir_def::LoweringMode;
61pub(crate) use hir_def::TrackedStructToken;
62
63use crate::{
64    ImplTraitId, Span, TyLoweringDiagnostic,
65    consteval::{create_anon_const, path_to_const},
66    db::{AnonConstId, GeneralConstId, HirDatabase, InternedOpaqueTyId},
67    generics::{Generics, SingleGenerics, generics},
68    infer::unify::InferenceTable,
69    next_solver::{
70        AliasTy, Binder, BoundExistentialPredicates, BoundVarKinds, Clause, ClauseKind, Clauses,
71        Const, ConstKind, DbInterner, DefaultAny, EarlyBinder, EarlyParamRegion, ErrorGuaranteed,
72        FnSigKind, FxIndexMap, GenericArg, GenericArgs, ParamConst, ParamEnv, PatList, Pattern,
73        PolyFnSig, Predicate, Region, StoredClauses, StoredConst, StoredEarlyBinder,
74        StoredGenericArg, StoredGenericArgs, StoredPolyFnSig, StoredTraitRef, StoredTy,
75        TraitPredicate, TraitRef, Ty, Tys, Unnormalized, abi::Safety, mk_param,
76        util::BottomUpFolder,
77    },
78};
79
80pub(crate) struct PathDiagnosticCallbackData(pub(crate) TypeRefId);
81
82#[derive(PartialEq, Eq, Debug, Hash)]
83pub struct ImplTraits {
84    pub(crate) impl_traits: Arena<ImplTrait>,
85}
86
87#[derive(PartialEq, Eq, Debug, Hash)]
88pub struct ImplTrait {
89    pub(crate) predicates: StoredClauses,
90    pub(crate) assoc_ty_bounds_start: u32,
91}
92
93pub type ImplTraitIdx = Idx<ImplTrait>;
94
95#[derive(Debug, Default)]
96struct ImplTraitLoweringState {
97    /// When turning `impl Trait` into opaque types, we have to collect the
98    /// bounds at the same time to get the IDs correct (without becoming too
99    /// complicated).
100    mode: ImplTraitLoweringMode,
101    // This is structured as a struct with fields and not as an enum because it helps with the borrow checker.
102    opaque_type_data: Arena<ImplTrait>,
103}
104
105impl ImplTraitLoweringState {
106    fn new(mode: ImplTraitLoweringMode) -> ImplTraitLoweringState {
107        Self { mode, opaque_type_data: Arena::new() }
108    }
109}
110
111#[derive(Debug, Clone, Copy)]
112pub enum LifetimeElisionKind<'db> {
113    /// Create a new anonymous lifetime parameter and reference it.
114    ///
115    /// If `report_in_path`, report an error when encountering lifetime elision in a path:
116    /// ```compile_fail
117    /// struct Foo<'a> { x: &'a () }
118    /// async fn foo(x: Foo) {}
119    /// ```
120    ///
121    /// Note: the error should not trigger when the elided lifetime is in a pattern or
122    /// expression-position path:
123    /// ```
124    /// struct Foo<'a> { x: &'a () }
125    /// async fn foo(Foo { x: _ }: Foo<'_>) {}
126    /// ```
127    AnonymousCreateParameter { report_in_path: bool },
128
129    /// Replace all anonymous lifetimes by provided lifetime.
130    Elided(Region<'db>),
131
132    /// Give a hard error when either `&` or `'_` is written. Used to
133    /// rule out things like `where T: Foo<'_>`. Does not imply an
134    /// error on default object bounds (e.g., `Box<dyn Foo>`).
135    AnonymousReportError,
136
137    /// Resolves elided lifetimes to `'static` if there are no other lifetimes in scope,
138    /// otherwise give a warning that the previous behavior of introducing a new early-bound
139    /// lifetime is a bug and will be removed (if `only_lint` is enabled).
140    StaticIfNoLifetimeInScope { only_lint: bool },
141
142    /// Signal we cannot find which should be the anonymous lifetime.
143    ElisionFailure,
144
145    /// Infer all elided lifetimes.
146    Infer,
147}
148
149impl<'db> LifetimeElisionKind<'db> {
150    #[inline]
151    pub(crate) fn for_const(
152        interner: DbInterner<'db>,
153        const_parent: ItemContainerId,
154    ) -> LifetimeElisionKind<'db> {
155        match const_parent {
156            ItemContainerId::ExternBlockId(_) | ItemContainerId::ModuleId(_) => {
157                LifetimeElisionKind::Elided(Region::new_static(interner))
158            }
159            ItemContainerId::ImplId(_) => {
160                LifetimeElisionKind::StaticIfNoLifetimeInScope { only_lint: true }
161            }
162            ItemContainerId::TraitId(_) => {
163                LifetimeElisionKind::StaticIfNoLifetimeInScope { only_lint: false }
164            }
165        }
166    }
167
168    #[inline]
169    pub(crate) fn for_fn_params(data: &FunctionSignature) -> LifetimeElisionKind<'db> {
170        LifetimeElisionKind::AnonymousCreateParameter { report_in_path: data.is_async() }
171    }
172
173    #[inline]
174    pub(crate) fn for_fn_ret(interner: DbInterner<'db>) -> LifetimeElisionKind<'db> {
175        // FIXME: We should use the elided lifetime here, or `ElisionFailure`.
176        LifetimeElisionKind::Elided(Region::error(interner))
177    }
178}
179
180#[derive(Clone, Copy, PartialEq, Debug)]
181pub(crate) enum GenericPredicateSource {
182    SelfOnly,
183    AssocTyBound,
184}
185
186#[derive(Debug, Clone, Copy, PartialEq, Eq)]
187pub(crate) enum ForbidParamsAfterReason {
188    /// When lowering generic param defaults, you cannot refer to any param after
189    /// the currently lowered param, including the current param.
190    LoweringParamDefault,
191    /// Most anon const (except array repeat expressions) cannot refer to any generic
192    /// param.
193    AnonConst,
194    /// The type of a const param cannot refer to a type param.
195    ConstParamTy,
196}
197
198pub trait TyLoweringInferVarsCtx<'db> {
199    fn next_ty_var(&mut self, span: Span) -> Ty<'db>;
200    fn next_const_var(&mut self, span: Span) -> Const<'db>;
201    fn next_region_var(&mut self, span: Span) -> Region<'db>;
202
203    #[expect(private_interfaces)]
204    fn as_table(&mut self) -> Option<&mut InferenceTable<'db>> {
205        None
206    }
207}
208
209pub struct TyLoweringContext<'db, 'a> {
210    pub db: &'db dyn HirDatabase,
211    pub(crate) interner: DbInterner<'db>,
212    types: &'db crate::next_solver::DefaultAny<'db>,
213    lang_items: &'db LangItems,
214    resolver: &'a Resolver<'db>,
215    store: &'db ExpressionStore,
216    def: ExpressionStoreOwnerId,
217    generic_def: GenericDefId,
218    generics: &'a OnceCell<Generics<'db>>,
219    in_binders: DebruijnIndex,
220    impl_trait_mode: ImplTraitLoweringState,
221    interning_mode: LoweringMode,
222    /// Tracks types with explicit `?Sized` bounds.
223    pub(crate) unsized_types: FxHashSet<Ty<'db>>,
224    pub(crate) diagnostics: ThinVec<TyLoweringDiagnostic>,
225    lifetime_elision: LifetimeElisionKind<'db>,
226    forbid_params_after: Option<u32>,
227    forbid_params_after_reason: ForbidParamsAfterReason,
228    pub(crate) defined_anon_consts: ThinVec<AnonConstId<'db>>,
229    infer_vars: Option<&'a mut dyn TyLoweringInferVarsCtx<'db>>,
230    is_lowering_impl_trait_bounds: bool,
231    bound_vars: Vec<(Vec<Name>, BoundVarKinds<'db>)>,
232    lifetime_lowering_mode: LifetimeLoweringMode,
233}
234
235impl<'db, 'a> TyLoweringContext<'db, 'a> {
236    pub fn new(
237        db: &'db dyn HirDatabase,
238        resolver: &'a Resolver<'db>,
239        store: &'db ExpressionStore,
240        def: ExpressionStoreOwnerId,
241        generic_def: GenericDefId,
242        generics: &'a OnceCell<Generics<'db>>,
243        lifetime_elision: LifetimeElisionKind<'db>,
244        lifetime_lowering_mode: LifetimeLoweringMode,
245    ) -> Self {
246        let impl_trait_mode = ImplTraitLoweringState::new(ImplTraitLoweringMode::Disallowed);
247        let in_binders = DebruijnIndex::ZERO;
248        let interner = DbInterner::new_with(db, resolver.krate());
249        let bound_vars =
250            vec![(Vec::new(), TyLoweringContext::bound_vars(db, interner, generic_def, generics))];
251        Self {
252            db,
253            // Can provide no block since we don't use it for trait solving.
254            interner,
255            types: crate::next_solver::default_types(db),
256            lang_items: interner.lang_items(),
257            resolver,
258            def,
259            generic_def,
260            generics,
261            store,
262            in_binders,
263            impl_trait_mode,
264            interning_mode: LoweringMode::Analysis,
265            unsized_types: FxHashSet::default(),
266            diagnostics: ThinVec::new(),
267            lifetime_elision,
268            forbid_params_after: None,
269            forbid_params_after_reason: ForbidParamsAfterReason::AnonConst,
270            defined_anon_consts: ThinVec::new(),
271            infer_vars: None,
272            is_lowering_impl_trait_bounds: false,
273            bound_vars,
274            lifetime_lowering_mode,
275        }
276    }
277
278    pub(crate) fn set_lifetime_elision(&mut self, lifetime_elision: LifetimeElisionKind<'db>) {
279        self.lifetime_elision = lifetime_elision;
280    }
281
282    pub(crate) fn set_owner(&mut self, owner: &'a SingleGenerics<'db>) {
283        self.store = owner.store();
284        self.def = ExpressionStoreOwnerId::Signature(owner.def());
285    }
286
287    pub(crate) fn with_interning_mode(mut self, interning_mode: LoweringMode) -> Self {
288        self.interning_mode = interning_mode;
289        self
290    }
291
292    pub(crate) fn with_debruijn<T>(
293        &mut self,
294        debruijn: DebruijnIndex,
295        f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> T,
296    ) -> T {
297        let old_debruijn = mem::replace(&mut self.in_binders, debruijn);
298        let result = f(self);
299        self.in_binders = old_debruijn;
300        result
301    }
302
303    pub(crate) fn with_shifted_in<T>(
304        &mut self,
305        binder: &[Name],
306        f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> T,
307    ) -> (T, BoundVarKinds<'db>) {
308        self.push_bound_vars(binder);
309        let res = self.with_debruijn(self.in_binders.shifted_in(1), f);
310        let bound_vars = self.pop_bound_vars();
311        (res, bound_vars)
312    }
313
314    pub(crate) fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
315        Self { impl_trait_mode: ImplTraitLoweringState::new(impl_trait_mode), ..self }
316    }
317
318    pub(crate) fn impl_trait_mode(&mut self, impl_trait_mode: ImplTraitLoweringMode) -> &mut Self {
319        self.impl_trait_mode = ImplTraitLoweringState::new(impl_trait_mode);
320        self
321    }
322
323    pub(crate) fn forbid_params_after(&mut self, index: u32, reason: ForbidParamsAfterReason) {
324        self.forbid_params_after = Some(index);
325        self.forbid_params_after_reason = reason;
326    }
327
328    pub fn with_infer_vars_behavior(
329        mut self,
330        behavior: Option<&'a mut dyn TyLoweringInferVarsCtx<'db>>,
331    ) -> Self {
332        self.infer_vars = behavior;
333        self
334    }
335
336    pub(crate) fn push_diagnostic(&mut self, diagnostic: TyLoweringDiagnostic) {
337        self.diagnostics.push(diagnostic);
338    }
339
340    fn push_infer_vars_not_allowed(&mut self, span: Span) {
341        if !span.is_dummy() {
342            self.push_diagnostic(TyLoweringDiagnostic::InferVarsNotAllowed { source: span });
343        }
344    }
345
346    #[track_caller]
347    pub(crate) fn expect_table(&mut self) -> &mut InferenceTable<'db> {
348        self.infer_vars.as_mut().unwrap().as_table().unwrap()
349    }
350
351    fn next_ty_var(&mut self, span: Span) -> Ty<'db> {
352        match &mut self.infer_vars {
353            Some(infer_vars) => infer_vars.next_ty_var(span),
354            None => {
355                self.push_infer_vars_not_allowed(span);
356                self.types.types.error
357            }
358        }
359    }
360
361    fn next_const_var(&mut self, span: Span) -> Const<'db> {
362        match &mut self.infer_vars {
363            Some(infer_vars) => infer_vars.next_const_var(span),
364            None => {
365                self.push_infer_vars_not_allowed(span);
366                self.types.consts.error
367            }
368        }
369    }
370
371    fn next_region_var(&mut self, span: Span) -> Region<'db> {
372        match &mut self.infer_vars {
373            Some(infer_vars) => infer_vars.next_region_var(span),
374            None => {
375                self.push_infer_vars_not_allowed(span);
376                self.types.regions.error
377            }
378        }
379    }
380
381    fn push_bound_vars(&mut self, binder: &[Name]) {
382        let bound_vars = BoundVarKinds::new_from_iter(
383            self.interner,
384            binder.iter().map(|_| {
385                BoundVariableKind::Region(BoundRegionKind::Named(self.generic_def.into()))
386            }),
387        );
388        self.bound_vars.push((binder.to_vec(), bound_vars));
389    }
390
391    fn pop_bound_vars(&mut self) -> BoundVarKinds<'db> {
392        self.bound_vars.pop().unwrap().1
393    }
394
395    fn peek_bound_vars(&self) -> BoundVarKinds<'db> {
396        self.bound_vars.last().unwrap().1
397    }
398
399    fn bound_vars(
400        db: &'db dyn HirDatabase,
401        interner: DbInterner<'db>,
402        def: GenericDefId,
403        generic: &'a OnceCell<Generics<'db>>,
404    ) -> BoundVarKinds<'db> {
405        let def_id = def.into();
406
407        let generics = generic.get_or_init(|| generics(db, def));
408        let args = generics.iter_self_late_bound().map(|(_, data)| match data {
409            GenericParamDataRef::TypeParamData(..) => {
410                BoundVariableKind::Ty(BoundTyKind::Param(def_id))
411            }
412            GenericParamDataRef::ConstParamData(..) => BoundVariableKind::Const,
413            GenericParamDataRef::LifetimeParamData(..) => {
414                BoundVariableKind::Region(BoundRegionKind::Named(def_id))
415            }
416        });
417
418        BoundVarKinds::new_from_iter(interner, args)
419    }
420}
421
422#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
423pub(crate) enum ImplTraitLoweringMode {
424    /// `impl Trait` gets lowered into an opaque type that doesn't unify with
425    /// anything except itself. This is used in places where values flow 'out',
426    /// i.e. for arguments of the function we're currently checking, and return
427    /// types of functions we're calling.
428    Opaque,
429    /// `impl Trait` is disallowed and will be an error.
430    #[default]
431    Disallowed,
432}
433
434#[derive(Clone, Debug, PartialEq, Eq)]
435pub enum LifetimeLoweringMode {
436    /// Lowers the late bound lifetimes to `ReBound`, used in cases when lowering
437    /// from outside of function.
438    Bound,
439    /// Lowers the late bound lifetimes to `ReLateParam`, used in cases when lowering
440    /// inside the function itself
441    LateParam,
442}
443
444impl<'db, 'a> TyLoweringContext<'db, 'a> {
445    pub fn lower_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> {
446        self.lower_ty_ext(type_ref).0
447    }
448
449    pub(crate) fn lower_const(&mut self, const_ref: ConstRef, const_type: Ty<'db>) -> Const<'db> {
450        self.lower_expr_as_const(const_ref.expr, const_type)
451    }
452
453    pub(crate) fn lower_expr_as_const(
454        &mut self,
455        expr_id: ExprId,
456        const_type: Ty<'db>,
457    ) -> Const<'db> {
458        #[expect(clippy::manual_map, reason = "a `map()` here generates a borrowck error")]
459        let create_var = match &mut self.infer_vars {
460            Some(infer_vars) => Some(
461                (&mut |span| infer_vars.next_const_var(span)) as &mut dyn FnMut(Span) -> Const<'db>,
462            ),
463            None => None,
464        };
465        let konst = create_anon_const(
466            self.interner,
467            self.def,
468            self.store,
469            expr_id,
470            self.resolver,
471            const_type,
472            &|| self.generics.get_or_init(|| generics(self.db, self.generic_def)),
473            create_var,
474            self.interning_mode,
475            self.forbid_params_after,
476        );
477
478        if let Ok(konst) = konst
479            && let ConstKind::Unevaluated(konst) = konst.kind()
480            && let GeneralConstId::AnonConstId(konst) = konst.def.0
481        {
482            self.defined_anon_consts.push(konst);
483        }
484
485        konst.unwrap_or({
486            // FIXME: Report an error.
487            self.types.consts.error
488        })
489    }
490
491    pub(crate) fn lower_path_as_const(&mut self, path: &Path, _const_type: Ty<'db>) -> Const<'db> {
492        path_to_const(self.db, self.resolver, &|| self.generics(), self.forbid_params_after, path)
493            .unwrap_or({
494                // FIXME: Report an error.
495                self.types.consts.error
496            })
497    }
498
499    fn generics(&self) -> &Generics<'db> {
500        self.generics.get_or_init(|| generics(self.db, self.generic_def))
501    }
502
503    fn param_index_is_disallowed(&self, index: u32) -> bool {
504        self.forbid_params_after.is_some_and(|disallow_params_after| index >= disallow_params_after)
505    }
506
507    fn type_param(&mut self, id: TypeParamId, index: u32) -> Ty<'db> {
508        if self.param_index_is_disallowed(index) {
509            // FIXME: Report an error.
510            self.types.types.error
511        } else {
512            Ty::new_param(self.interner, id, index)
513        }
514    }
515
516    fn region_param(
517        &mut self,
518        id: LifetimeParamId,
519        index: u32,
520        is_late_bound: bool,
521    ) -> Region<'db> {
522        if self.param_index_is_disallowed(index) {
523            // FIXME: Report an error.
524            self.types.regions.error
525        } else {
526            if is_late_bound {
527                self.hrtb_region_param(
528                    index,
529                    DebruijnIndex::from_usize(self.in_binders.as_usize()),
530                    id.parent,
531                )
532            } else {
533                Region::new_early_param(self.interner, EarlyParamRegion { id, index })
534            }
535        }
536    }
537
538    fn hrtb_region_param(
539        &self,
540        index: u32,
541        debruijn: DebruijnIndex,
542        parent: GenericDefId,
543    ) -> Region<'db> {
544        if self.param_index_is_disallowed(index) {
545            // FIXME: Report an error.
546            self.types.regions.error
547        } else {
548            if self.lifetime_lowering_mode == LifetimeLoweringMode::Bound {
549                Region::new_bound(
550                    self.interner,
551                    debruijn,
552                    BoundRegion {
553                        var: BoundVar::from_u32(index),
554                        kind: BoundRegionKind::Named(parent.into()),
555                    },
556                )
557            } else {
558                let solver_def_id = parent.into();
559                Region::new_late_param(
560                    self.interner,
561                    solver_def_id,
562                    BoundRegion {
563                        var: BoundVar::from_u32(index),
564                        kind: BoundRegionKind::Named(solver_def_id),
565                    },
566                )
567            }
568        }
569    }
570
571    #[tracing::instrument(skip(self), ret)]
572    pub fn lower_ty_ext(&mut self, type_ref_id: TypeRefId) -> (Ty<'db>, Option<TypeNs>) {
573        let interner = self.interner;
574        let mut res = None;
575        let type_ref = &self.store[type_ref_id];
576        tracing::debug!(?type_ref);
577        let ty = match type_ref {
578            TypeRef::Never => self.types.types.never,
579            TypeRef::Tuple(inner) => {
580                let inner_tys = inner.iter().map(|&tr| self.lower_ty(tr));
581                Ty::new_tup_from_iter(interner, inner_tys)
582            }
583            TypeRef::Path(path) => {
584                let (ty, res_) =
585                    self.lower_path(path, PathId::from_type_ref_unchecked(type_ref_id));
586                res = res_;
587                ty
588            }
589            &TypeRef::TypeParam(type_param_id) => {
590                res = Some(TypeNs::GenericParam(type_param_id));
591
592                let generics = self.generics();
593                let idx = generics.type_or_const_param_idx(type_param_id.into());
594                self.type_param(type_param_id, idx)
595            }
596            &TypeRef::RawPtr(inner, mutability) => {
597                let inner_ty = self.lower_ty(inner);
598                Ty::new(interner, TyKind::RawPtr(inner_ty, lower_mutability(mutability)))
599            }
600            TypeRef::Array(array) => {
601                let inner_ty = self.lower_ty(array.ty);
602                let const_len = self.lower_const(array.len, self.types.types.usize);
603                Ty::new_array_with_const_len(interner, inner_ty, const_len)
604            }
605            &TypeRef::Slice(inner) => {
606                let inner_ty = self.lower_ty(inner);
607                Ty::new_slice(interner, inner_ty)
608            }
609            TypeRef::Reference(ref_) => {
610                let inner_ty = self.lower_ty(ref_.ty);
611                // FIXME: It should infer the eldided lifetimes instead of stubbing with error
612                let lifetime =
613                    ref_.lifetime.map_or(self.types.regions.error, |lr| self.lower_lifetime(lr));
614                Ty::new_ref(interner, lifetime, inner_ty, lower_mutability(ref_.mutability))
615            }
616            TypeRef::Placeholder => self.next_ty_var(type_ref_id.into()),
617            TypeRef::Fn(fn_) => self.lower_fn_ptr(fn_),
618            TypeRef::DynTrait(bounds) => self.lower_dyn_trait(bounds),
619            TypeRef::ImplTrait(bounds) => {
620                match self.impl_trait_mode.mode {
621                    ImplTraitLoweringMode::Opaque => {
622                        let origin = match self.resolver.generic_def() {
623                            Some(GenericDefId::FunctionId(it)) => Either::Left(it),
624                            Some(GenericDefId::TypeAliasId(it)) => Either::Right(it),
625                            _ => panic!(
626                                "opaque impl trait lowering must be in function or type alias"
627                            ),
628                        };
629
630                        // this dance is to make sure the data is in the right
631                        // place even if we encounter more opaque types while
632                        // lowering the bounds
633                        let idx = self.impl_trait_mode.opaque_type_data.alloc(ImplTrait {
634                            predicates: Clauses::empty(interner).store(),
635                            assoc_ty_bounds_start: 0,
636                        });
637
638                        let impl_trait_id = origin.either(
639                            |f| ImplTraitId::ReturnTypeImplTrait(f, idx),
640                            |a| ImplTraitId::TypeAliasImplTrait(a, idx),
641                        );
642                        let opaque_ty_id = InternedOpaqueTyId::new(self.db, impl_trait_id);
643
644                        // We don't want to lower the bounds inside the binders
645                        // we're currently in, because they don't end up inside
646                        // those binders. E.g. when we have `impl Trait<impl
647                        // OtherTrait<T>>`, the `impl OtherTrait<T>` can't refer
648                        // to the self parameter from `impl Trait`, and the
649                        // bounds aren't actually stored nested within each
650                        // other, but separately. So if the `T` refers to a type
651                        // parameter of the outer function, it's just one binder
652                        // away instead of two.
653                        let actual_opaque_type_data = self
654                            .with_debruijn(DebruijnIndex::ZERO, |ctx| {
655                                ctx.lower_impl_trait(opaque_ty_id, bounds)
656                            });
657                        self.impl_trait_mode.opaque_type_data[idx] = actual_opaque_type_data;
658
659                        let mut late_bound_index = 0;
660                        let args = GenericArgs::for_item(
661                            self.interner,
662                            opaque_ty_id.into(),
663                            |index, param_id, lt_param, _| {
664                                if let Some(lt) = lt_param
665                                    && lt.is_late_bound()
666                                    && !self.is_lowering_impl_trait_bounds
667                                {
668                                    let GenericParamId::LifetimeParamId(id) = param_id else {
669                                        unreachable!()
670                                    };
671                                    let bound_region_kind =
672                                        BoundRegionKind::Named(id.parent.into());
673                                    let region = match self.lifetime_lowering_mode {
674                                        LifetimeLoweringMode::Bound => Region::new_bound(
675                                            interner,
676                                            self.in_binders,
677                                            BoundRegion {
678                                                var: BoundVar::from_u32(late_bound_index),
679                                                kind: bound_region_kind,
680                                            },
681                                        ),
682                                        LifetimeLoweringMode::LateParam => Region::new_late_param(
683                                            interner,
684                                            self.generic_def.into(),
685                                            BoundRegion {
686                                                var: BoundVar::from_u32(late_bound_index),
687                                                kind: bound_region_kind,
688                                            },
689                                        ),
690                                    };
691                                    late_bound_index += 1;
692                                    return region.into();
693                                }
694
695                                mk_param(interner, index - late_bound_index, param_id)
696                            },
697                        );
698                        Ty::new_alias(
699                            self.interner,
700                            AliasTy::new_from_args(
701                                self.interner,
702                                AliasTyKind::Opaque { def_id: opaque_ty_id.into() },
703                                args,
704                            ),
705                        )
706                    }
707                    ImplTraitLoweringMode::Disallowed => {
708                        // FIXME: report error
709                        self.types.types.error
710                    }
711                }
712            }
713            &TypeRef::PatternType(ty, pat) => {
714                let ty = self.lower_ty(ty);
715                let Some(pat) = self.lower_pattern_type(pat, ty) else {
716                    return (self.types.types.error, res);
717                };
718                Ty::new_pat(self.interner, ty, pat)
719            }
720            TypeRef::Error => self.types.types.error,
721        };
722        (ty, res)
723    }
724
725    fn lower_pattern_type(&mut self, pat: PatId, ty: Ty<'db>) -> Option<Pattern<'db>> {
726        let pat_kind = match self.store[pat] {
727            hir_def::hir::Pat::Range { start: Some(start), end: Some(end), range_type: _ } => {
728                rustc_type_ir::PatternKind::Range {
729                    start: self.lower_expr_as_const(start, ty),
730                    end: self.lower_expr_as_const(end, ty),
731                }
732            }
733            hir_def::hir::Pat::NotNull => rustc_type_ir::PatternKind::NotNull,
734            hir_def::hir::Pat::Or(ref pats) => rustc_type_ir::PatternKind::Or(
735                PatList::new_from_iter(
736                    self.interner,
737                    pats.iter().map(|&pat| self.lower_pattern_type(pat, ty).ok_or(())),
738                )
739                .ok()?,
740            ),
741            hir_def::hir::Pat::Missing => return None,
742            _ => {
743                never!("pattern type can only be Range, NotNull or Or");
744                return None;
745            }
746        };
747        Some(Pattern::new(self.interner, pat_kind))
748    }
749
750    fn lower_fn_ptr(&mut self, fn_: &FnType) -> Ty<'db> {
751        let interner = self.interner;
752        let (params, ret_ty) = fn_.split_params_and_ret();
753        let old_lifetime_elision = self.lifetime_elision;
754        let mut args = Vec::with_capacity(fn_.params.len());
755        let binder = fn_.binder.as_ref().map(|b| b.as_ref()).unwrap_or_default();
756        let (_, binder) = self.with_shifted_in(binder, |ctx: &mut TyLoweringContext<'_, '_>| {
757            ctx.lifetime_elision =
758                LifetimeElisionKind::AnonymousCreateParameter { report_in_path: false };
759            args.extend(params.iter().map(|&(_, tr)| ctx.lower_ty(tr)));
760            ctx.lifetime_elision = LifetimeElisionKind::for_fn_ret(interner);
761            args.push(ctx.lower_ty(ret_ty));
762        });
763        self.lifetime_elision = old_lifetime_elision;
764
765        Ty::new_fn_ptr(
766            interner,
767            Binder::bind_with_vars(
768                FnSig {
769                    fn_sig_kind: FnSigKind::new(
770                        fn_.abi,
771                        if fn_.is_unsafe { Safety::Unsafe } else { Safety::Safe },
772                        fn_.is_varargs,
773                        // FIXME(splat): handle splatted arguments
774                    ),
775                    inputs_and_output: Tys::new_from_slice(&args),
776                },
777                binder,
778            ),
779        )
780    }
781
782    /// This is only for `generic_predicates_for_param`, where we can't just
783    /// lower the self types of the predicates since that could lead to cycles.
784    /// So we just check here if the `type_ref` resolves to a generic param, and which.
785    fn lower_ty_only_param(&self, type_ref: TypeRefId) -> Option<TypeOrConstParamId> {
786        let type_ref = &self.store[type_ref];
787        let path = match type_ref {
788            TypeRef::Path(path) => path,
789            &TypeRef::TypeParam(idx) => return Some(idx.into()),
790            _ => return None,
791        };
792        if path.type_anchor().is_some() {
793            return None;
794        }
795        if path.segments().len() > 1 {
796            return None;
797        }
798        let resolution = match self.resolver.resolve_path_in_type_ns(self.db, path) {
799            Some((it, None, _)) => it,
800            _ => return None,
801        };
802        match resolution {
803            TypeNs::GenericParam(param_id) => Some(param_id.into()),
804            _ => None,
805        }
806    }
807
808    #[inline]
809    fn on_path_diagnostic_callback<'b>(type_ref: TypeRefId) -> PathDiagnosticCallback<'b, 'db> {
810        PathDiagnosticCallback {
811            data: Either::Left(PathDiagnosticCallbackData(type_ref)),
812            callback: |data, this, diag| {
813                let type_ref = data.as_ref().left().unwrap().0;
814                this.push_diagnostic(TyLoweringDiagnostic::PathDiagnostic {
815                    source: type_ref,
816                    diag,
817                })
818            },
819        }
820    }
821
822    #[inline]
823    fn at_path(&mut self, path_id: PathId) -> PathLoweringContext<'_, 'a, 'db> {
824        PathLoweringContext::new(
825            self,
826            Self::on_path_diagnostic_callback(path_id.type_ref()),
827            &self.store[path_id],
828        )
829    }
830
831    pub(crate) fn lower_path(&mut self, path: &Path, path_id: PathId) -> (Ty<'db>, Option<TypeNs>) {
832        // Resolve the path (in type namespace)
833        if let Some(type_ref) = path.type_anchor() {
834            let (ty, res) = self.lower_ty_ext(type_ref);
835            let mut ctx = self.at_path(path_id);
836            return ctx.lower_ty_relative_path(ty, res, false, path_id.type_ref().into());
837        }
838
839        let mut ctx = self.at_path(path_id);
840        let (resolution, remaining_index) = match ctx.resolve_path_in_type_ns() {
841            Some(it) => it,
842            None => return (self.types.types.error, None),
843        };
844
845        if matches!(resolution, TypeNs::TraitId(_)) && remaining_index.is_none() {
846            // trait object type without dyn
847            let bound = TypeBound::Path(path_id, TraitBoundModifier::None);
848            let ty = self.lower_dyn_trait(&[bound]);
849            return (ty, None);
850        }
851
852        ctx.lower_partly_resolved_path(resolution, false, path_id.type_ref().into())
853    }
854
855    fn lower_trait_ref_from_path(
856        &mut self,
857        path_id: PathId,
858        explicit_self_ty: Ty<'db>,
859    ) -> Option<(TraitRef<'db>, PathLoweringContext<'_, 'a, 'db>)> {
860        let mut ctx = self.at_path(path_id);
861        let resolved = match ctx.resolve_path_in_type_ns_fully()? {
862            // FIXME(trait_alias): We need to handle trait alias here.
863            TypeNs::TraitId(tr) => tr,
864            _ => return None,
865        };
866        Some((
867            ctx.lower_trait_ref_from_resolved_path(
868                resolved,
869                explicit_self_ty,
870                false,
871                path_id.type_ref().into(),
872            ),
873            ctx,
874        ))
875    }
876
877    fn lower_trait_ref(
878        &mut self,
879        trait_ref: &HirTraitRef,
880        explicit_self_ty: Ty<'db>,
881    ) -> Option<TraitRef<'db>> {
882        self.lower_trait_ref_from_path(trait_ref.path, explicit_self_ty).map(|it| it.0)
883    }
884
885    pub(crate) fn lower_where_predicate<'b>(
886        &'b mut self,
887        where_predicate: &'b WherePredicate,
888        ignore_bindings: bool,
889    ) -> impl Iterator<Item = (Clause<'db>, GenericPredicateSource)> + use<'a, 'b, 'db> {
890        let lower_type_outlives = |ctx: &mut TyLoweringContext<'db, '_>,
891                                   target: &TypeRefId,
892                                   bound| {
893            let self_ty = ctx.lower_ty(*target);
894            let clause = ctx.lower_type_bound(bound, self_ty, ignore_bindings).collect::<Vec<_>>();
895            Either::Left(clause.into_iter())
896        };
897
898        match where_predicate {
899            WherePredicate::TypeBound { lifetimes, target, bound } => match lifetimes {
900                Some(lifetimes) => {
901                    self.with_shifted_in(lifetimes, |ctx| lower_type_outlives(ctx, target, bound)).0
902                }
903                None => lower_type_outlives(self, target, bound),
904            },
905            &WherePredicate::Lifetime { bound, target } => Either::Right(iter::once((
906                Clause(Predicate::new(
907                    self.interner,
908                    Binder::dummy(rustc_type_ir::PredicateKind::Clause(
909                        rustc_type_ir::ClauseKind::RegionOutlives(OutlivesPredicate(
910                            self.lower_lifetime(bound),
911                            self.lower_lifetime(target),
912                        )),
913                    )),
914                )),
915                GenericPredicateSource::SelfOnly,
916            ))),
917        }
918        .into_iter()
919    }
920
921    pub(crate) fn lower_type_bound<'b>(
922        &'b mut self,
923        bound: &'b TypeBound,
924        self_ty: Ty<'db>,
925        ignore_bindings: bool,
926    ) -> impl Iterator<Item = (Clause<'db>, GenericPredicateSource)> + use<'b, 'a, 'db> {
927        let interner = self.interner;
928        let meta_sized = self.lang_items.MetaSized;
929        let pointee_sized = self.lang_items.PointeeSized;
930
931        let mut assoc_bounds = None;
932        let mut clause = None;
933
934        let mut lower_path_bound = |ctx: &mut TyLoweringContext<'db, '_>, path| {
935            let binder = ctx.peek_bound_vars();
936
937            if let Some((trait_ref, mut ctx)) = ctx.lower_trait_ref_from_path(path, self_ty) {
938                // FIXME(sized-hierarchy): Remove this bound modifications once we have implemented
939                // sized-hierarchy correctly.
940                if meta_sized.is_some_and(|it| it == trait_ref.def_id.0) {
941                    // Ignore this bound
942                } else if pointee_sized.is_some_and(|it| it == trait_ref.def_id.0) {
943                    // Regard this as `?Sized` bound
944                    ctx.ty_ctx().unsized_types.insert(self_ty);
945                } else {
946                    if !ignore_bindings {
947                        assoc_bounds = ctx
948                            .assoc_type_bindings_from_type_bound(trait_ref, path.type_ref().into())
949                            .map(|iter| iter.collect::<Vec<_>>());
950                    }
951                    clause = Some(Clause(Predicate::new(
952                        interner,
953                        Binder::bind_with_vars(
954                            rustc_type_ir::PredicateKind::Clause(rustc_type_ir::ClauseKind::Trait(
955                                TraitPredicate {
956                                    trait_ref,
957                                    polarity: rustc_type_ir::PredicatePolarity::Positive,
958                                },
959                            )),
960                            binder,
961                        ),
962                    )));
963                }
964            }
965        };
966
967        match bound {
968            &TypeBound::ForLifetime(ref binder, path) => {
969                self.with_shifted_in(binder, |ctx| lower_path_bound(ctx, path)).0
970            }
971            &TypeBound::Path(path, TraitBoundModifier::None) => lower_path_bound(self, path),
972            &TypeBound::Path(path, TraitBoundModifier::Maybe) => {
973                let sized_trait = self.lang_items.Sized;
974                // Don't lower associated type bindings as the only possible relaxed trait bound
975                // `?Sized` has no of them.
976                // If we got another trait here ignore the bound completely.
977                let trait_id = self
978                    .lower_trait_ref_from_path(path, self_ty)
979                    .map(|(trait_ref, _)| trait_ref.def_id.0);
980                if trait_id == sized_trait {
981                    self.unsized_types.insert(self_ty);
982                }
983            }
984            &TypeBound::Lifetime(l) => {
985                let lifetime = self.lower_lifetime(l);
986                let binder = self.peek_bound_vars();
987                clause = Some(Clause(Predicate::new(
988                    self.interner,
989                    Binder::bind_with_vars(
990                        rustc_type_ir::PredicateKind::Clause(
991                            rustc_type_ir::ClauseKind::TypeOutlives(OutlivesPredicate(
992                                self_ty, lifetime,
993                            )),
994                        ),
995                        binder,
996                    ),
997                )));
998            }
999            TypeBound::Use(_) | TypeBound::Error => {}
1000        }
1001        clause
1002            .into_iter()
1003            .map(|pred| (pred, GenericPredicateSource::SelfOnly))
1004            .chain(assoc_bounds.into_iter().flatten())
1005    }
1006
1007    fn lower_dyn_trait(&mut self, bounds: &[TypeBound]) -> Ty<'db> {
1008        let interner = self.interner;
1009        let dummy_self_ty = self.types.types.dyn_trait_dummy_self;
1010        let mut region = None;
1011        // INVARIANT: The principal trait bound, if present, must come first. Others may be in any
1012        // order but should be in the same order for the same set but possibly different order of
1013        // bounds in the input.
1014        // INVARIANT: If this function returns `DynTy`, there should be at least one trait bound.
1015        // These invariants are utilized by `TyExt::dyn_trait()` and chalk.
1016        let bounds = 'bounds: {
1017            let mut principal = None;
1018            let mut auto_traits = SmallVec::<[_; 3]>::new();
1019            let mut projections = Vec::new();
1020            let mut had_error = false;
1021
1022            for b in bounds {
1023                let db = self.db;
1024                self.lower_type_bound(b, dummy_self_ty, false).for_each(|(b, _)| {
1025                    match b.kind().skip_binder() {
1026                        rustc_type_ir::ClauseKind::Trait(t) => {
1027                            let id = t.def_id();
1028                            let is_auto =
1029                                TraitSignature::of(db, id.0).flags.contains(TraitFlags::AUTO);
1030                            if is_auto {
1031                                auto_traits.push(t.def_id().0);
1032                            } else {
1033                                if principal.is_some() {
1034                                    // FIXME: Report an error.
1035                                    had_error = true;
1036                                }
1037                                principal = Some(b.kind().rebind(t.trait_ref));
1038                            }
1039                        }
1040                        rustc_type_ir::ClauseKind::Projection(p) => {
1041                            projections.push(b.kind().rebind(p));
1042                        }
1043                        rustc_type_ir::ClauseKind::TypeOutlives(outlives_predicate) => {
1044                            if region.is_some() {
1045                                // FIXME: Report an error.
1046                                had_error = true;
1047                            }
1048                            region = Some(outlives_predicate.1);
1049                        }
1050                        rustc_type_ir::ClauseKind::RegionOutlives(_)
1051                        | rustc_type_ir::ClauseKind::ConstArgHasType(_, _)
1052                        | rustc_type_ir::ClauseKind::WellFormed(_)
1053                        | rustc_type_ir::ClauseKind::ConstEvaluatable(_)
1054                        | rustc_type_ir::ClauseKind::HostEffect(_)
1055                        | rustc_type_ir::ClauseKind::UnstableFeature(_) => unreachable!(),
1056                    }
1057                })
1058            }
1059
1060            if had_error {
1061                break 'bounds None;
1062            }
1063
1064            if principal.is_none() && auto_traits.is_empty() {
1065                // No traits is not allowed.
1066                break 'bounds None;
1067            }
1068
1069            // `Send + Sync` is the same as `Sync + Send`.
1070            auto_traits.sort_unstable();
1071            // Duplicate auto traits are permitted.
1072            auto_traits.dedup();
1073
1074            // Map the projection bounds onto a key that makes it easy to remove redundant
1075            // bounds that are constrained by supertraits of the principal def id.
1076            //
1077            // Also make sure we detect conflicting bounds from expanding a trait alias and
1078            // also specifying it manually, like:
1079            // ```
1080            // type Alias = Trait<Assoc = i32>;
1081            // let _: &dyn Alias<Assoc = u32> = /* ... */;
1082            // ```
1083            let mut projection_bounds = FxIndexMap::default();
1084            for proj in projections {
1085                let key = (
1086                    proj.skip_binder().def_id().0,
1087                    interner.anonymize_bound_vars(
1088                        proj.map_bound(|proj| proj.projection_term.trait_ref(interner)),
1089                    ),
1090                );
1091                if let Some(old_proj) = projection_bounds.insert(key, proj)
1092                    && interner.anonymize_bound_vars(proj)
1093                        != interner.anonymize_bound_vars(old_proj)
1094                {
1095                    // FIXME: Report "conflicting associated type" error.
1096                }
1097            }
1098
1099            // A stable ordering of associated types from the principal trait and all its
1100            // supertraits. We use this to ensure that different substitutions of a trait
1101            // don't result in `dyn Trait` types with different projections lists, which
1102            // can be unsound: <https://github.com/rust-lang/rust/pull/136458>.
1103            // We achieve a stable ordering by walking over the unsubstituted principal
1104            // trait ref.
1105            let mut ordered_associated_types = vec![];
1106
1107            if let Some(principal_trait) = principal {
1108                // Generally we should not elaborate in lowering as this can lead to cycles, but
1109                // here rustc cycles as well.
1110                for clause in elaborate::elaborate(
1111                    interner,
1112                    [Clause::upcast_from(
1113                        TraitRef::identity(interner, principal_trait.def_id()),
1114                        interner,
1115                    )],
1116                )
1117                .filter_only_self()
1118                {
1119                    let clause = clause.instantiate_supertrait(interner, principal_trait);
1120                    debug!("observing object predicate `{clause:?}`");
1121
1122                    let bound_predicate = clause.kind();
1123                    match bound_predicate.skip_binder() {
1124                        ClauseKind::Trait(pred) => {
1125                            // FIXME(negative_bounds): Handle this correctly...
1126                            let trait_ref = interner
1127                                .anonymize_bound_vars(bound_predicate.rebind(pred.trait_ref));
1128                            ordered_associated_types.extend(
1129                                pred.trait_ref
1130                                    .def_id
1131                                    .0
1132                                    .trait_items(self.db)
1133                                    .associated_types()
1134                                    .map(|item| (item.into(), trait_ref)),
1135                            );
1136                        }
1137                        ClauseKind::Projection(pred) => {
1138                            let pred = bound_predicate.rebind(pred);
1139                            // A `Self` within the original bound will be instantiated with a
1140                            // `trait_object_dummy_self`, so check for that.
1141                            let references_self = match pred.skip_binder().term.kind() {
1142                                TermKind::Ty(ty) => {
1143                                    ty.walk().any(|arg| arg == dummy_self_ty.into())
1144                                }
1145                                // FIXME(mgca): We should walk the const instead of not doing anything
1146                                TermKind::Const(_) => false,
1147                            };
1148
1149                            // If the projection output contains `Self`, force the user to
1150                            // elaborate it explicitly to avoid a lot of complexity.
1151                            //
1152                            // The "classically useful" case is the following:
1153                            // ```
1154                            //     trait MyTrait: FnMut() -> <Self as MyTrait>::MyOutput {
1155                            //         type MyOutput;
1156                            //     }
1157                            // ```
1158                            //
1159                            // Here, the user could theoretically write `dyn MyTrait<MyOutput = X>`,
1160                            // but actually supporting that would "expand" to an infinitely-long type
1161                            // `fix $ τ → dyn MyTrait<MyOutput = X, Output = <τ as MyTrait>::MyOutput`.
1162                            //
1163                            // Instead, we force the user to write
1164                            // `dyn MyTrait<MyOutput = X, Output = X>`, which is uglier but works. See
1165                            // the discussion in #56288 for alternatives.
1166                            if !references_self {
1167                                let key = (
1168                                    pred.skip_binder().def_id().0,
1169                                    interner.anonymize_bound_vars(pred.map_bound(|proj| {
1170                                        proj.projection_term.trait_ref(interner)
1171                                    })),
1172                                );
1173                                if !projection_bounds.contains_key(&key) {
1174                                    projection_bounds.insert(key, pred);
1175                                }
1176                            }
1177                        }
1178                        _ => (),
1179                    }
1180                }
1181            }
1182
1183            // We compute the list of projection bounds taking the ordered associated types,
1184            // and check if there was an entry in the collected `projection_bounds`. Those
1185            // are computed by first taking the user-written associated types, then elaborating
1186            // the principal trait ref, and only using those if there was no user-written.
1187            // See note below about how we handle missing associated types with `Self: Sized`,
1188            // which are not required to be provided, but are still used if they are provided.
1189            let mut projection_bounds: Vec<_> = ordered_associated_types
1190                .into_iter()
1191                .filter_map(|key| projection_bounds.get(&key).copied())
1192                .collect();
1193
1194            projection_bounds.sort_unstable_by_key(|proj| proj.skip_binder().def_id().0);
1195
1196            let principal = principal.map(|principal| {
1197                principal.map_bound(|principal| {
1198                    // Verify that `dummy_self` did not leak inside default type parameters.
1199                    let args: Vec<_> = principal
1200                        .args
1201                        .iter()
1202                        // Skip `Self`
1203                        .skip(1)
1204                        .map(|arg| {
1205                            if arg.walk().any(|arg| arg == dummy_self_ty.into()) {
1206                                // FIXME: Report an error.
1207                                self.types.types.error.into()
1208                            } else {
1209                                arg
1210                            }
1211                        })
1212                        .collect();
1213
1214                    ExistentialPredicate::Trait(ExistentialTraitRef::new(
1215                        interner,
1216                        principal.def_id,
1217                        args,
1218                    ))
1219                })
1220            });
1221
1222            let projections = projection_bounds.into_iter().map(|proj| {
1223                proj.map_bound(|mut proj| {
1224                    // Like for trait refs, verify that `dummy_self` did not leak inside default type
1225                    // parameters.
1226                    let references_self = proj.projection_term.args.iter().skip(1).any(|arg| {
1227                        if arg.walk().any(|arg| arg == dummy_self_ty.into()) {
1228                            return true;
1229                        }
1230                        false
1231                    });
1232                    if references_self {
1233                        proj.projection_term = replace_dummy_self_with_error(
1234                            interner,
1235                            self.types,
1236                            proj.projection_term,
1237                        );
1238                    }
1239
1240                    ExistentialPredicate::Projection(ExistentialProjection::erase_self_ty(
1241                        interner, proj,
1242                    ))
1243                })
1244            });
1245
1246            let auto_traits = auto_traits.into_iter().map(|auto_trait| {
1247                Binder::dummy(ExistentialPredicate::AutoTrait(auto_trait.into()))
1248            });
1249
1250            // N.b. principal, projections, auto traits
1251            Some(BoundExistentialPredicates::new_from_iter(
1252                interner,
1253                principal.into_iter().chain(projections).chain(auto_traits),
1254            ))
1255        };
1256
1257        if let Some(bounds) = bounds {
1258            let region = match region {
1259                Some(it) => it,
1260                None => Region::new_static(self.interner),
1261            };
1262            Ty::new_dynamic(self.interner, bounds, region)
1263        } else {
1264            // FIXME: report error
1265            // (additional non-auto traits, associated type rebound, or no resolved trait)
1266            self.types.types.error
1267        }
1268    }
1269
1270    fn lower_impl_trait(
1271        &mut self,
1272        def_id: InternedOpaqueTyId<'db>,
1273        bounds: &[TypeBound],
1274    ) -> ImplTrait {
1275        let interner = self.interner;
1276        cov_mark::hit!(lower_rpit);
1277        let args = GenericArgs::identity_for_item(interner, def_id.into());
1278        let self_ty = Ty::new_alias(
1279            self.interner,
1280            AliasTy::new_from_args(interner, rustc_type_ir::Opaque { def_id: def_id.into() }, args),
1281        );
1282        let prev_is_lowering_impl_trait_bounds =
1283            mem::replace(&mut self.is_lowering_impl_trait_bounds, true);
1284
1285        let mut predicates = Vec::new();
1286        let mut assoc_ty_bounds = Vec::new();
1287        for b in bounds {
1288            for (pred, source) in self.lower_type_bound(b, self_ty, false) {
1289                match source {
1290                    GenericPredicateSource::SelfOnly => predicates.push(pred),
1291                    GenericPredicateSource::AssocTyBound => assoc_ty_bounds.push(pred),
1292                }
1293            }
1294        }
1295
1296        if !self.unsized_types.contains(&self_ty) {
1297            let sized_trait = self.lang_items.Sized;
1298            let sized_clause = sized_trait.map(|trait_id| {
1299                let trait_ref = TraitRef::new_from_args(
1300                    interner,
1301                    trait_id.into(),
1302                    GenericArgs::new_from_slice(&[self_ty.into()]),
1303                );
1304                Clause(Predicate::new(
1305                    interner,
1306                    Binder::dummy(rustc_type_ir::PredicateKind::Clause(
1307                        rustc_type_ir::ClauseKind::Trait(TraitPredicate {
1308                            trait_ref,
1309                            polarity: rustc_type_ir::PredicatePolarity::Positive,
1310                        }),
1311                    )),
1312                ))
1313            });
1314            predicates.extend(sized_clause);
1315        }
1316
1317        let assoc_ty_bounds_start = predicates.len() as u32;
1318        predicates.extend(assoc_ty_bounds);
1319
1320        self.is_lowering_impl_trait_bounds = prev_is_lowering_impl_trait_bounds;
1321        ImplTrait {
1322            predicates: Clauses::new_from_slice(&predicates).store(),
1323            assoc_ty_bounds_start,
1324        }
1325    }
1326
1327    pub(crate) fn lower_lifetime(&mut self, lifetime: LifetimeRefId) -> Region<'db> {
1328        if let Some(region) = self.find_and_lower_hrtb_lifetime(lifetime) {
1329            return region;
1330        };
1331
1332        match self.resolver.resolve_lifetime(&self.store[lifetime]) {
1333            Some(resolution) => match resolution {
1334                LifetimeNs::Static => Region::new_static(self.interner),
1335                LifetimeNs::LifetimeParam(id) => {
1336                    let (idx, is_late_bound) =
1337                        self.generics().lifetime_param_idx(id, self.is_lowering_impl_trait_bounds);
1338                    self.region_param(id, idx, is_late_bound)
1339                }
1340            },
1341            None => Region::error(self.interner),
1342        }
1343    }
1344
1345    fn find_and_lower_hrtb_lifetime(&mut self, lifetime: LifetimeRefId) -> Option<Region<'db>> {
1346        if let LifetimeRef::Named(lt_name) = &self.store[lifetime] {
1347            self.bound_vars.iter().rev().enumerate().find_map(|(debruijn, (binder, _))| {
1348                binder.iter().enumerate().find_map(|(index, l)| {
1349                    (l == lt_name).then(|| {
1350                        self.hrtb_region_param(
1351                            index as u32,
1352                            DebruijnIndex::from_usize(debruijn),
1353                            self.generic_def,
1354                        )
1355                    })
1356                })
1357            })
1358        } else {
1359            None
1360        }
1361    }
1362}
1363
1364#[derive(Clone, PartialEq, Eq, Update)]
1365pub struct TyLoweringResult<'db, T> {
1366    #[update(fallback)]
1367    pub value: T,
1368    #[update(bounds(TyLoweringResultInfo<'db>: Update), unsafe(with(update_fallback_db::<'db, _>)))]
1369    info: Option<Box<TyLoweringResultInfo<'db>>>,
1370}
1371
1372#[derive(Clone, PartialEq, Eq, Update)]
1373struct TyLoweringResultInfo<'db> {
1374    diagnostics: ThinVec<TyLoweringDiagnostic>,
1375    anon_consts: ThinVec<AnonConstId<'db>>,
1376}
1377
1378impl<T: std::fmt::Debug> std::fmt::Debug for TyLoweringResult<'_, T> {
1379    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1380        let mut debug = f.debug_struct("TyLoweringResult");
1381        debug.field("value", &self.value);
1382        let diagnostics = self.diagnostics();
1383        if !diagnostics.is_empty() {
1384            debug.field("diagnostics", &diagnostics);
1385        }
1386        let defined_anon_consts = self.defined_anon_consts();
1387        if !defined_anon_consts.is_empty() {
1388            debug.field("defined_anon_consts", &defined_anon_consts);
1389        }
1390        debug.finish()
1391    }
1392}
1393
1394impl<'db, T> TyLoweringResult<'db, T> {
1395    fn new(
1396        value: T,
1397        mut diagnostics: ThinVec<TyLoweringDiagnostic>,
1398        mut defined_anon_consts: ThinVec<AnonConstId<'db>>,
1399    ) -> Self {
1400        let info = if diagnostics.is_empty() && defined_anon_consts.is_empty() {
1401            None
1402        } else {
1403            diagnostics.shrink_to_fit();
1404            defined_anon_consts.shrink_to_fit();
1405            Some(Box::new(TyLoweringResultInfo { diagnostics, anon_consts: defined_anon_consts }))
1406        };
1407        Self { value, info }
1408    }
1409
1410    fn from_ctx(value: T, ctx: TyLoweringContext<'db, '_>) -> Self {
1411        Self::new(value, ctx.diagnostics, ctx.defined_anon_consts)
1412    }
1413
1414    fn empty(value: T) -> Self {
1415        Self { value, info: None }
1416    }
1417
1418    #[inline]
1419    pub fn diagnostics(&self) -> &[TyLoweringDiagnostic] {
1420        match &self.info {
1421            Some(info) => &info.diagnostics,
1422            None => &[],
1423        }
1424    }
1425
1426    #[inline]
1427    pub fn defined_anon_consts(&self) -> &[AnonConstId<'db>] {
1428        match &self.info {
1429            Some(info) => &info.anon_consts,
1430            None => &[],
1431        }
1432    }
1433}
1434
1435fn replace_dummy_self_with_error<'db, T: TypeFoldable<DbInterner<'db>>>(
1436    interner: DbInterner<'db>,
1437    types: &DefaultAny<'db>,
1438    t: T,
1439) -> T {
1440    t.fold_with(&mut BottomUpFolder {
1441        interner,
1442        ty_op: |ty| {
1443            if ty == types.types.dyn_trait_dummy_self { types.types.error } else { ty }
1444        },
1445        lt_op: |lt| lt,
1446        ct_op: |ct| ct,
1447    })
1448}
1449
1450pub(crate) fn lower_mutability(m: hir_def::type_ref::Mutability) -> Mutability {
1451    match m {
1452        hir_def::type_ref::Mutability::Shared => Mutability::Not,
1453        hir_def::type_ref::Mutability::Mut => Mutability::Mut,
1454    }
1455}
1456
1457pub(crate) fn impl_trait_query<'db>(
1458    db: &'db dyn HirDatabase,
1459    impl_id: ImplId,
1460) -> Option<EarlyBinder<'db, TraitRef<'db>>> {
1461    impl_trait_with_diagnostics(db, impl_id)
1462        .as_ref()
1463        .map(|it| it.value.get(DbInterner::new_no_crate(db)))
1464}
1465
1466#[salsa::tracked(returns(ref))]
1467pub(crate) fn impl_trait_with_diagnostics<'db>(
1468    db: &'db dyn HirDatabase,
1469    impl_id: ImplId,
1470) -> Option<TyLoweringResult<'db, StoredEarlyBinder<StoredTraitRef>>> {
1471    let impl_data = ImplSignature::of(db, impl_id);
1472    let resolver = impl_id.resolver(db);
1473    let generics = OnceCell::new();
1474    let mut ctx = TyLoweringContext::new(
1475        db,
1476        &resolver,
1477        &impl_data.store,
1478        ExpressionStoreOwnerId::Signature(impl_id.into()),
1479        impl_id.into(),
1480        &generics,
1481        LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true },
1482        LifetimeLoweringMode::Bound,
1483    );
1484    let self_ty = db.impl_self_ty(impl_id).skip_binder();
1485    let target_trait = impl_data.target_trait.as_ref()?;
1486    let trait_ref = ctx.lower_trait_ref(target_trait, self_ty)?;
1487    Some(TyLoweringResult::from_ctx(StoredEarlyBinder::bind(StoredTraitRef::new(trait_ref)), ctx))
1488}
1489
1490impl ImplTraitId {
1491    #[inline]
1492    pub fn predicates<'db>(self, db: &'db dyn HirDatabase) -> EarlyBinder<'db, &'db [Clause<'db>]> {
1493        let (impl_traits, idx) = match self {
1494            ImplTraitId::ReturnTypeImplTrait(owner, idx) => {
1495                (ImplTraits::return_type_impl_traits(db, owner), idx)
1496            }
1497            ImplTraitId::TypeAliasImplTrait(owner, idx) => {
1498                (ImplTraits::type_alias_impl_traits(db, owner), idx)
1499            }
1500        };
1501        impl_traits
1502            .as_deref()
1503            .expect("owner should have opaque type")
1504            .get_with(|it| it.impl_traits[idx].predicates.as_ref().as_slice())
1505    }
1506
1507    #[inline]
1508    pub fn self_predicates<'db>(
1509        self,
1510        db: &'db dyn HirDatabase,
1511    ) -> EarlyBinder<'db, &'db [Clause<'db>]> {
1512        let (impl_traits, idx) = match self {
1513            ImplTraitId::ReturnTypeImplTrait(owner, idx) => {
1514                (ImplTraits::return_type_impl_traits(db, owner), idx)
1515            }
1516            ImplTraitId::TypeAliasImplTrait(owner, idx) => {
1517                (ImplTraits::type_alias_impl_traits(db, owner), idx)
1518            }
1519        };
1520        let predicates =
1521            impl_traits.as_deref().expect("owner should have opaque type").get_with(|it| {
1522                let impl_trait = &it.impl_traits[idx];
1523                (
1524                    impl_trait.predicates.as_ref().as_slice(),
1525                    impl_trait.assoc_ty_bounds_start as usize,
1526                )
1527            });
1528
1529        predicates.map_bound(|(preds, len)| &preds[..len])
1530    }
1531}
1532
1533impl InternedOpaqueTyId<'_> {
1534    #[inline]
1535    pub fn predicates<'db>(self, db: &'db dyn HirDatabase) -> EarlyBinder<'db, &'db [Clause<'db>]> {
1536        self.loc(db).predicates(db)
1537    }
1538
1539    #[inline]
1540    pub fn self_predicates<'db>(
1541        self,
1542        db: &'db dyn HirDatabase,
1543    ) -> EarlyBinder<'db, &'db [Clause<'db>]> {
1544        self.loc(db).self_predicates(db)
1545    }
1546}
1547
1548#[salsa::tracked]
1549impl ImplTraits {
1550    #[salsa::tracked(returns(ref))]
1551    pub(crate) fn return_type_impl_traits(
1552        db: &dyn HirDatabase,
1553        def: hir_def::FunctionId,
1554    ) -> Option<Box<StoredEarlyBinder<ImplTraits>>> {
1555        // FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
1556        let data = FunctionSignature::of(db, def);
1557        let resolver = def.resolver(db);
1558        let generics = OnceCell::new();
1559        let mut ctx_ret = TyLoweringContext::new(
1560            db,
1561            &resolver,
1562            &data.store,
1563            ExpressionStoreOwnerId::Signature(def.into()),
1564            def.into(),
1565            &generics,
1566            LifetimeElisionKind::Infer,
1567            LifetimeLoweringMode::Bound,
1568        )
1569        .with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
1570        if let Some(ret_type) = data.ret_type {
1571            let _ret = ctx_ret.lower_ty(ret_type);
1572        }
1573        let mut return_type_impl_traits =
1574            ImplTraits { impl_traits: ctx_ret.impl_trait_mode.opaque_type_data };
1575        if return_type_impl_traits.impl_traits.is_empty() {
1576            None
1577        } else {
1578            return_type_impl_traits.impl_traits.shrink_to_fit();
1579            Some(Box::new(StoredEarlyBinder::bind(return_type_impl_traits)))
1580        }
1581    }
1582
1583    #[salsa::tracked(returns(ref))]
1584    pub(crate) fn type_alias_impl_traits(
1585        db: &dyn HirDatabase,
1586        def: hir_def::TypeAliasId,
1587    ) -> Option<Box<StoredEarlyBinder<ImplTraits>>> {
1588        let data = TypeAliasSignature::of(db, def);
1589        let resolver = def.resolver(db);
1590        let generics = OnceCell::new();
1591        let mut ctx = TyLoweringContext::new(
1592            db,
1593            &resolver,
1594            &data.store,
1595            ExpressionStoreOwnerId::Signature(def.into()),
1596            def.into(),
1597            &generics,
1598            LifetimeElisionKind::AnonymousReportError,
1599            LifetimeLoweringMode::Bound,
1600        )
1601        .with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
1602        if let Some(type_ref) = data.ty {
1603            let _ty = ctx.lower_ty(type_ref);
1604        }
1605        let mut type_alias_impl_traits =
1606            ImplTraits { impl_traits: ctx.impl_trait_mode.opaque_type_data };
1607        if type_alias_impl_traits.impl_traits.is_empty() {
1608            None
1609        } else {
1610            type_alias_impl_traits.impl_traits.shrink_to_fit();
1611            Some(Box::new(StoredEarlyBinder::bind(type_alias_impl_traits)))
1612        }
1613    }
1614}
1615
1616#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1617pub enum TyDefId {
1618    BuiltinType(BuiltinType),
1619    AdtId(AdtId),
1620    TypeAliasId(TypeAliasId),
1621}
1622impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
1623
1624#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
1625pub enum ValueTyDefId {
1626    FunctionId(FunctionId),
1627    StructId(StructId),
1628    UnionId(UnionId),
1629    EnumVariantId(EnumVariantId),
1630    ConstId(ConstId),
1631    StaticId(StaticId),
1632}
1633impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
1634
1635impl ValueTyDefId {
1636    pub(crate) fn to_generic_def_id(self, db: &dyn HirDatabase) -> GenericDefId {
1637        match self {
1638            Self::FunctionId(id) => id.into(),
1639            Self::StructId(id) => id.into(),
1640            Self::UnionId(id) => id.into(),
1641            Self::EnumVariantId(var) => var.lookup(db).parent.into(),
1642            Self::ConstId(id) => id.into(),
1643            Self::StaticId(id) => id.into(),
1644        }
1645    }
1646}
1647
1648/// Build the declared type of an item. This depends on the namespace; e.g. for
1649/// `struct Foo(usize)`, we have two types: The type of the struct itself, and
1650/// the constructor function `(usize) -> Foo` which lives in the values
1651/// namespace.
1652pub(crate) fn ty_query<'db>(db: &'db dyn HirDatabase, def: TyDefId) -> EarlyBinder<'db, Ty<'db>> {
1653    let interner = DbInterner::new_no_crate(db);
1654    match def {
1655        TyDefId::BuiltinType(it) => EarlyBinder::bind(Ty::from_builtin_type(interner, it)),
1656        TyDefId::AdtId(it) => EarlyBinder::bind(Ty::new_adt(
1657            interner,
1658            it,
1659            GenericArgs::identity_for_item(interner, it.into()),
1660        )),
1661        TyDefId::TypeAliasId(it) => db.type_for_type_alias_with_diagnostics(it).value.get(),
1662    }
1663}
1664
1665/// Build the declared type of a function. This should not need to look at the
1666/// function body.
1667fn type_for_fn<'db>(db: &'db dyn HirDatabase, def: FunctionId) -> EarlyBinder<'db, Ty<'db>> {
1668    let interner = DbInterner::new_no_crate(db);
1669    EarlyBinder::bind(Ty::new_fn_def(
1670        interner,
1671        CallableDefId::FunctionId(def).into(),
1672        GenericArgs::identity_for_item(interner, def.into()),
1673    ))
1674}
1675
1676pub(crate) fn type_for_const<'db>(
1677    db: &'db dyn HirDatabase,
1678    def: ConstId,
1679) -> EarlyBinder<'db, Ty<'db>> {
1680    type_for_const_with_diagnostics(db, def).value.get()
1681}
1682
1683/// Build the declared type of a const.
1684#[salsa::tracked(returns(ref))]
1685pub(crate) fn type_for_const_with_diagnostics<'db>(
1686    db: &'db dyn HirDatabase,
1687    def: ConstId,
1688) -> TyLoweringResult<'db, StoredEarlyBinder<StoredTy>> {
1689    let resolver = def.resolver(db);
1690    let data = ConstSignature::of(db, def);
1691    let parent = def.loc(db).container;
1692    let generics = OnceCell::new();
1693    let mut ctx = TyLoweringContext::new(
1694        db,
1695        &resolver,
1696        &data.store,
1697        ExpressionStoreOwnerId::Signature(def.into()),
1698        def.into(),
1699        &generics,
1700        LifetimeElisionKind::AnonymousReportError,
1701        LifetimeLoweringMode::Bound,
1702    );
1703    ctx.set_lifetime_elision(LifetimeElisionKind::for_const(ctx.interner, parent));
1704    let result = StoredEarlyBinder::bind(ctx.lower_ty(data.type_ref).store());
1705    TyLoweringResult::from_ctx(result, ctx)
1706}
1707
1708pub(crate) fn type_for_static<'db>(
1709    db: &'db dyn HirDatabase,
1710    def: StaticId,
1711) -> EarlyBinder<'db, Ty<'db>> {
1712    type_for_static_with_diagnostics(db, def).value.get()
1713}
1714
1715/// Build the declared type of a static.
1716#[salsa::tracked(returns(ref))]
1717pub(crate) fn type_for_static_with_diagnostics<'db>(
1718    db: &'db dyn HirDatabase,
1719    def: StaticId,
1720) -> TyLoweringResult<'db, StoredEarlyBinder<StoredTy>> {
1721    let resolver = def.resolver(db);
1722    let data = StaticSignature::of(db, def);
1723    let generics = OnceCell::new();
1724    let mut ctx = TyLoweringContext::new(
1725        db,
1726        &resolver,
1727        &data.store,
1728        ExpressionStoreOwnerId::Signature(def.into()),
1729        def.into(),
1730        &generics,
1731        LifetimeElisionKind::AnonymousReportError,
1732        LifetimeLoweringMode::Bound,
1733    );
1734    ctx.set_lifetime_elision(LifetimeElisionKind::Elided(Region::new_static(ctx.interner)));
1735    let result = StoredEarlyBinder::bind(ctx.lower_ty(data.type_ref).store());
1736    TyLoweringResult::from_ctx(result, ctx)
1737}
1738
1739/// Build the type of a tuple struct constructor.
1740fn type_for_struct_constructor<'db>(
1741    db: &'db dyn HirDatabase,
1742    def: StructId,
1743) -> Option<EarlyBinder<'db, Ty<'db>>> {
1744    let struct_data = StructSignature::of(db, def);
1745    match struct_data.shape {
1746        FieldsShape::Record => None,
1747        FieldsShape::Unit => Some(type_for_adt(db, def.into())),
1748        FieldsShape::Tuple => {
1749            let interner = DbInterner::new_no_crate(db);
1750            let def = CallableDefId::StructId(def);
1751            Some(EarlyBinder::bind(Ty::new_fn_def(
1752                interner,
1753                def.into(),
1754                GenericArgs::identity_for_item(interner, def.into()),
1755            )))
1756        }
1757    }
1758}
1759
1760/// Build the type of a tuple enum variant constructor.
1761fn type_for_enum_variant_constructor<'db>(
1762    db: &'db dyn HirDatabase,
1763    def: EnumVariantId,
1764) -> Option<EarlyBinder<'db, Ty<'db>>> {
1765    let struct_data = def.fields(db);
1766    match struct_data.shape {
1767        FieldsShape::Record => None,
1768        FieldsShape::Unit => Some(type_for_adt(db, def.loc(db).parent.into())),
1769        FieldsShape::Tuple => {
1770            let interner = DbInterner::new_no_crate(db);
1771            let def = CallableDefId::EnumVariantId(def);
1772            Some(EarlyBinder::bind(Ty::new_fn_def(
1773                interner,
1774                def.into(),
1775                GenericArgs::identity_for_item(interner, def.into()),
1776            )))
1777        }
1778    }
1779}
1780
1781pub(crate) fn value_ty<'db>(
1782    db: &'db dyn HirDatabase,
1783    def: ValueTyDefId,
1784) -> Option<EarlyBinder<'db, Ty<'db>>> {
1785    match def {
1786        ValueTyDefId::FunctionId(it) => Some(type_for_fn(db, it)),
1787        ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
1788        ValueTyDefId::UnionId(it) => Some(type_for_adt(db, it.into())),
1789        ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
1790        ValueTyDefId::ConstId(it) => Some(type_for_const(db, it)),
1791        ValueTyDefId::StaticId(it) => Some(type_for_static(db, it)),
1792    }
1793}
1794
1795#[salsa::tracked(returns(ref), cycle_result = type_for_type_alias_with_diagnostics_cycle_result)]
1796pub(crate) fn type_for_type_alias_with_diagnostics<'db>(
1797    db: &'db dyn HirDatabase,
1798    t: TypeAliasId,
1799) -> TyLoweringResult<'db, StoredEarlyBinder<StoredTy>> {
1800    let type_alias_data = TypeAliasSignature::of(db, t);
1801    let interner = DbInterner::new_no_crate(db);
1802    if type_alias_data.flags.contains(TypeAliasFlags::IS_EXTERN) {
1803        TyLoweringResult::empty(StoredEarlyBinder::bind(
1804            Ty::new_foreign(interner, t.into()).store(),
1805        ))
1806    } else {
1807        let resolver = t.resolver(db);
1808        let generics = OnceCell::new();
1809        let mut ctx = TyLoweringContext::new(
1810            db,
1811            &resolver,
1812            &type_alias_data.store,
1813            ExpressionStoreOwnerId::Signature(t.into()),
1814            t.into(),
1815            &generics,
1816            LifetimeElisionKind::AnonymousReportError,
1817            LifetimeLoweringMode::Bound,
1818        )
1819        .with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
1820        let res = StoredEarlyBinder::bind(
1821            type_alias_data
1822                .ty
1823                .map(|type_ref| ctx.lower_ty(type_ref))
1824                .unwrap_or_else(|| Ty::new_error(interner, ErrorGuaranteed))
1825                .store(),
1826        );
1827        TyLoweringResult::from_ctx(res, ctx)
1828    }
1829}
1830
1831pub(crate) fn type_for_type_alias_with_diagnostics_cycle_result<'db>(
1832    db: &'db dyn HirDatabase,
1833    _: salsa::Id,
1834    _adt: TypeAliasId,
1835) -> TyLoweringResult<'db, StoredEarlyBinder<StoredTy>> {
1836    TyLoweringResult::empty(StoredEarlyBinder::bind(
1837        Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed).store(),
1838    ))
1839}
1840
1841pub(crate) fn impl_self_ty_query<'db>(
1842    db: &'db dyn HirDatabase,
1843    impl_id: ImplId,
1844) -> EarlyBinder<'db, Ty<'db>> {
1845    impl_self_ty_with_diagnostics(db, impl_id).value.get()
1846}
1847
1848#[salsa::tracked(returns(ref), cycle_result = impl_self_ty_with_diagnostics_cycle_result)]
1849pub(crate) fn impl_self_ty_with_diagnostics<'db>(
1850    db: &'db dyn HirDatabase,
1851    impl_id: ImplId,
1852) -> TyLoweringResult<'db, StoredEarlyBinder<StoredTy>> {
1853    let resolver = impl_id.resolver(db);
1854    let generics = OnceCell::new();
1855    let impl_data = ImplSignature::of(db, impl_id);
1856    let mut ctx = TyLoweringContext::new(
1857        db,
1858        &resolver,
1859        &impl_data.store,
1860        ExpressionStoreOwnerId::Signature(impl_id.into()),
1861        impl_id.into(),
1862        &generics,
1863        LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true },
1864        LifetimeLoweringMode::Bound,
1865    );
1866    let ty = ctx.lower_ty(impl_data.self_ty);
1867    assert!(!ty.has_escaping_bound_vars());
1868    TyLoweringResult::from_ctx(StoredEarlyBinder::bind(ty.store()), ctx)
1869}
1870
1871pub(crate) fn impl_self_ty_with_diagnostics_cycle_result<'db>(
1872    db: &'db dyn HirDatabase,
1873    _: salsa::Id,
1874    _impl_id: ImplId,
1875) -> TyLoweringResult<'db, StoredEarlyBinder<StoredTy>> {
1876    TyLoweringResult::empty(StoredEarlyBinder::bind(
1877        Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed).store(),
1878    ))
1879}
1880
1881pub(crate) fn const_param_ty<'db>(db: &'db dyn HirDatabase, def: ConstParamId) -> Ty<'db> {
1882    let param_types = const_param_types(db, def.parent());
1883    match param_types.get(def.local_id()) {
1884        Some(ty) => ty.as_ref(),
1885        None => Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed),
1886    }
1887}
1888
1889pub(crate) fn const_param_types(
1890    db: &dyn HirDatabase,
1891    def: GenericDefId,
1892) -> &ArenaMap<LocalTypeOrConstParamId, StoredTy> {
1893    &const_param_types_with_diagnostics(db, def).value
1894}
1895
1896#[salsa::tracked(returns(ref), cycle_result = const_param_types_with_diagnostics_cycle_result)]
1897pub(crate) fn const_param_types_with_diagnostics<'db>(
1898    db: &'db dyn HirDatabase,
1899    def: GenericDefId,
1900) -> TyLoweringResult<'db, ArenaMap<LocalTypeOrConstParamId, StoredTy>> {
1901    let mut result = ArenaMap::new();
1902    let (data, store) = GenericParams::with_store(db, def);
1903    let resolver = def.resolver(db);
1904    let generics = OnceCell::new();
1905    let mut ctx = TyLoweringContext::new(
1906        db,
1907        &resolver,
1908        store,
1909        ExpressionStoreOwnerId::Signature(def),
1910        def,
1911        &generics,
1912        LifetimeElisionKind::AnonymousReportError,
1913        LifetimeLoweringMode::Bound,
1914    );
1915    ctx.forbid_params_after(0, ForbidParamsAfterReason::ConstParamTy);
1916    for (local_id, param_data) in data.iter_type_or_consts() {
1917        if let TypeOrConstParamData::ConstParamData(param_data) = param_data {
1918            result.insert(local_id, ctx.lower_ty(param_data.ty).store());
1919        }
1920    }
1921    result.shrink_to_fit();
1922    TyLoweringResult::from_ctx(result, ctx)
1923}
1924
1925fn const_param_types_with_diagnostics_cycle_result<'db>(
1926    _db: &'db dyn HirDatabase,
1927    _: salsa::Id,
1928    _def: GenericDefId,
1929) -> TyLoweringResult<'db, ArenaMap<LocalTypeOrConstParamId, StoredTy>> {
1930    TyLoweringResult::empty(ArenaMap::default())
1931}
1932
1933pub(crate) fn field_types_query(
1934    db: &dyn HirDatabase,
1935    variant_id: VariantId,
1936) -> &ArenaMap<LocalFieldId, FieldType> {
1937    &field_types_with_diagnostics(db, variant_id).value
1938}
1939
1940#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1941pub struct FieldType {
1942    ty: StoredEarlyBinder<StoredTy>,
1943    default: Option<StoredEarlyBinder<StoredConst>>,
1944}
1945
1946impl FieldType {
1947    #[inline]
1948    pub fn ty<'db>(&self) -> EarlyBinder<'db, Ty<'db>> {
1949        self.ty.get()
1950    }
1951
1952    #[inline]
1953    pub fn default<'db>(&self) -> Option<EarlyBinder<'db, Const<'db>>> {
1954        self.default.as_ref().map(|default| default.get_with(|it| it.as_ref()))
1955    }
1956}
1957
1958/// Build the type of all specific fields of a struct or enum variant.
1959#[salsa::tracked(returns(ref))]
1960pub(crate) fn field_types_with_diagnostics<'db>(
1961    db: &'db dyn HirDatabase,
1962    variant_id: VariantId,
1963) -> TyLoweringResult<'db, ArenaMap<LocalFieldId, FieldType>> {
1964    let var_data = variant_id.fields(db);
1965    let fields = var_data.fields();
1966    if fields.is_empty() {
1967        return TyLoweringResult::empty(ArenaMap::default());
1968    }
1969
1970    let (resolver, generic_def): (_, GenericDefId) = match variant_id {
1971        VariantId::StructId(it) => (it.resolver(db), it.into()),
1972        VariantId::UnionId(it) => (it.resolver(db), it.into()),
1973        VariantId::EnumVariantId(it) => (it.resolver(db), it.lookup(db).parent.into()),
1974    };
1975    let generics = OnceCell::new();
1976    let mut res = ArenaMap::default();
1977    let mut ctx = TyLoweringContext::new(
1978        db,
1979        &resolver,
1980        &var_data.store,
1981        ExpressionStoreOwnerId::VariantFields(variant_id),
1982        generic_def,
1983        &generics,
1984        LifetimeElisionKind::AnonymousReportError,
1985        LifetimeLoweringMode::Bound,
1986    );
1987    for (field_id, field_data) in var_data.fields().iter() {
1988        let ty = ctx.lower_ty(field_data.type_ref);
1989        let default = field_data.default_value.map(|default| ctx.lower_const(default, ty));
1990        res.insert(
1991            field_id,
1992            FieldType {
1993                ty: StoredEarlyBinder::bind(ty.store()),
1994                default: default.map(|default| StoredEarlyBinder::bind(default.store())),
1995            },
1996        );
1997    }
1998    TyLoweringResult::from_ctx(res, ctx)
1999}
2000
2001#[derive(Debug, PartialEq, Eq, Default)]
2002pub(crate) struct SupertraitsInfo {
2003    /// This includes the trait itself.
2004    pub(crate) all_supertraits: Box<[TraitId]>,
2005    pub(crate) direct_supertraits: Box<[TraitId]>,
2006    pub(crate) defined_assoc_types: Box<[(Name, TypeAliasId)]>,
2007}
2008
2009impl SupertraitsInfo {
2010    #[inline]
2011    pub(crate) fn query(db: &dyn HirDatabase, trait_: TraitId) -> &Self {
2012        return supertraits_info(db, trait_);
2013
2014        #[salsa::tracked(returns(ref), cycle_result = supertraits_info_cycle)]
2015        fn supertraits_info(db: &dyn HirDatabase, trait_: TraitId) -> SupertraitsInfo {
2016            let mut all_supertraits = FxHashSet::default();
2017            let mut direct_supertraits = FxHashSet::default();
2018            let mut defined_assoc_types = FxHashSet::default();
2019
2020            all_supertraits.insert(trait_);
2021            defined_assoc_types.extend(trait_.trait_items(db).items.iter().filter_map(
2022                |(name, id)| match *id {
2023                    AssocItemId::TypeAliasId(id) => Some((name.clone(), id)),
2024                    _ => None,
2025                },
2026            ));
2027
2028            let resolver = trait_.resolver(db);
2029            let signature = TraitSignature::of(db, trait_);
2030            for pred in signature.generic_params.where_predicates() {
2031                let WherePredicate::TypeBound { lifetimes: _, target, bound } = pred else {
2032                    continue;
2033                };
2034                let (TypeBound::Path(bounded_trait, TraitBoundModifier::None)
2035                | TypeBound::ForLifetime(_, bounded_trait)) = *bound
2036                else {
2037                    continue;
2038                };
2039                let target = &signature.store[*target];
2040                match target {
2041                    TypeRef::TypeParam(param)
2042                        if param.local_id() == GenericParams::SELF_PARAM_ID_IN_SELF => {}
2043                    TypeRef::Path(path) if path.is_self_type() => {}
2044                    _ => continue,
2045                }
2046                let Some(TypeNs::TraitId(bounded_trait)) =
2047                    resolver.resolve_path_in_type_ns_fully(db, &signature.store[bounded_trait])
2048                else {
2049                    continue;
2050                };
2051                let SupertraitsInfo {
2052                    all_supertraits: bounded_trait_all_supertraits,
2053                    direct_supertraits: _,
2054                    defined_assoc_types: bounded_traits_defined_assoc_types,
2055                } = SupertraitsInfo::query(db, bounded_trait);
2056                all_supertraits.extend(bounded_trait_all_supertraits);
2057                direct_supertraits.insert(bounded_trait);
2058                defined_assoc_types.extend(bounded_traits_defined_assoc_types.iter().cloned());
2059            }
2060
2061            SupertraitsInfo {
2062                all_supertraits: Box::from_iter(all_supertraits),
2063                direct_supertraits: Box::from_iter(direct_supertraits),
2064                defined_assoc_types: Box::from_iter(defined_assoc_types),
2065            }
2066        }
2067
2068        fn supertraits_info_cycle(
2069            _db: &dyn HirDatabase,
2070            _: salsa::Id,
2071            _trait_: TraitId,
2072        ) -> SupertraitsInfo {
2073            SupertraitsInfo::default()
2074        }
2075    }
2076}
2077
2078#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2079enum AssocTypeShorthandResolution {
2080    Resolved(StoredEarlyBinder<(TypeAliasId, StoredGenericArgs)>),
2081    Ambiguous {
2082        /// If one resolution belongs to a sub-trait and one to a supertrait, this contains
2083        /// the sub-trait's resolution. This can be `None` if there is no trait inheritance
2084        /// relationship between the resolutions.
2085        sub_trait_resolution: Option<StoredEarlyBinder<(TypeAliasId, StoredGenericArgs)>>,
2086    },
2087    NotFound,
2088    Cycle,
2089}
2090
2091/// Predicates for `param_id` of the form `P: SomeTrait`. If
2092/// `assoc_name` is provided, only return predicates referencing traits
2093/// that have an associated type of that name.
2094///
2095/// This query exists only to be used when resolving short-hand associated types
2096/// like `T::Item`.
2097///
2098/// See the analogous query in rustc and its comment:
2099/// <https://github.com/rust-lang/rust/blob/9150f844e2624eb013ec78ca08c1d416e6644026/src/librustc_typeck/astconv.rs#L46>
2100///
2101/// This is a query mostly to handle cycles somewhat gracefully; e.g. the
2102/// following bounds are disallowed: `T: Foo<U::Item>, U: Foo<T::Item>`, but
2103/// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
2104#[tracing::instrument(skip(db), ret)]
2105#[salsa::tracked(returns(ref), cycle_result = resolve_type_param_assoc_type_shorthand_cycle_result)]
2106fn resolve_type_param_assoc_type_shorthand(
2107    db: &dyn HirDatabase,
2108    def: GenericDefId,
2109    param: TypeParamId,
2110    assoc_name: Name,
2111) -> AssocTypeShorthandResolution {
2112    let generics = generics(db, def);
2113    let store = generics.store();
2114    let generics = &OnceCell::from(generics);
2115    let resolver = def.resolver(db);
2116    let mut ctx = TyLoweringContext::new(
2117        db,
2118        &resolver,
2119        store,
2120        ExpressionStoreOwnerId::Signature(def),
2121        def,
2122        generics,
2123        LifetimeElisionKind::AnonymousReportError,
2124        LifetimeLoweringMode::Bound,
2125    );
2126    let interner = ctx.interner;
2127    let generics = generics.get().unwrap();
2128    let param_ty = Ty::new_param(interner, param, generics.type_or_const_param_idx(param.into()));
2129
2130    let mut this_trait_resolution = None;
2131    if let GenericDefId::TraitId(containing_trait) = param.parent()
2132        && param.local_id() == GenericParams::SELF_PARAM_ID_IN_SELF
2133    {
2134        // Add the trait's own associated types.
2135        if let Some(assoc_type) =
2136            containing_trait.trait_items(db).associated_type_by_name(&assoc_name)
2137        {
2138            let args = GenericArgs::identity_for_item(interner, containing_trait.into());
2139            this_trait_resolution = Some(StoredEarlyBinder::bind((assoc_type, args.store())));
2140        }
2141    }
2142
2143    let mut supertraits_resolution = None;
2144    for maybe_parent_generics in generics.iter_owners().rev() {
2145        ctx.set_owner(maybe_parent_generics);
2146        for pred in maybe_parent_generics.where_predicates() {
2147            let WherePredicate::TypeBound { lifetimes: _, target, bound } = pred else {
2148                continue;
2149            };
2150            let (TypeBound::Path(bounded_trait_path, TraitBoundModifier::None)
2151            | TypeBound::ForLifetime(_, bounded_trait_path)) = *bound
2152            else {
2153                continue;
2154            };
2155            let Some(target) = ctx.lower_ty_only_param(*target) else { continue };
2156            if target != param.into() {
2157                continue;
2158            }
2159            let Some(TypeNs::TraitId(bounded_trait)) =
2160                resolver.resolve_path_in_type_ns_fully(db, &ctx.store[bounded_trait_path])
2161            else {
2162                continue;
2163            };
2164            if !SupertraitsInfo::query(db, bounded_trait)
2165                .defined_assoc_types
2166                .iter()
2167                .any(|(name, _)| *name == assoc_name)
2168            {
2169                continue;
2170            }
2171
2172            let Some((bounded_trait_ref, _)) =
2173                ctx.lower_trait_ref_from_path(bounded_trait_path, param_ty)
2174            else {
2175                continue;
2176            };
2177            // Now, search from the start on the *bounded* trait like if we wrote `Self::Assoc`. Eventually, we'll get
2178            // the correct trait ref (or a cycle).
2179            let lookup_on_bounded_trait = resolve_type_param_assoc_type_shorthand(
2180                db,
2181                bounded_trait.into(),
2182                TypeParamId::trait_self(bounded_trait),
2183                assoc_name.clone(),
2184            );
2185            let assoc_type_and_args = match &lookup_on_bounded_trait {
2186                AssocTypeShorthandResolution::Resolved(trait_ref) => trait_ref,
2187                AssocTypeShorthandResolution::Ambiguous {
2188                    sub_trait_resolution: Some(trait_ref),
2189                } => trait_ref,
2190                AssocTypeShorthandResolution::Ambiguous { sub_trait_resolution: None } => {
2191                    return AssocTypeShorthandResolution::Ambiguous {
2192                        sub_trait_resolution: this_trait_resolution,
2193                    };
2194                }
2195                AssocTypeShorthandResolution::NotFound => {
2196                    never!("we checked that the trait defines this assoc type");
2197                    continue;
2198                }
2199                AssocTypeShorthandResolution::Cycle => return AssocTypeShorthandResolution::Cycle,
2200            };
2201            let (assoc_type, args) = assoc_type_and_args
2202                .get_with(|(assoc_type, args)| (*assoc_type, args.as_ref()))
2203                .skip_binder();
2204            let args = EarlyBinder::bind(args)
2205                .instantiate(interner, bounded_trait_ref.args)
2206                .skip_norm_wip();
2207            let current_result = StoredEarlyBinder::bind((assoc_type, args.store()));
2208            if let Some(this_trait_resolution) = &this_trait_resolution {
2209                if *this_trait_resolution == current_result {
2210                    continue;
2211                } else {
2212                    return AssocTypeShorthandResolution::Ambiguous {
2213                        sub_trait_resolution: Some(this_trait_resolution.clone()),
2214                    };
2215                }
2216            } else if let Some(prev_resolution) = &supertraits_resolution {
2217                if let AssocTypeShorthandResolution::Ambiguous {
2218                    sub_trait_resolution: Some(prev_resolution),
2219                }
2220                | AssocTypeShorthandResolution::Resolved(prev_resolution) = prev_resolution
2221                    && *prev_resolution == current_result
2222                {
2223                    continue;
2224                } else {
2225                    return AssocTypeShorthandResolution::Ambiguous { sub_trait_resolution: None };
2226                }
2227            } else {
2228                supertraits_resolution = Some(match lookup_on_bounded_trait {
2229                    AssocTypeShorthandResolution::Resolved(_) => {
2230                        AssocTypeShorthandResolution::Resolved(current_result)
2231                    }
2232                    AssocTypeShorthandResolution::Ambiguous { .. } => {
2233                        AssocTypeShorthandResolution::Ambiguous {
2234                            sub_trait_resolution: Some(current_result),
2235                        }
2236                    }
2237                    AssocTypeShorthandResolution::NotFound
2238                    | AssocTypeShorthandResolution::Cycle => unreachable!(),
2239                });
2240            }
2241        }
2242    }
2243
2244    supertraits_resolution
2245        .or_else(|| this_trait_resolution.map(AssocTypeShorthandResolution::Resolved))
2246        .unwrap_or(AssocTypeShorthandResolution::NotFound)
2247}
2248
2249fn resolve_type_param_assoc_type_shorthand_cycle_result(
2250    _db: &dyn HirDatabase,
2251    _: salsa::Id,
2252    _def: GenericDefId,
2253    _param: TypeParamId,
2254    _assoc_name: Name,
2255) -> AssocTypeShorthandResolution {
2256    AssocTypeShorthandResolution::Cycle
2257}
2258
2259#[inline]
2260pub(crate) fn type_alias_bounds<'db>(
2261    db: &'db dyn HirDatabase,
2262    type_alias: TypeAliasId,
2263) -> EarlyBinder<'db, &'db [Clause<'db>]> {
2264    type_alias_bounds_with_diagnostics(db, type_alias)
2265        .value
2266        .predicates
2267        .get()
2268        .map_bound(|it| it.as_slice())
2269}
2270
2271#[inline]
2272pub(crate) fn type_alias_self_bounds<'db>(
2273    db: &'db dyn HirDatabase,
2274    type_alias: TypeAliasId,
2275) -> EarlyBinder<'db, &'db [Clause<'db>]> {
2276    let TypeAliasBounds { predicates, assoc_ty_bounds_start } =
2277        &type_alias_bounds_with_diagnostics(db, type_alias).value;
2278    predicates.get().map_bound(|it| &it.as_slice()[..*assoc_ty_bounds_start as usize])
2279}
2280
2281#[derive(PartialEq, Eq, Debug, Hash)]
2282pub struct TypeAliasBounds<T> {
2283    predicates: T,
2284    assoc_ty_bounds_start: u32,
2285}
2286
2287#[salsa::tracked(returns(ref))]
2288pub(crate) fn type_alias_bounds_with_diagnostics<'db>(
2289    db: &'db dyn HirDatabase,
2290    type_alias: TypeAliasId,
2291) -> TyLoweringResult<'db, TypeAliasBounds<StoredEarlyBinder<StoredClauses>>> {
2292    let type_alias_data = TypeAliasSignature::of(db, type_alias);
2293    let resolver = type_alias.resolver(db);
2294    let generics = OnceCell::new();
2295    let mut ctx = TyLoweringContext::new(
2296        db,
2297        &resolver,
2298        &type_alias_data.store,
2299        ExpressionStoreOwnerId::Signature(type_alias.into()),
2300        type_alias.into(),
2301        &generics,
2302        LifetimeElisionKind::AnonymousReportError,
2303        LifetimeLoweringMode::Bound,
2304    );
2305    let interner = ctx.interner;
2306
2307    let item_args = GenericArgs::identity_for_item(interner, type_alias.into());
2308    let interner_ty = Ty::new_projection_from_args(interner, type_alias.into(), item_args);
2309
2310    let mut bounds = Vec::new();
2311    let mut assoc_ty_bounds = Vec::new();
2312    for bound in &type_alias_data.bounds {
2313        ctx.lower_type_bound(bound, interner_ty, false).for_each(|(pred, source)| match source {
2314            GenericPredicateSource::SelfOnly => {
2315                bounds.push(pred);
2316            }
2317            GenericPredicateSource::AssocTyBound => {
2318                assoc_ty_bounds.push(pred);
2319            }
2320        });
2321    }
2322
2323    if !ctx.unsized_types.contains(&interner_ty) {
2324        let sized_trait = ctx.lang_items.Sized;
2325        if let Some(sized_trait) = sized_trait {
2326            let trait_ref = TraitRef::new_from_args(
2327                interner,
2328                sized_trait.into(),
2329                GenericArgs::new_from_slice(&[interner_ty.into()]),
2330            );
2331            bounds.push(trait_ref.upcast(interner));
2332        };
2333    }
2334
2335    let assoc_ty_bounds_start = bounds.len() as u32;
2336    bounds.extend(assoc_ty_bounds);
2337
2338    TyLoweringResult::from_ctx(
2339        TypeAliasBounds {
2340            predicates: StoredEarlyBinder::bind(Clauses::new_from_slice(&bounds).store()),
2341            assoc_ty_bounds_start,
2342        },
2343        ctx,
2344    )
2345}
2346
2347#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2348pub struct GenericPredicates {
2349    // The order is the following:
2350    //
2351    // 1. If `has_trait_implied_predicate == true`, the implicit trait predicate.
2352    // 2. The bounds of the associated types of the parents, coming from `Trait<Assoc: Trait>`.
2353    //    Note: associated type bounds from `Self::Assoc: Trait` on traits *won't* be included
2354    //    here, they are in 3.
2355    // 3. The explicit, self-only predicates for the parent.
2356    // 4. The explicit, self-only trait predicate for the child,
2357    // 5. The bounds of the associated types of the child.
2358    predicates: StoredEarlyBinder<StoredClauses>,
2359    // Keep this ordered according to the above.
2360    has_trait_implied_predicate: bool,
2361    parent_explicit_self_predicates_start: u32,
2362    own_predicates_start: u32,
2363    own_assoc_ty_bounds_start: u32,
2364}
2365
2366#[salsa::tracked]
2367impl<'db> GenericPredicates {
2368    /// Resolve the where clause(s) of an item with generics.
2369    ///
2370    /// Diagnostics are computed only for this item's predicates, not for parents.
2371    #[salsa::tracked(returns(ref), cycle_result=generic_predicates_cycle_result)]
2372    pub fn query_with_diagnostics(
2373        db: &'db dyn HirDatabase,
2374        def: GenericDefId,
2375    ) -> TyLoweringResult<'db, GenericPredicates> {
2376        generic_predicates(db, def)
2377    }
2378}
2379
2380/// A cycle can occur from malformed code.
2381fn generic_predicates_cycle_result<'db>(
2382    db: &'db dyn HirDatabase,
2383    _: salsa::Id,
2384    _def: GenericDefId,
2385) -> TyLoweringResult<'db, GenericPredicates> {
2386    TyLoweringResult::empty(GenericPredicates::from_explicit_own_predicates(
2387        StoredEarlyBinder::bind(Clauses::empty(DbInterner::new_no_crate(db)).store()),
2388    ))
2389}
2390
2391impl GenericPredicates {
2392    #[inline]
2393    pub fn empty() -> &'static GenericPredicates {
2394        static EMPTY: OnceLock<GenericPredicates> = OnceLock::new();
2395        EMPTY.get_or_init(|| GenericPredicates {
2396            predicates: StoredEarlyBinder::bind(Clauses::new_from_slice(&[]).store()),
2397            has_trait_implied_predicate: false,
2398            parent_explicit_self_predicates_start: 0,
2399            own_predicates_start: 0,
2400            own_assoc_ty_bounds_start: 0,
2401        })
2402    }
2403
2404    #[inline]
2405    pub(crate) fn from_explicit_own_predicates(
2406        predicates: StoredEarlyBinder<StoredClauses>,
2407    ) -> Self {
2408        let len = predicates.get().skip_binder().len() as u32;
2409        Self {
2410            predicates,
2411            has_trait_implied_predicate: false,
2412            parent_explicit_self_predicates_start: 0,
2413            own_predicates_start: 0,
2414            own_assoc_ty_bounds_start: len,
2415        }
2416    }
2417
2418    #[inline]
2419    pub fn query(db: &dyn HirDatabase, def: GenericDefId) -> &GenericPredicates {
2420        &Self::query_with_diagnostics(db, def).value
2421    }
2422
2423    #[inline]
2424    pub fn query_all<'db>(
2425        db: &'db dyn HirDatabase,
2426        def: GenericDefId,
2427    ) -> EarlyBinder<'db, impl Iterator<Item = Clause<'db>>> {
2428        Self::query(db, def).all_predicates()
2429    }
2430
2431    #[inline]
2432    pub fn query_own_explicit<'db>(
2433        db: &'db dyn HirDatabase,
2434        def: GenericDefId,
2435    ) -> EarlyBinder<'db, impl Iterator<Item = Clause<'db>>> {
2436        Self::query(db, def).own_explicit_predicates()
2437    }
2438
2439    #[inline]
2440    pub fn query_explicit<'db>(
2441        db: &'db dyn HirDatabase,
2442        def: GenericDefId,
2443    ) -> EarlyBinder<'db, impl Iterator<Item = Clause<'db>>> {
2444        Self::query(db, def).explicit_predicates()
2445    }
2446
2447    #[inline]
2448    pub fn all_predicates(&self) -> EarlyBinder<'_, impl Iterator<Item = Clause<'_>>> {
2449        self.predicates.get().map_bound(|it| it.as_slice().iter().copied())
2450    }
2451
2452    #[inline]
2453    pub fn own_explicit_predicates(&self) -> EarlyBinder<'_, impl Iterator<Item = Clause<'_>>> {
2454        self.predicates
2455            .get()
2456            .map_bound(|it| it.as_slice()[self.own_predicates_start as usize..].iter().copied())
2457    }
2458
2459    #[inline]
2460    pub fn explicit_predicates(&self) -> EarlyBinder<'_, impl Iterator<Item = Clause<'_>>> {
2461        self.predicates.get().map_bound(|it| {
2462            it.as_slice()[usize::from(self.has_trait_implied_predicate)..].iter().copied()
2463        })
2464    }
2465
2466    #[inline]
2467    pub fn explicit_non_assoc_types_predicates(
2468        &self,
2469    ) -> EarlyBinder<'_, impl Iterator<Item = Clause<'_>>> {
2470        self.predicates.get().map_bound(|it| {
2471            it.as_slice()[self.parent_explicit_self_predicates_start as usize
2472                ..self.own_assoc_ty_bounds_start as usize]
2473                .iter()
2474                .copied()
2475        })
2476    }
2477
2478    #[inline]
2479    pub fn explicit_assoc_types_predicates(
2480        &self,
2481    ) -> EarlyBinder<'_, impl Iterator<Item = Clause<'_>>> {
2482        self.predicates.get().map_bound(|predicates| {
2483            let predicates = predicates.as_slice();
2484            predicates[usize::from(self.has_trait_implied_predicate)
2485                ..self.parent_explicit_self_predicates_start as usize]
2486                .iter()
2487                .copied()
2488                .chain(predicates[self.own_assoc_ty_bounds_start as usize..].iter().copied())
2489        })
2490    }
2491}
2492
2493pub(crate) fn param_env_from_predicates<'db>(
2494    interner: DbInterner<'db>,
2495    predicates: &'db GenericPredicates,
2496) -> ParamEnv<'db> {
2497    let clauses = rustc_type_ir::elaborate::elaborate(
2498        interner,
2499        predicates.all_predicates().iter_identity().map(Unnormalized::skip_norm_wip),
2500    );
2501    let clauses = Clauses::new_from_iter(interner, clauses);
2502
2503    // FIXME: We should normalize projections here, like rustc does.
2504    ParamEnv { clauses }
2505}
2506
2507pub(crate) fn trait_environment<'db>(db: &'db dyn HirDatabase, def: GenericDefId) -> ParamEnv<'db> {
2508    return ParamEnv { clauses: trait_environment_query(db, def).as_ref() };
2509
2510    #[salsa::tracked(returns(ref))]
2511    pub(crate) fn trait_environment_query(
2512        db: &dyn HirDatabase,
2513        def: GenericDefId,
2514    ) -> StoredClauses {
2515        let module = def.module(db);
2516        let interner = DbInterner::new_with(db, module.krate(db));
2517        let predicates = GenericPredicates::query(db, def);
2518        param_env_from_predicates(interner, predicates).clauses.store()
2519    }
2520}
2521
2522/// Resolve the where clause(s) of an item with generics,
2523/// with a given filter
2524#[tracing::instrument(skip(db), ret)]
2525fn generic_predicates<'db>(
2526    db: &'db dyn HirDatabase,
2527    def: GenericDefId,
2528) -> TyLoweringResult<'db, GenericPredicates> {
2529    let generics = generics(db, def);
2530    let store = generics.store();
2531    let generics = &OnceCell::from(generics);
2532    let resolver = def.resolver(db);
2533    let interner = DbInterner::new_no_crate(db);
2534    let mut ctx = TyLoweringContext::new(
2535        db,
2536        &resolver,
2537        store,
2538        ExpressionStoreOwnerId::Signature(def),
2539        def,
2540        generics,
2541        LifetimeElisionKind::AnonymousReportError,
2542        LifetimeLoweringMode::Bound,
2543    );
2544    let generics = generics.get().unwrap();
2545    let sized_trait = ctx.lang_items.Sized;
2546
2547    // We need to lower parents and self separately - see the comment below lowering of implicit
2548    // `Sized` predicates for why.
2549    let mut own_predicates = Vec::new();
2550    let mut parent_predicates = Vec::new();
2551    let mut own_assoc_ty_bounds = Vec::new();
2552    let mut parent_assoc_ty_bounds = Vec::new();
2553    let own_implicit_trait_predicate = implicit_trait_predicate(interner, def);
2554    let parent_implicit_trait_predicate = if let Some(parent) = generics.parent() {
2555        implicit_trait_predicate(interner, parent.def())
2556    } else {
2557        None
2558    };
2559    for maybe_parent_generics in generics.iter_owners() {
2560        // Collect only diagnostics from the child, not including parents.
2561        ctx.diagnostics.clear();
2562
2563        ctx.set_owner(maybe_parent_generics);
2564        for pred in maybe_parent_generics.where_predicates() {
2565            tracing::debug!(?pred);
2566            for (pred, source) in ctx.lower_where_predicate(pred, false) {
2567                match source {
2568                    GenericPredicateSource::SelfOnly => {
2569                        if maybe_parent_generics.def() == def {
2570                            own_predicates.push(pred);
2571                        } else {
2572                            parent_predicates.push(pred);
2573                        }
2574                    }
2575                    GenericPredicateSource::AssocTyBound => {
2576                        if maybe_parent_generics.def() == def {
2577                            own_assoc_ty_bounds.push(pred);
2578                        } else {
2579                            parent_assoc_ty_bounds.push(pred);
2580                        }
2581                    }
2582                }
2583            }
2584        }
2585
2586        if maybe_parent_generics.def() == def {
2587            push_const_arg_has_type_predicates(db, &mut own_predicates, maybe_parent_generics);
2588        } else {
2589            push_const_arg_has_type_predicates(db, &mut parent_predicates, maybe_parent_generics);
2590        }
2591
2592        if let Some(sized_trait) = sized_trait {
2593            let mut add_sized_clause = |param_idx, param_id, param_data| {
2594                let (
2595                    GenericParamId::TypeParamId(param_id),
2596                    GenericParamDataRef::TypeParamData(param_data),
2597                ) = (param_id, param_data)
2598                else {
2599                    return;
2600                };
2601
2602                if param_data.provenance == TypeParamProvenance::TraitSelf {
2603                    return;
2604                }
2605
2606                let param_ty = Ty::new_param(interner, param_id, param_idx);
2607                if ctx.unsized_types.contains(&param_ty) {
2608                    return;
2609                }
2610                let trait_ref = TraitRef::new_from_args(
2611                    interner,
2612                    sized_trait.into(),
2613                    GenericArgs::new_from_slice(&[param_ty.into()]),
2614                );
2615                let clause = Clause(Predicate::new(
2616                    interner,
2617                    Binder::dummy(rustc_type_ir::PredicateKind::Clause(
2618                        rustc_type_ir::ClauseKind::Trait(TraitPredicate {
2619                            trait_ref,
2620                            polarity: rustc_type_ir::PredicatePolarity::Positive,
2621                        }),
2622                    )),
2623                ));
2624                if maybe_parent_generics.def() == def {
2625                    own_predicates.push(clause);
2626                } else {
2627                    parent_predicates.push(clause);
2628                }
2629            };
2630            maybe_parent_generics.iter_with_idx().for_each(|(param_idx, param_id, param_data)| {
2631                add_sized_clause(param_idx, param_id, param_data);
2632            });
2633        }
2634
2635        // We do not clear `ctx.unsized_types`, as the `?Sized` clause of a child (e.g. an associated type) can
2636        // be declared on the parent (e.g. the trait). It is nevertheless fine to register the implicit `Sized`
2637        // predicates before lowering the child, as a child cannot define a `?Sized` predicate for its parent.
2638        // But we do have to lower the parent first.
2639    }
2640
2641    let diagnostics = mem::take(&mut ctx.diagnostics);
2642    let defined_anon_consts = mem::take(&mut ctx.defined_anon_consts);
2643
2644    let predicates = parent_implicit_trait_predicate
2645        .iter()
2646        .chain(own_implicit_trait_predicate.iter())
2647        .chain(parent_assoc_ty_bounds.iter())
2648        .chain(parent_predicates.iter())
2649        .chain(own_predicates.iter())
2650        .chain(own_assoc_ty_bounds.iter())
2651        .copied()
2652        .collect::<Vec<_>>();
2653    let has_trait_implied_predicate =
2654        parent_implicit_trait_predicate.is_some() || own_implicit_trait_predicate.is_some();
2655    let parent_explicit_self_predicates_start =
2656        has_trait_implied_predicate as u32 + parent_assoc_ty_bounds.len() as u32;
2657    let own_predicates_start =
2658        parent_explicit_self_predicates_start + parent_predicates.len() as u32;
2659    let own_assoc_ty_bounds_start = own_predicates_start + own_predicates.len() as u32;
2660
2661    let predicates = GenericPredicates {
2662        has_trait_implied_predicate,
2663        parent_explicit_self_predicates_start,
2664        own_predicates_start,
2665        own_assoc_ty_bounds_start,
2666        predicates: StoredEarlyBinder::bind(Clauses::new_from_slice(&predicates).store()),
2667    };
2668    return TyLoweringResult::new(predicates, diagnostics, defined_anon_consts);
2669
2670    fn implicit_trait_predicate<'db>(
2671        interner: DbInterner<'db>,
2672        def: GenericDefId,
2673    ) -> Option<Clause<'db>> {
2674        // For traits, add `Self: Trait` predicate. This is
2675        // not part of the predicates that a user writes, but it
2676        // is something that one must prove in order to invoke a
2677        // method or project an associated type.
2678        //
2679        // In the chalk setup, this predicate is not part of the
2680        // "predicates" for a trait item. But it is useful in
2681        // rustc because if you directly (e.g.) invoke a trait
2682        // method like `Trait::method(...)`, you must naturally
2683        // prove that the trait applies to the types that were
2684        // used, and adding the predicate into this list ensures
2685        // that this is done.
2686        if let GenericDefId::TraitId(def_id) = def {
2687            Some(TraitRef::identity(interner, def_id.into()).upcast(interner))
2688        } else {
2689            None
2690        }
2691    }
2692}
2693
2694fn push_const_arg_has_type_predicates<'db>(
2695    db: &'db dyn HirDatabase,
2696    predicates: &mut Vec<Clause<'db>>,
2697    single_generics: &SingleGenerics<'db>,
2698) {
2699    let interner = DbInterner::new_no_crate(db);
2700    for (param_index, param_id, _) in single_generics.iter_with_idx() {
2701        let GenericParamId::ConstParamId(param_id) = param_id else { continue };
2702        predicates.push(Clause(
2703            ClauseKind::ConstArgHasType(
2704                Const::new_param(interner, ParamConst { id: param_id, index: param_index }),
2705                db.const_param_ty(param_id),
2706            )
2707            .upcast(interner),
2708        ));
2709    }
2710}
2711
2712#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2713pub struct GenericDefaults(ThinVec<Option<StoredEarlyBinder<StoredGenericArg>>>);
2714
2715impl GenericDefaults {
2716    #[inline]
2717    pub fn as_ref(&self) -> GenericDefaultsRef<'_> {
2718        GenericDefaultsRef(&self.0)
2719    }
2720}
2721
2722#[derive(Debug, Clone, Copy)]
2723pub struct GenericDefaultsRef<'db>(&'db [Option<StoredEarlyBinder<StoredGenericArg>>]);
2724
2725impl<'db> GenericDefaultsRef<'db> {
2726    #[inline]
2727    pub fn get(self, idx: usize) -> Option<EarlyBinder<'db, GenericArg<'db>>> {
2728        Some(self.0.get(idx)?.as_ref()?.get())
2729    }
2730}
2731
2732pub(crate) fn generic_defaults(db: &dyn HirDatabase, def: GenericDefId) -> GenericDefaultsRef<'_> {
2733    generic_defaults_with_diagnostics(db, def).value.as_ref()
2734}
2735
2736/// Resolve the default type params from generics.
2737///
2738/// Diagnostics are only returned for this `GenericDefId` (returned defaults include parents).
2739#[salsa::tracked(returns(ref), cycle_result = generic_defaults_with_diagnostics_cycle_result)]
2740pub(crate) fn generic_defaults_with_diagnostics<'db>(
2741    db: &'db dyn HirDatabase,
2742    def: GenericDefId,
2743) -> TyLoweringResult<'db, GenericDefaults> {
2744    let generics = generics(db, def);
2745    if generics.has_no_params() {
2746        return TyLoweringResult::empty(GenericDefaults(ThinVec::new()));
2747    }
2748    let resolver = def.resolver(db);
2749
2750    let store_for_self = generics.store();
2751    let generics = &OnceCell::from(generics);
2752    let mut ctx = TyLoweringContext::new(
2753        db,
2754        &resolver,
2755        store_for_self,
2756        ExpressionStoreOwnerId::Signature(def),
2757        def,
2758        generics,
2759        LifetimeElisionKind::AnonymousReportError,
2760        LifetimeLoweringMode::Bound,
2761    )
2762    .with_impl_trait_mode(ImplTraitLoweringMode::Disallowed);
2763    let generics = generics.get().unwrap();
2764    let mut defaults = ThinVec::new();
2765    if let Some(parent) = generics.parent() {
2766        ctx.set_owner(parent);
2767        defaults.extend(
2768            parent.iter_with_idx().map(|(idx, _id, p)| handle_generic_param(&mut ctx, idx, p)),
2769        );
2770    }
2771    ctx.diagnostics.clear(); // Don't include diagnostics from the parent.
2772    ctx.defined_anon_consts.clear();
2773    ctx.set_owner(generics.owner());
2774    defaults.extend(
2775        generics.iter_self_with_idx().map(|(idx, _id, p)| handle_generic_param(&mut ctx, idx, p)),
2776    );
2777    defaults.shrink_to_fit();
2778    return TyLoweringResult::from_ctx(GenericDefaults(defaults), ctx);
2779
2780    fn handle_generic_param<'db>(
2781        ctx: &mut TyLoweringContext<'db, '_>,
2782        idx: u32,
2783        p: GenericParamDataRef<'_>,
2784    ) -> Option<StoredEarlyBinder<StoredGenericArg>> {
2785        ctx.forbid_params_after(idx, ForbidParamsAfterReason::LoweringParamDefault);
2786        match p {
2787            GenericParamDataRef::TypeParamData(p) => {
2788                let ty = p.default.map(|ty| ctx.lower_ty(ty));
2789                ty.map(|ty| StoredEarlyBinder::bind(GenericArg::from(ty).store()))
2790            }
2791            GenericParamDataRef::ConstParamData(p) => {
2792                let val = p.default.map(|c| {
2793                    let param_ty = ctx.lower_ty(p.ty);
2794                    let c = ctx.lower_const(c, param_ty);
2795                    GenericArg::from(c).store()
2796                });
2797                val.map(StoredEarlyBinder::bind)
2798            }
2799            GenericParamDataRef::LifetimeParamData(_) => None,
2800        }
2801    }
2802}
2803
2804fn generic_defaults_with_diagnostics_cycle_result<'db>(
2805    _db: &'db dyn HirDatabase,
2806    _: salsa::Id,
2807    _def: GenericDefId,
2808) -> TyLoweringResult<'db, GenericDefaults> {
2809    TyLoweringResult::empty(GenericDefaults(ThinVec::new()))
2810}
2811
2812/// Build the signature of a callable item (function, struct or enum variant).
2813pub(crate) fn callable_item_signature<'db>(
2814    db: &'db dyn HirDatabase,
2815    def: CallableDefId,
2816) -> EarlyBinder<'db, PolyFnSig<'db>> {
2817    callable_item_signature_with_diagnostics(db, def).value.get()
2818}
2819
2820#[salsa::tracked(returns(ref))]
2821pub(crate) fn callable_item_signature_with_diagnostics<'db>(
2822    db: &'db dyn HirDatabase,
2823    def: CallableDefId,
2824) -> TyLoweringResult<'db, StoredEarlyBinder<StoredPolyFnSig>> {
2825    match def {
2826        CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f),
2827        CallableDefId::StructId(s) => TyLoweringResult::empty(fn_sig_for_struct_constructor(db, s)),
2828        CallableDefId::EnumVariantId(e) => {
2829            TyLoweringResult::empty(fn_sig_for_enum_variant_constructor(db, e))
2830        }
2831    }
2832}
2833
2834fn fn_sig_for_fn<'db>(
2835    db: &'db dyn HirDatabase,
2836    def: FunctionId,
2837) -> TyLoweringResult<'db, StoredEarlyBinder<StoredPolyFnSig>> {
2838    let data = FunctionSignature::of(db, def);
2839    let resolver = def.resolver(db);
2840    let interner = DbInterner::new_no_crate(db);
2841    let generics = OnceCell::new();
2842    let mut ctx_params = TyLoweringContext::new(
2843        db,
2844        &resolver,
2845        &data.store,
2846        ExpressionStoreOwnerId::Signature(def.into()),
2847        def.into(),
2848        &generics,
2849        LifetimeElisionKind::for_fn_params(data),
2850        LifetimeLoweringMode::Bound,
2851    );
2852    let params = data.params.iter().map(|&tr| ctx_params.lower_ty(tr));
2853
2854    let mut ctx_ret = TyLoweringContext::new(
2855        db,
2856        &resolver,
2857        &data.store,
2858        ExpressionStoreOwnerId::Signature(def.into()),
2859        def.into(),
2860        &generics,
2861        LifetimeElisionKind::for_fn_ret(interner),
2862        LifetimeLoweringMode::Bound,
2863    )
2864    .with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
2865    let ret = match data.ret_type {
2866        Some(ret_type) => ctx_ret.lower_ty(ret_type),
2867        None => Ty::new_unit(interner),
2868    };
2869
2870    let inputs_and_output = Tys::new_from_iter(interner, params.chain(Some(ret)));
2871    ctx_params.diagnostics.extend(ctx_ret.diagnostics);
2872    ctx_params.defined_anon_consts.extend(ctx_ret.defined_anon_consts);
2873
2874    let binder = TyLoweringContext::bound_vars(db, interner, def.into(), &generics);
2875    let result = StoredEarlyBinder::bind(StoredPolyFnSig::new(Binder::bind_with_vars(
2876        FnSig {
2877            inputs_and_output,
2878            fn_sig_kind: FnSigKind::new(
2879                data.abi,
2880                if data.is_unsafe() { Safety::Unsafe } else { Safety::Safe },
2881                data.is_varargs(),
2882            ),
2883        },
2884        binder,
2885    )));
2886    TyLoweringResult::from_ctx(result, ctx_params)
2887}
2888
2889fn type_for_adt<'db>(db: &'db dyn HirDatabase, adt: AdtId) -> EarlyBinder<'db, Ty<'db>> {
2890    let interner = DbInterner::new_no_crate(db);
2891    let args = GenericArgs::identity_for_item(interner, adt.into());
2892    let ty = Ty::new_adt(interner, adt, args);
2893    EarlyBinder::bind(ty)
2894}
2895
2896fn fn_sig_for_struct_constructor(
2897    db: &dyn HirDatabase,
2898    def: StructId,
2899) -> StoredEarlyBinder<StoredPolyFnSig> {
2900    let field_tys = db.field_types(def.into());
2901    let params = field_tys.iter().map(|(_, field)| field.ty().skip_binder());
2902    let ret = type_for_adt(db, def.into()).skip_binder();
2903
2904    let inputs_and_output =
2905        Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret)));
2906    StoredEarlyBinder::bind(StoredPolyFnSig::new(Binder::dummy(FnSig {
2907        fn_sig_kind: FnSigKind::new(ExternAbi::Rust, Safety::Safe, false),
2908        inputs_and_output,
2909    })))
2910}
2911
2912fn fn_sig_for_enum_variant_constructor(
2913    db: &dyn HirDatabase,
2914    def: EnumVariantId,
2915) -> StoredEarlyBinder<StoredPolyFnSig> {
2916    let field_tys = db.field_types(def.into());
2917    let params = field_tys.iter().map(|(_, field)| field.ty().skip_binder());
2918    let parent = def.lookup(db).parent;
2919    let ret = type_for_adt(db, parent.into()).skip_binder();
2920
2921    let inputs_and_output =
2922        Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret)));
2923    StoredEarlyBinder::bind(StoredPolyFnSig::new(Binder::dummy(FnSig {
2924        fn_sig_kind: FnSigKind::new(ExternAbi::Rust, Safety::Safe, false),
2925        inputs_and_output,
2926    })))
2927}
2928
2929// FIXME: Remove this.
2930pub(crate) fn associated_ty_item_bounds<'db>(
2931    db: &'db dyn HirDatabase,
2932    type_alias: TypeAliasId,
2933) -> EarlyBinder<'db, BoundExistentialPredicates<'db>> {
2934    let type_alias_data = TypeAliasSignature::of(db, type_alias);
2935    let resolver = type_alias.resolver(db);
2936    let interner = DbInterner::new_no_crate(db);
2937    let generics = OnceCell::new();
2938    let mut ctx = TyLoweringContext::new(
2939        db,
2940        &resolver,
2941        &type_alias_data.store,
2942        ExpressionStoreOwnerId::Signature(type_alias.into()),
2943        type_alias.into(),
2944        &generics,
2945        LifetimeElisionKind::AnonymousReportError,
2946        LifetimeLoweringMode::Bound,
2947    );
2948    // FIXME: we should never create non-existential predicates in the first place
2949    // For now, use an error type so we don't run into dummy binder issues
2950    let self_ty = Ty::new_error(interner, ErrorGuaranteed);
2951
2952    let mut bounds = Vec::new();
2953    for bound in &type_alias_data.bounds {
2954        ctx.lower_type_bound(bound, self_ty, false).for_each(|(pred, _)| {
2955            if let Some(bound) = pred
2956                .kind()
2957                .map_bound(|c| match c {
2958                    rustc_type_ir::ClauseKind::Trait(t) => {
2959                        let id = t.def_id();
2960                        let is_auto = TraitSignature::of(db, id.0).flags.contains(TraitFlags::AUTO);
2961                        if is_auto {
2962                            Some(ExistentialPredicate::AutoTrait(t.def_id()))
2963                        } else {
2964                            Some(ExistentialPredicate::Trait(ExistentialTraitRef::new_from_args(
2965                                interner,
2966                                t.def_id(),
2967                                GenericArgs::new_from_slice(&t.trait_ref.args[1..]),
2968                            )))
2969                        }
2970                    }
2971                    rustc_type_ir::ClauseKind::Projection(p) => Some(
2972                        ExistentialPredicate::Projection(ExistentialProjection::new_from_args(
2973                            interner,
2974                            p.def_id(),
2975                            GenericArgs::new_from_slice(&p.projection_term.args[1..]),
2976                            p.term,
2977                        )),
2978                    ),
2979                    rustc_type_ir::ClauseKind::TypeOutlives(_) => None,
2980                    rustc_type_ir::ClauseKind::RegionOutlives(_)
2981                    | rustc_type_ir::ClauseKind::ConstArgHasType(_, _)
2982                    | rustc_type_ir::ClauseKind::WellFormed(_)
2983                    | rustc_type_ir::ClauseKind::ConstEvaluatable(_)
2984                    | rustc_type_ir::ClauseKind::HostEffect(_)
2985                    | rustc_type_ir::ClauseKind::UnstableFeature(_) => unreachable!(),
2986                })
2987                .transpose()
2988            {
2989                bounds.push(bound);
2990            }
2991        });
2992    }
2993
2994    if !ctx.unsized_types.contains(&self_ty)
2995        && let Some(sized_trait) = ctx.lang_items.Sized
2996    {
2997        let sized_clause = Binder::dummy(ExistentialPredicate::Trait(ExistentialTraitRef::new(
2998            interner,
2999            sized_trait.into(),
3000            [] as [GenericArg<'_>; 0],
3001        )));
3002        bounds.push(sized_clause);
3003    }
3004
3005    EarlyBinder::bind(BoundExistentialPredicates::new_from_slice(&bounds))
3006}
3007
3008pub(crate) fn associated_type_by_name_including_super_traits_allow_ambiguity<'db>(
3009    db: &'db dyn HirDatabase,
3010    trait_ref: TraitRef<'db>,
3011    name: Name,
3012) -> Option<(TypeAliasId, GenericArgs<'db>)> {
3013    let (AssocTypeShorthandResolution::Resolved(assoc_type)
3014    | AssocTypeShorthandResolution::Ambiguous { sub_trait_resolution: Some(assoc_type) }) =
3015        resolve_type_param_assoc_type_shorthand(
3016            db,
3017            trait_ref.def_id.0.into(),
3018            TypeParamId::trait_self(trait_ref.def_id.0),
3019            name.clone(),
3020        )
3021    else {
3022        return None;
3023    };
3024    let (assoc_type, trait_args) = assoc_type
3025        .get_with(|(assoc_type, trait_args)| (*assoc_type, trait_args.as_ref()))
3026        .skip_binder();
3027    let interner = DbInterner::new_no_crate(db);
3028    Some((
3029        assoc_type,
3030        EarlyBinder::bind(trait_args).instantiate(interner, trait_ref.args).skip_norm_wip(),
3031    ))
3032}