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