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