1pub(crate) mod diagnostics;
9pub(crate) mod path;
10
11use std::{
12    cell::OnceCell,
13    iter, mem,
14    ops::{self, Deref, Not as _},
15};
16
17use base_db::Crate;
18use either::Either;
19use hir_def::{
20    AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId,
21    FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
22    LocalFieldId, Lookup, StaticId, StructId, TypeAliasId, TypeOrConstParamId, TypeParamId,
23    UnionId, VariantId,
24    builtin_type::BuiltinType,
25    expr_store::{ExpressionStore, HygieneId, path::Path},
26    hir::generics::{
27        GenericParamDataRef, TypeOrConstParamData, TypeParamProvenance, WherePredicate,
28    },
29    item_tree::FieldsShape,
30    lang_item::LangItem,
31    resolver::{HasResolver, LifetimeNs, Resolver, TypeNs, ValueNs},
32    signatures::{FunctionSignature, TraitFlags, TypeAliasFlags},
33    type_ref::{
34        ConstRef, LifetimeRefId, LiteralConstRef, PathId, TraitBoundModifier,
35        TraitRef as HirTraitRef, TypeBound, TypeRef, TypeRefId,
36    },
37};
38use hir_expand::name::Name;
39use la_arena::{Arena, ArenaMap, Idx};
40use path::{PathDiagnosticCallback, PathLoweringContext};
41use rustc_ast_ir::Mutability;
42use rustc_hash::FxHashSet;
43use rustc_pattern_analysis::Captures;
44use rustc_type_ir::{
45    AliasTyKind, BoundVarIndexKind, ConstKind, DebruijnIndex, ExistentialPredicate,
46    ExistentialProjection, ExistentialTraitRef, FnSig, OutlivesPredicate,
47    TyKind::{self},
48    TypeVisitableExt,
49    inherent::{GenericArg as _, GenericArgs as _, IntoKind as _, Region as _, SliceLike, Ty as _},
50};
51use salsa::plumbing::AsId;
52use smallvec::{SmallVec, smallvec};
53use stdx::{impl_from, never};
54use triomphe::{Arc, ThinArc};
55
56use crate::{
57    FnAbi, ImplTraitId, TraitEnvironment, TyLoweringDiagnostic, TyLoweringDiagnosticKind,
58    consteval::intern_const_ref,
59    db::HirDatabase,
60    generics::{Generics, generics, trait_self_param_idx},
61    next_solver::{
62        AliasTy, Binder, BoundExistentialPredicates, Clause, Clauses, Const, DbInterner,
63        EarlyBinder, EarlyParamRegion, ErrorGuaranteed, GenericArg, GenericArgs, ParamConst,
64        ParamEnv, PolyFnSig, Predicate, Region, SolverDefId, TraitPredicate, TraitRef, Ty, Tys,
65        UnevaluatedConst, abi::Safety,
66    },
67};
68
69pub(crate) struct PathDiagnosticCallbackData(pub(crate) TypeRefId);
70
71#[derive(PartialEq, Eq, Debug, Hash)]
72pub struct ImplTraits<'db> {
73    pub(crate) impl_traits: Arena<ImplTrait<'db>>,
74}
75
76#[derive(PartialEq, Eq, Debug, Hash)]
77pub struct ImplTrait<'db> {
78    pub(crate) predicates: Vec<Clause<'db>>,
79}
80
81pub type ImplTraitIdx<'db> = Idx<ImplTrait<'db>>;
82
83#[derive(Debug, Default)]
84struct ImplTraitLoweringState<'db> {
85    mode: ImplTraitLoweringMode,
89    opaque_type_data: Arena<ImplTrait<'db>>,
91}
92
93impl<'db> ImplTraitLoweringState<'db> {
94    fn new(mode: ImplTraitLoweringMode) -> ImplTraitLoweringState<'db> {
95        Self { mode, opaque_type_data: Arena::new() }
96    }
97}
98
99#[derive(Debug, Clone)]
100pub enum LifetimeElisionKind<'db> {
101    AnonymousCreateParameter { report_in_path: bool },
116
117    Elided(Region<'db>),
119
120    AnonymousReportError,
124
125    StaticIfNoLifetimeInScope { only_lint: bool },
129
130    ElisionFailure,
132
133    Infer,
135}
136
137impl<'db> LifetimeElisionKind<'db> {
138    #[inline]
139    pub(crate) fn for_const(
140        interner: DbInterner<'db>,
141        const_parent: ItemContainerId,
142    ) -> LifetimeElisionKind<'db> {
143        match const_parent {
144            ItemContainerId::ExternBlockId(_) | ItemContainerId::ModuleId(_) => {
145                LifetimeElisionKind::Elided(Region::new_static(interner))
146            }
147            ItemContainerId::ImplId(_) => {
148                LifetimeElisionKind::StaticIfNoLifetimeInScope { only_lint: true }
149            }
150            ItemContainerId::TraitId(_) => {
151                LifetimeElisionKind::StaticIfNoLifetimeInScope { only_lint: false }
152            }
153        }
154    }
155
156    #[inline]
157    pub(crate) fn for_fn_params(data: &FunctionSignature) -> LifetimeElisionKind<'db> {
158        LifetimeElisionKind::AnonymousCreateParameter { report_in_path: data.is_async() }
159    }
160
161    #[inline]
162    pub(crate) fn for_fn_ret(interner: DbInterner<'db>) -> LifetimeElisionKind<'db> {
163        LifetimeElisionKind::Elided(Region::error(interner))
165    }
166}
167
168#[derive(Debug)]
169pub struct TyLoweringContext<'db, 'a> {
170    pub db: &'db dyn HirDatabase,
171    interner: DbInterner<'db>,
172    resolver: &'a Resolver<'db>,
173    store: &'a ExpressionStore,
174    def: GenericDefId,
175    generics: OnceCell<Generics>,
176    in_binders: DebruijnIndex,
177    impl_trait_mode: ImplTraitLoweringState<'db>,
178    pub(crate) unsized_types: FxHashSet<Ty<'db>>,
180    pub(crate) diagnostics: Vec<TyLoweringDiagnostic>,
181    lifetime_elision: LifetimeElisionKind<'db>,
182    lowering_param_default: Option<u32>,
185}
186
187impl<'db, 'a> TyLoweringContext<'db, 'a> {
188    pub fn new(
189        db: &'db dyn HirDatabase,
190        resolver: &'a Resolver<'db>,
191        store: &'a ExpressionStore,
192        def: GenericDefId,
193        lifetime_elision: LifetimeElisionKind<'db>,
194    ) -> Self {
195        let impl_trait_mode = ImplTraitLoweringState::new(ImplTraitLoweringMode::Disallowed);
196        let in_binders = DebruijnIndex::ZERO;
197        Self {
198            db,
199            interner: DbInterner::new_with(db, Some(resolver.krate()), None),
200            resolver,
201            def,
202            generics: Default::default(),
203            store,
204            in_binders,
205            impl_trait_mode,
206            unsized_types: FxHashSet::default(),
207            diagnostics: Vec::new(),
208            lifetime_elision,
209            lowering_param_default: None,
210        }
211    }
212
213    pub(crate) fn set_lifetime_elision(&mut self, lifetime_elision: LifetimeElisionKind<'db>) {
214        self.lifetime_elision = lifetime_elision;
215    }
216
217    pub(crate) fn with_debruijn<T>(
218        &mut self,
219        debruijn: DebruijnIndex,
220        f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> T,
221    ) -> T {
222        let old_debruijn = mem::replace(&mut self.in_binders, debruijn);
223        let result = f(self);
224        self.in_binders = old_debruijn;
225        result
226    }
227
228    pub(crate) fn with_shifted_in<T>(
229        &mut self,
230        debruijn: DebruijnIndex,
231        f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> T,
232    ) -> T {
233        self.with_debruijn(self.in_binders.shifted_in(debruijn.as_u32()), f)
234    }
235
236    pub(crate) fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
237        Self { impl_trait_mode: ImplTraitLoweringState::new(impl_trait_mode), ..self }
238    }
239
240    pub(crate) fn impl_trait_mode(&mut self, impl_trait_mode: ImplTraitLoweringMode) -> &mut Self {
241        self.impl_trait_mode = ImplTraitLoweringState::new(impl_trait_mode);
242        self
243    }
244
245    pub(crate) fn lowering_param_default(&mut self, index: u32) {
246        self.lowering_param_default = Some(index);
247    }
248
249    pub(crate) fn push_diagnostic(&mut self, type_ref: TypeRefId, kind: TyLoweringDiagnosticKind) {
250        self.diagnostics.push(TyLoweringDiagnostic { source: type_ref, kind });
251    }
252}
253
254#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
255pub(crate) enum ImplTraitLoweringMode {
256    Opaque,
261    #[default]
263    Disallowed,
264}
265
266impl<'db, 'a> TyLoweringContext<'db, 'a> {
267    pub fn lower_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> {
268        self.lower_ty_ext(type_ref).0
269    }
270
271    pub(crate) fn lower_const(&mut self, const_ref: ConstRef, const_type: Ty<'db>) -> Const<'db> {
272        let const_ref = &self.store[const_ref.expr];
273        match const_ref {
274            hir_def::hir::Expr::Path(path) => {
275                self.path_to_const(path).unwrap_or_else(|| unknown_const(const_type))
276            }
277            hir_def::hir::Expr::Literal(literal) => intern_const_ref(
278                self.db,
279                &match *literal {
280                    hir_def::hir::Literal::Float(_, _)
281                    | hir_def::hir::Literal::String(_)
282                    | hir_def::hir::Literal::ByteString(_)
283                    | hir_def::hir::Literal::CString(_) => LiteralConstRef::Unknown,
284                    hir_def::hir::Literal::Char(c) => LiteralConstRef::Char(c),
285                    hir_def::hir::Literal::Bool(b) => LiteralConstRef::Bool(b),
286                    hir_def::hir::Literal::Int(val, _) => LiteralConstRef::Int(val),
287                    hir_def::hir::Literal::Uint(val, _) => LiteralConstRef::UInt(val),
288                },
289                const_type,
290                self.resolver.krate(),
291            ),
292            hir_def::hir::Expr::UnaryOp { expr: inner_expr, op: hir_def::hir::UnaryOp::Neg } => {
293                if let hir_def::hir::Expr::Literal(literal) = &self.store[*inner_expr] {
294                    match literal {
296                        hir_def::hir::Literal::Int(_, _) | hir_def::hir::Literal::Float(_, _) => {
297                            if let Some(negated_literal) = literal.clone().negate() {
298                                intern_const_ref(
299                                    self.db,
300                                    &negated_literal.into(),
301                                    const_type,
302                                    self.resolver.krate(),
303                                )
304                            } else {
305                                unknown_const(const_type)
306                            }
307                        }
308                        _ => unknown_const(const_type),
310                    }
311                } else {
312                    unknown_const(const_type)
313                }
314            }
315            _ => unknown_const(const_type),
316        }
317    }
318
319    pub(crate) fn path_to_const(&mut self, path: &Path) -> Option<Const<'db>> {
320        match self.resolver.resolve_path_in_value_ns_fully(self.db, path, HygieneId::ROOT) {
321            Some(ValueNs::GenericParam(p)) => {
322                let args = self.generics();
323                match args.type_or_const_param_idx(p.into()) {
324                    Some(idx) => Some(self.const_param(p, idx as u32)),
325                    None => {
326                        never!(
327                            "Generic list doesn't contain this param: {:?}, {:?}, {:?}",
328                            args,
329                            path,
330                            p
331                        );
332                        None
333                    }
334                }
335            }
336            Some(ValueNs::ConstId(c)) => {
337                let args = GenericArgs::new_from_iter(self.interner, []);
338                Some(Const::new(
339                    self.interner,
340                    rustc_type_ir::ConstKind::Unevaluated(UnevaluatedConst::new(
341                        SolverDefId::ConstId(c),
342                        args,
343                    )),
344                ))
345            }
346            _ => None,
347        }
348    }
349
350    pub(crate) fn lower_path_as_const(&mut self, path: &Path, const_type: Ty<'db>) -> Const<'db> {
351        self.path_to_const(path).unwrap_or_else(|| unknown_const(const_type))
352    }
353
354    fn generics(&self) -> &Generics {
355        self.generics.get_or_init(|| generics(self.db, self.def))
356    }
357
358    fn param_index_is_disallowed(&self, index: u32) -> bool {
359        self.lowering_param_default
360            .is_some_and(|disallow_params_after| index >= disallow_params_after)
361    }
362
363    fn type_param(&mut self, id: TypeParamId, index: u32) -> Ty<'db> {
364        if self.param_index_is_disallowed(index) {
365            Ty::new_error(self.interner, ErrorGuaranteed)
367        } else {
368            Ty::new_param(self.interner, id, index)
369        }
370    }
371
372    fn const_param(&mut self, id: ConstParamId, index: u32) -> Const<'db> {
373        if self.param_index_is_disallowed(index) {
374            Const::error(self.interner)
376        } else {
377            Const::new_param(self.interner, ParamConst { id, index })
378        }
379    }
380
381    fn region_param(&mut self, id: LifetimeParamId, index: u32) -> Region<'db> {
382        if self.param_index_is_disallowed(index) {
383            Region::error(self.interner)
385        } else {
386            Region::new_early_param(self.interner, EarlyParamRegion { id, index })
387        }
388    }
389
390    #[tracing::instrument(skip(self), ret)]
391    pub fn lower_ty_ext(&mut self, type_ref_id: TypeRefId) -> (Ty<'db>, Option<TypeNs>) {
392        let interner = self.interner;
393        let mut res = None;
394        let type_ref = &self.store[type_ref_id];
395        tracing::debug!(?type_ref);
396        let ty = match type_ref {
397            TypeRef::Never => Ty::new(interner, TyKind::Never),
398            TypeRef::Tuple(inner) => {
399                let inner_tys = inner.iter().map(|&tr| self.lower_ty(tr));
400                Ty::new_tup_from_iter(interner, inner_tys)
401            }
402            TypeRef::Path(path) => {
403                let (ty, res_) =
404                    self.lower_path(path, PathId::from_type_ref_unchecked(type_ref_id));
405                res = res_;
406                ty
407            }
408            &TypeRef::TypeParam(type_param_id) => {
409                res = Some(TypeNs::GenericParam(type_param_id));
410
411                let generics = self.generics();
412                let (idx, _data) =
413                    generics.type_or_const_param(type_param_id.into()).expect("matching generics");
414                self.type_param(type_param_id, idx as u32)
415            }
416            &TypeRef::RawPtr(inner, mutability) => {
417                let inner_ty = self.lower_ty(inner);
418                Ty::new(interner, TyKind::RawPtr(inner_ty, lower_mutability(mutability)))
419            }
420            TypeRef::Array(array) => {
421                let inner_ty = self.lower_ty(array.ty);
422                let const_len = self.lower_const(array.len, Ty::new_usize(interner));
423                Ty::new_array_with_const_len(interner, inner_ty, const_len)
424            }
425            &TypeRef::Slice(inner) => {
426                let inner_ty = self.lower_ty(inner);
427                Ty::new_slice(interner, inner_ty)
428            }
429            TypeRef::Reference(ref_) => {
430                let inner_ty = self.lower_ty(ref_.ty);
431                let lifetime = ref_
433                    .lifetime
434                    .map_or_else(|| Region::error(interner), |lr| self.lower_lifetime(lr));
435                Ty::new_ref(interner, lifetime, inner_ty, lower_mutability(ref_.mutability))
436            }
437            TypeRef::Placeholder => Ty::new_error(interner, ErrorGuaranteed),
438            TypeRef::Fn(fn_) => {
439                let substs = self.with_shifted_in(
440                    DebruijnIndex::from_u32(1),
441                    |ctx: &mut TyLoweringContext<'_, '_>| {
442                        Tys::new_from_iter(
443                            interner,
444                            fn_.params.iter().map(|&(_, tr)| ctx.lower_ty(tr)),
445                        )
446                    },
447                );
448                Ty::new_fn_ptr(
449                    interner,
450                    Binder::dummy(FnSig {
451                        abi: fn_.abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol),
452                        safety: if fn_.is_unsafe { Safety::Unsafe } else { Safety::Safe },
453                        c_variadic: fn_.is_varargs,
454                        inputs_and_output: substs,
455                    }),
456                )
457            }
458            TypeRef::DynTrait(bounds) => self.lower_dyn_trait(bounds),
459            TypeRef::ImplTrait(bounds) => {
460                match self.impl_trait_mode.mode {
461                    ImplTraitLoweringMode::Opaque => {
462                        let origin = match self.resolver.generic_def() {
463                            Some(GenericDefId::FunctionId(it)) => Either::Left(it),
464                            Some(GenericDefId::TypeAliasId(it)) => Either::Right(it),
465                            _ => panic!(
466                                "opaque impl trait lowering must be in function or type alias"
467                            ),
468                        };
469
470                        let idx = self
474                            .impl_trait_mode
475                            .opaque_type_data
476                            .alloc(ImplTrait { predicates: Vec::default() });
477
478                        let impl_trait_id = origin.either(
479                            |f| ImplTraitId::ReturnTypeImplTrait(f, idx),
480                            |a| ImplTraitId::TypeAliasImplTrait(a, idx),
481                        );
482                        let opaque_ty_id: SolverDefId =
483                            self.db.intern_impl_trait_id(impl_trait_id).into();
484
485                        let actual_opaque_type_data = self
495                            .with_debruijn(DebruijnIndex::ZERO, |ctx| {
496                                ctx.lower_impl_trait(opaque_ty_id, bounds, self.resolver.krate())
497                            });
498                        self.impl_trait_mode.opaque_type_data[idx] = actual_opaque_type_data;
499
500                        let args = GenericArgs::identity_for_item(self.interner, opaque_ty_id);
501                        Ty::new_alias(
502                            self.interner,
503                            AliasTyKind::Opaque,
504                            AliasTy::new_from_args(self.interner, opaque_ty_id, args),
505                        )
506                    }
507                    ImplTraitLoweringMode::Disallowed => {
508                        Ty::new_error(self.interner, ErrorGuaranteed)
510                    }
511                }
512            }
513            TypeRef::Error => Ty::new_error(self.interner, ErrorGuaranteed),
514        };
515        (ty, res)
516    }
517
518    fn lower_ty_only_param(&self, type_ref: TypeRefId) -> Option<TypeOrConstParamId> {
522        let type_ref = &self.store[type_ref];
523        let path = match type_ref {
524            TypeRef::Path(path) => path,
525            &TypeRef::TypeParam(idx) => return Some(idx.into()),
526            _ => return None,
527        };
528        if path.type_anchor().is_some() {
529            return None;
530        }
531        if path.segments().len() > 1 {
532            return None;
533        }
534        let resolution = match self.resolver.resolve_path_in_type_ns(self.db, path) {
535            Some((it, None, _)) => it,
536            _ => return None,
537        };
538        match resolution {
539            TypeNs::GenericParam(param_id) => Some(param_id.into()),
540            _ => None,
541        }
542    }
543
544    #[inline]
545    fn on_path_diagnostic_callback<'b>(type_ref: TypeRefId) -> PathDiagnosticCallback<'b, 'db> {
546        PathDiagnosticCallback {
547            data: Either::Left(PathDiagnosticCallbackData(type_ref)),
548            callback: |data, this, diag| {
549                let type_ref = data.as_ref().left().unwrap().0;
550                this.push_diagnostic(type_ref, TyLoweringDiagnosticKind::PathDiagnostic(diag))
551            },
552        }
553    }
554
555    #[inline]
556    fn at_path(&mut self, path_id: PathId) -> PathLoweringContext<'_, 'a, 'db> {
557        PathLoweringContext::new(
558            self,
559            Self::on_path_diagnostic_callback(path_id.type_ref()),
560            &self.store[path_id],
561        )
562    }
563
564    pub(crate) fn lower_path(&mut self, path: &Path, path_id: PathId) -> (Ty<'db>, Option<TypeNs>) {
565        if let Some(type_ref) = path.type_anchor() {
567            let (ty, res) = self.lower_ty_ext(type_ref);
568            let mut ctx = self.at_path(path_id);
569            return ctx.lower_ty_relative_path(ty, res, false);
570        }
571
572        let mut ctx = self.at_path(path_id);
573        let (resolution, remaining_index) = match ctx.resolve_path_in_type_ns() {
574            Some(it) => it,
575            None => return (Ty::new_error(self.interner, ErrorGuaranteed), None),
576        };
577
578        if matches!(resolution, TypeNs::TraitId(_)) && remaining_index.is_none() {
579            let bound = TypeBound::Path(path_id, TraitBoundModifier::None);
581            let ty = self.lower_dyn_trait(&[bound]);
582            return (ty, None);
583        }
584
585        ctx.lower_partly_resolved_path(resolution, false)
586    }
587
588    fn lower_trait_ref_from_path(
589        &mut self,
590        path_id: PathId,
591        explicit_self_ty: Ty<'db>,
592    ) -> Option<(TraitRef<'db>, PathLoweringContext<'_, 'a, 'db>)> {
593        let mut ctx = self.at_path(path_id);
594        let resolved = match ctx.resolve_path_in_type_ns_fully()? {
595            TypeNs::TraitId(tr) => tr,
597            _ => return None,
598        };
599        Some((ctx.lower_trait_ref_from_resolved_path(resolved, explicit_self_ty, false), ctx))
600    }
601
602    fn lower_trait_ref(
603        &mut self,
604        trait_ref: &HirTraitRef,
605        explicit_self_ty: Ty<'db>,
606    ) -> Option<TraitRef<'db>> {
607        self.lower_trait_ref_from_path(trait_ref.path, explicit_self_ty).map(|it| it.0)
608    }
609
610    pub(crate) fn lower_where_predicate<'b>(
611        &'b mut self,
612        where_predicate: &'b WherePredicate,
613        ignore_bindings: bool,
614        generics: &Generics,
615        predicate_filter: PredicateFilter,
616    ) -> impl Iterator<Item = Clause<'db>> + use<'a, 'b, 'db> {
617        match where_predicate {
618            WherePredicate::ForLifetime { target, bound, .. }
619            | WherePredicate::TypeBound { target, bound } => {
620                if let PredicateFilter::SelfTrait = predicate_filter {
621                    let target_type = &self.store[*target];
622                    let self_type = 'is_self: {
623                        if let TypeRef::Path(path) = target_type
624                            && path.is_self_type()
625                        {
626                            break 'is_self true;
627                        }
628                        if let TypeRef::TypeParam(param) = target_type
629                            && generics[param.local_id()].is_trait_self()
630                        {
631                            break 'is_self true;
632                        }
633                        false
634                    };
635                    if !self_type {
636                        return Either::Left(Either::Left(iter::empty()));
637                    }
638                }
639                let self_ty = self.lower_ty(*target);
640                Either::Left(Either::Right(self.lower_type_bound(bound, self_ty, ignore_bindings)))
641            }
642            &WherePredicate::Lifetime { bound, target } => {
643                Either::Right(iter::once(Clause(Predicate::new(
644                    self.interner,
645                    Binder::dummy(rustc_type_ir::PredicateKind::Clause(
646                        rustc_type_ir::ClauseKind::RegionOutlives(OutlivesPredicate(
647                            self.lower_lifetime(bound),
648                            self.lower_lifetime(target),
649                        )),
650                    )),
651                ))))
652            }
653        }
654        .into_iter()
655    }
656
657    pub(crate) fn lower_type_bound<'b>(
658        &'b mut self,
659        bound: &'b TypeBound,
660        self_ty: Ty<'db>,
661        ignore_bindings: bool,
662    ) -> impl Iterator<Item = Clause<'db>> + use<'b, 'a, 'db> {
663        let interner = self.interner;
664        let mut assoc_bounds = None;
665        let mut clause = None;
666        match bound {
667            &TypeBound::Path(path, TraitBoundModifier::None) | &TypeBound::ForLifetime(_, path) => {
668                if let Some((trait_ref, mut ctx)) = self.lower_trait_ref_from_path(path, self_ty) {
670                    let meta_sized = LangItem::MetaSized
673                        .resolve_trait(ctx.ty_ctx().db, ctx.ty_ctx().resolver.krate());
674                    let pointee_sized = LangItem::PointeeSized
675                        .resolve_trait(ctx.ty_ctx().db, ctx.ty_ctx().resolver.krate());
676                    if meta_sized.is_some_and(|it| it == trait_ref.def_id.0) {
677                        } else if pointee_sized.is_some_and(|it| it == trait_ref.def_id.0) {
679                        ctx.ty_ctx().unsized_types.insert(self_ty);
681                    } else {
682                        if !ignore_bindings {
683                            assoc_bounds = ctx.assoc_type_bindings_from_type_bound(trait_ref);
684                        }
685                        clause = Some(Clause(Predicate::new(
686                            interner,
687                            Binder::dummy(rustc_type_ir::PredicateKind::Clause(
688                                rustc_type_ir::ClauseKind::Trait(TraitPredicate {
689                                    trait_ref,
690                                    polarity: rustc_type_ir::PredicatePolarity::Positive,
691                                }),
692                            )),
693                        )));
694                    }
695                }
696            }
697            &TypeBound::Path(path, TraitBoundModifier::Maybe) => {
698                let sized_trait = LangItem::Sized.resolve_trait(self.db, self.resolver.krate());
699                let trait_id = self
703                    .lower_trait_ref_from_path(path, self_ty)
704                    .map(|(trait_ref, _)| trait_ref.def_id.0);
705                if trait_id == sized_trait {
706                    self.unsized_types.insert(self_ty);
707                }
708            }
709            &TypeBound::Lifetime(l) => {
710                let lifetime = self.lower_lifetime(l);
711                clause = Some(Clause(Predicate::new(
712                    self.interner,
713                    Binder::dummy(rustc_type_ir::PredicateKind::Clause(
714                        rustc_type_ir::ClauseKind::TypeOutlives(OutlivesPredicate(
715                            self_ty, lifetime,
716                        )),
717                    )),
718                )));
719            }
720            TypeBound::Use(_) | TypeBound::Error => {}
721        }
722        clause.into_iter().chain(assoc_bounds.into_iter().flatten())
723    }
724
725    fn lower_dyn_trait(&mut self, bounds: &[TypeBound]) -> Ty<'db> {
726        let interner = self.interner;
727        let self_ty = Ty::new_error(interner, ErrorGuaranteed);
730        let mut lifetime = None;
736        let bounds = self.with_shifted_in(DebruijnIndex::from_u32(1), |ctx| {
737            let mut lowered_bounds: Vec<
738                rustc_type_ir::Binder<DbInterner<'db>, ExistentialPredicate<DbInterner<'db>>>,
739            > = Vec::new();
740            for b in bounds {
741                let db = ctx.db;
742                ctx.lower_type_bound(b, self_ty, false).for_each(|b| {
743                    if let Some(bound) = b
744                        .kind()
745                        .map_bound(|c| match c {
746                            rustc_type_ir::ClauseKind::Trait(t) => {
747                                let id = t.def_id();
748                                let is_auto =
749                                    db.trait_signature(id.0).flags.contains(TraitFlags::AUTO);
750                                if is_auto {
751                                    Some(ExistentialPredicate::AutoTrait(t.def_id()))
752                                } else {
753                                    Some(ExistentialPredicate::Trait(
754                                        ExistentialTraitRef::new_from_args(
755                                            interner,
756                                            t.def_id(),
757                                            GenericArgs::new_from_iter(
758                                                interner,
759                                                t.trait_ref.args.iter().skip(1),
760                                            ),
761                                        ),
762                                    ))
763                                }
764                            }
765                            rustc_type_ir::ClauseKind::Projection(p) => {
766                                Some(ExistentialPredicate::Projection(
767                                    ExistentialProjection::new_from_args(
768                                        interner,
769                                        p.def_id(),
770                                        GenericArgs::new_from_iter(
771                                            interner,
772                                            p.projection_term.args.iter().skip(1),
773                                        ),
774                                        p.term,
775                                    ),
776                                ))
777                            }
778                            rustc_type_ir::ClauseKind::TypeOutlives(outlives_predicate) => {
779                                lifetime = Some(outlives_predicate.1);
780                                None
781                            }
782                            rustc_type_ir::ClauseKind::RegionOutlives(_)
783                            | rustc_type_ir::ClauseKind::ConstArgHasType(_, _)
784                            | rustc_type_ir::ClauseKind::WellFormed(_)
785                            | rustc_type_ir::ClauseKind::ConstEvaluatable(_)
786                            | rustc_type_ir::ClauseKind::HostEffect(_)
787                            | rustc_type_ir::ClauseKind::UnstableFeature(_) => unreachable!(),
788                        })
789                        .transpose()
790                    {
791                        lowered_bounds.push(bound);
792                    }
793                })
794            }
795
796            let mut multiple_regular_traits = false;
797            let mut multiple_same_projection = false;
798            lowered_bounds.sort_unstable_by(|lhs, rhs| {
799                use std::cmp::Ordering;
800                match ((*lhs).skip_binder(), (*rhs).skip_binder()) {
801                    (ExistentialPredicate::Trait(_), ExistentialPredicate::Trait(_)) => {
802                        multiple_regular_traits = true;
803                        Ordering::Equal
805                    }
806                    (
807                        ExistentialPredicate::AutoTrait(lhs_id),
808                        ExistentialPredicate::AutoTrait(rhs_id),
809                    ) => lhs_id.0.cmp(&rhs_id.0),
810                    (ExistentialPredicate::Trait(_), _) => Ordering::Less,
811                    (_, ExistentialPredicate::Trait(_)) => Ordering::Greater,
812                    (ExistentialPredicate::AutoTrait(_), _) => Ordering::Less,
813                    (_, ExistentialPredicate::AutoTrait(_)) => Ordering::Greater,
814                    (
815                        ExistentialPredicate::Projection(lhs),
816                        ExistentialPredicate::Projection(rhs),
817                    ) => {
818                        let lhs_id = match lhs.def_id {
819                            SolverDefId::TypeAliasId(id) => id,
820                            _ => unreachable!(),
821                        };
822                        let rhs_id = match rhs.def_id {
823                            SolverDefId::TypeAliasId(id) => id,
824                            _ => unreachable!(),
825                        };
826                        if lhs_id == rhs_id {
830                            multiple_same_projection = true;
831                        }
832                        lhs_id.as_id().index().cmp(&rhs_id.as_id().index())
833                    }
834                }
835            });
836
837            if multiple_regular_traits || multiple_same_projection {
838                return None;
839            }
840
841            if !lowered_bounds.first().map_or(false, |b| {
842                matches!(
843                    b.as_ref().skip_binder(),
844                    ExistentialPredicate::Trait(_) | ExistentialPredicate::AutoTrait(_)
845                )
846            }) {
847                return None;
848            }
849
850            lowered_bounds.dedup();
853
854            Some(BoundExistentialPredicates::new_from_iter(interner, lowered_bounds))
855        });
856
857        if let Some(bounds) = bounds {
858            let region = match lifetime {
859                Some(it) => match it.kind() {
860                    rustc_type_ir::RegionKind::ReBound(BoundVarIndexKind::Bound(db), var) => {
861                        Region::new_bound(
862                            self.interner,
863                            db.shifted_out_to_binder(DebruijnIndex::from_u32(2)),
864                            var,
865                        )
866                    }
867                    _ => it,
868                },
869                None => Region::new_static(self.interner),
870            };
871            Ty::new_dynamic(self.interner, bounds, region)
872        } else {
873            Ty::new_error(self.interner, ErrorGuaranteed)
876        }
877    }
878
879    fn lower_impl_trait(
880        &mut self,
881        def_id: SolverDefId,
882        bounds: &[TypeBound],
883        krate: Crate,
884    ) -> ImplTrait<'db> {
885        let interner = self.interner;
886        cov_mark::hit!(lower_rpit);
887        let args = GenericArgs::identity_for_item(interner, def_id);
888        let self_ty = Ty::new_alias(
889            self.interner,
890            rustc_type_ir::AliasTyKind::Opaque,
891            AliasTy::new_from_args(interner, def_id, args),
892        );
893        let predicates = self.with_shifted_in(DebruijnIndex::from_u32(1), |ctx| {
894            let mut predicates = Vec::new();
895            for b in bounds {
896                predicates.extend(ctx.lower_type_bound(b, self_ty, false));
897            }
898
899            if !ctx.unsized_types.contains(&self_ty) {
900                let sized_trait = LangItem::Sized.resolve_trait(self.db, krate);
901                let sized_clause = sized_trait.map(|trait_id| {
902                    let trait_ref = TraitRef::new_from_args(
903                        interner,
904                        trait_id.into(),
905                        GenericArgs::new_from_iter(interner, [self_ty.into()]),
906                    );
907                    Clause(Predicate::new(
908                        interner,
909                        Binder::dummy(rustc_type_ir::PredicateKind::Clause(
910                            rustc_type_ir::ClauseKind::Trait(TraitPredicate {
911                                trait_ref,
912                                polarity: rustc_type_ir::PredicatePolarity::Positive,
913                            }),
914                        )),
915                    ))
916                });
917                predicates.extend(sized_clause);
918            }
919            predicates.shrink_to_fit();
920            predicates
921        });
922        ImplTrait { predicates }
923    }
924
925    pub(crate) fn lower_lifetime(&mut self, lifetime: LifetimeRefId) -> Region<'db> {
926        match self.resolver.resolve_lifetime(&self.store[lifetime]) {
927            Some(resolution) => match resolution {
928                LifetimeNs::Static => Region::new_static(self.interner),
929                LifetimeNs::LifetimeParam(id) => {
930                    let idx = match self.generics().lifetime_idx(id) {
931                        None => return Region::error(self.interner),
932                        Some(idx) => idx,
933                    };
934                    self.region_param(id, idx as u32)
935                }
936            },
937            None => Region::error(self.interner),
938        }
939    }
940}
941
942pub(crate) fn lower_mutability(m: hir_def::type_ref::Mutability) -> Mutability {
943    match m {
944        hir_def::type_ref::Mutability::Shared => Mutability::Not,
945        hir_def::type_ref::Mutability::Mut => Mutability::Mut,
946    }
947}
948
949fn unknown_const(_ty: Ty<'_>) -> Const<'_> {
950    Const::new(DbInterner::conjure(), ConstKind::Error(ErrorGuaranteed))
951}
952
953pub(crate) type Diagnostics = Option<ThinArc<(), TyLoweringDiagnostic>>;
954
955pub(crate) fn create_diagnostics(diagnostics: Vec<TyLoweringDiagnostic>) -> Diagnostics {
956    (!diagnostics.is_empty()).then(|| ThinArc::from_header_and_iter((), diagnostics.into_iter()))
957}
958
959pub(crate) fn impl_trait_query<'db>(
960    db: &'db dyn HirDatabase,
961    impl_id: ImplId,
962) -> Option<EarlyBinder<'db, TraitRef<'db>>> {
963    db.impl_trait_with_diagnostics(impl_id).map(|it| it.0)
964}
965
966pub(crate) fn impl_trait_with_diagnostics_query<'db>(
967    db: &'db dyn HirDatabase,
968    impl_id: ImplId,
969) -> Option<(EarlyBinder<'db, TraitRef<'db>>, Diagnostics)> {
970    let impl_data = db.impl_signature(impl_id);
971    let resolver = impl_id.resolver(db);
972    let mut ctx = TyLoweringContext::new(
973        db,
974        &resolver,
975        &impl_data.store,
976        impl_id.into(),
977        LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true },
978    );
979    let self_ty = db.impl_self_ty(impl_id).skip_binder();
980    let target_trait = impl_data.target_trait.as_ref()?;
981    let trait_ref = EarlyBinder::bind(ctx.lower_trait_ref(target_trait, self_ty)?);
982    Some((trait_ref, create_diagnostics(ctx.diagnostics)))
983}
984
985pub(crate) fn return_type_impl_traits<'db>(
986    db: &'db dyn HirDatabase,
987    def: hir_def::FunctionId,
988) -> Option<Arc<EarlyBinder<'db, ImplTraits<'db>>>> {
989    let data = db.function_signature(def);
991    let resolver = def.resolver(db);
992    let mut ctx_ret =
993        TyLoweringContext::new(db, &resolver, &data.store, def.into(), LifetimeElisionKind::Infer)
994            .with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
995    if let Some(ret_type) = data.ret_type {
996        let _ret = ctx_ret.lower_ty(ret_type);
997    }
998    let return_type_impl_traits =
999        ImplTraits { impl_traits: ctx_ret.impl_trait_mode.opaque_type_data };
1000    if return_type_impl_traits.impl_traits.is_empty() {
1001        None
1002    } else {
1003        Some(Arc::new(EarlyBinder::bind(return_type_impl_traits)))
1004    }
1005}
1006
1007pub(crate) fn type_alias_impl_traits<'db>(
1008    db: &'db dyn HirDatabase,
1009    def: hir_def::TypeAliasId,
1010) -> Option<Arc<EarlyBinder<'db, ImplTraits<'db>>>> {
1011    let data = db.type_alias_signature(def);
1012    let resolver = def.resolver(db);
1013    let mut ctx = TyLoweringContext::new(
1014        db,
1015        &resolver,
1016        &data.store,
1017        def.into(),
1018        LifetimeElisionKind::AnonymousReportError,
1019    )
1020    .with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
1021    if let Some(type_ref) = data.ty {
1022        let _ty = ctx.lower_ty(type_ref);
1023    }
1024    let type_alias_impl_traits = ImplTraits { impl_traits: ctx.impl_trait_mode.opaque_type_data };
1025    if type_alias_impl_traits.impl_traits.is_empty() {
1026        None
1027    } else {
1028        Some(Arc::new(EarlyBinder::bind(type_alias_impl_traits)))
1029    }
1030}
1031
1032#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
1033pub enum TyDefId {
1034    BuiltinType(BuiltinType),
1035    AdtId(AdtId),
1036    TypeAliasId(TypeAliasId),
1037}
1038impl_from!(BuiltinType, AdtId(StructId, EnumId, UnionId), TypeAliasId for TyDefId);
1039
1040#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
1041pub enum ValueTyDefId {
1042    FunctionId(FunctionId),
1043    StructId(StructId),
1044    UnionId(UnionId),
1045    EnumVariantId(EnumVariantId),
1046    ConstId(ConstId),
1047    StaticId(StaticId),
1048}
1049impl_from!(FunctionId, StructId, UnionId, EnumVariantId, ConstId, StaticId for ValueTyDefId);
1050
1051impl ValueTyDefId {
1052    pub(crate) fn to_generic_def_id(self, db: &dyn HirDatabase) -> GenericDefId {
1053        match self {
1054            Self::FunctionId(id) => id.into(),
1055            Self::StructId(id) => id.into(),
1056            Self::UnionId(id) => id.into(),
1057            Self::EnumVariantId(var) => var.lookup(db).parent.into(),
1058            Self::ConstId(id) => id.into(),
1059            Self::StaticId(id) => id.into(),
1060        }
1061    }
1062}
1063
1064pub(crate) fn ty_query<'db>(db: &'db dyn HirDatabase, def: TyDefId) -> EarlyBinder<'db, Ty<'db>> {
1069    let interner = DbInterner::new_with(db, None, None);
1070    match def {
1071        TyDefId::BuiltinType(it) => EarlyBinder::bind(Ty::from_builtin_type(interner, it)),
1072        TyDefId::AdtId(it) => EarlyBinder::bind(Ty::new_adt(
1073            interner,
1074            it,
1075            GenericArgs::identity_for_item(interner, it.into()),
1076        )),
1077        TyDefId::TypeAliasId(it) => db.type_for_type_alias_with_diagnostics(it).0,
1078    }
1079}
1080
1081fn type_for_fn<'db>(db: &'db dyn HirDatabase, def: FunctionId) -> EarlyBinder<'db, Ty<'db>> {
1084    let interner = DbInterner::new_with(db, None, None);
1085    EarlyBinder::bind(Ty::new_fn_def(
1086        interner,
1087        CallableDefId::FunctionId(def).into(),
1088        GenericArgs::identity_for_item(interner, def.into()),
1089    ))
1090}
1091
1092fn type_for_const<'db>(db: &'db dyn HirDatabase, def: ConstId) -> EarlyBinder<'db, Ty<'db>> {
1094    let resolver = def.resolver(db);
1095    let data = db.const_signature(def);
1096    let parent = def.loc(db).container;
1097    let mut ctx = TyLoweringContext::new(
1098        db,
1099        &resolver,
1100        &data.store,
1101        def.into(),
1102        LifetimeElisionKind::AnonymousReportError,
1103    );
1104    ctx.set_lifetime_elision(LifetimeElisionKind::for_const(ctx.interner, parent));
1105    EarlyBinder::bind(ctx.lower_ty(data.type_ref))
1106}
1107
1108fn type_for_static<'db>(db: &'db dyn HirDatabase, def: StaticId) -> EarlyBinder<'db, Ty<'db>> {
1110    let resolver = def.resolver(db);
1111    let data = db.static_signature(def);
1112    let mut ctx = TyLoweringContext::new(
1113        db,
1114        &resolver,
1115        &data.store,
1116        def.into(),
1117        LifetimeElisionKind::AnonymousReportError,
1118    );
1119    ctx.set_lifetime_elision(LifetimeElisionKind::Elided(Region::new_static(ctx.interner)));
1120    EarlyBinder::bind(ctx.lower_ty(data.type_ref))
1121}
1122
1123fn type_for_struct_constructor<'db>(
1125    db: &'db dyn HirDatabase,
1126    def: StructId,
1127) -> Option<EarlyBinder<'db, Ty<'db>>> {
1128    let struct_data = def.fields(db);
1129    match struct_data.shape {
1130        FieldsShape::Record => None,
1131        FieldsShape::Unit => Some(type_for_adt(db, def.into())),
1132        FieldsShape::Tuple => {
1133            let interner = DbInterner::new_with(db, None, None);
1134            Some(EarlyBinder::bind(Ty::new_fn_def(
1135                interner,
1136                CallableDefId::StructId(def).into(),
1137                GenericArgs::identity_for_item(interner, def.into()),
1138            )))
1139        }
1140    }
1141}
1142
1143fn type_for_enum_variant_constructor<'db>(
1145    db: &'db dyn HirDatabase,
1146    def: EnumVariantId,
1147) -> Option<EarlyBinder<'db, Ty<'db>>> {
1148    let struct_data = def.fields(db);
1149    match struct_data.shape {
1150        FieldsShape::Record => None,
1151        FieldsShape::Unit => Some(type_for_adt(db, def.loc(db).parent.into())),
1152        FieldsShape::Tuple => {
1153            let interner = DbInterner::new_with(db, None, None);
1154            Some(EarlyBinder::bind(Ty::new_fn_def(
1155                interner,
1156                CallableDefId::EnumVariantId(def).into(),
1157                GenericArgs::identity_for_item(interner, def.loc(db).parent.into()),
1158            )))
1159        }
1160    }
1161}
1162
1163pub(crate) fn value_ty_query<'db>(
1164    db: &'db dyn HirDatabase,
1165    def: ValueTyDefId,
1166) -> Option<EarlyBinder<'db, Ty<'db>>> {
1167    match def {
1168        ValueTyDefId::FunctionId(it) => Some(type_for_fn(db, it)),
1169        ValueTyDefId::StructId(it) => type_for_struct_constructor(db, it),
1170        ValueTyDefId::UnionId(it) => Some(type_for_adt(db, it.into())),
1171        ValueTyDefId::EnumVariantId(it) => type_for_enum_variant_constructor(db, it),
1172        ValueTyDefId::ConstId(it) => Some(type_for_const(db, it)),
1173        ValueTyDefId::StaticId(it) => Some(type_for_static(db, it)),
1174    }
1175}
1176
1177pub(crate) fn type_for_type_alias_with_diagnostics_query<'db>(
1178    db: &'db dyn HirDatabase,
1179    t: TypeAliasId,
1180) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics) {
1181    let type_alias_data = db.type_alias_signature(t);
1182    let mut diags = None;
1183    let resolver = t.resolver(db);
1184    let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
1185    let inner = if type_alias_data.flags.contains(TypeAliasFlags::IS_EXTERN) {
1186        EarlyBinder::bind(Ty::new_foreign(interner, t.into()))
1187    } else {
1188        let mut ctx = TyLoweringContext::new(
1189            db,
1190            &resolver,
1191            &type_alias_data.store,
1192            t.into(),
1193            LifetimeElisionKind::AnonymousReportError,
1194        )
1195        .with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
1196        let res = EarlyBinder::bind(
1197            type_alias_data
1198                .ty
1199                .map(|type_ref| ctx.lower_ty(type_ref))
1200                .unwrap_or_else(|| Ty::new_error(interner, ErrorGuaranteed)),
1201        );
1202        diags = create_diagnostics(ctx.diagnostics);
1203        res
1204    };
1205    (inner, diags)
1206}
1207
1208pub(crate) fn type_for_type_alias_with_diagnostics_cycle_result<'db>(
1209    db: &'db dyn HirDatabase,
1210    _adt: TypeAliasId,
1211) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics) {
1212    (EarlyBinder::bind(Ty::new_error(DbInterner::new_with(db, None, None), ErrorGuaranteed)), None)
1213}
1214
1215pub(crate) fn impl_self_ty_query<'db>(
1216    db: &'db dyn HirDatabase,
1217    impl_id: ImplId,
1218) -> EarlyBinder<'db, Ty<'db>> {
1219    db.impl_self_ty_with_diagnostics(impl_id).0
1220}
1221
1222pub(crate) fn impl_self_ty_with_diagnostics_query<'db>(
1223    db: &'db dyn HirDatabase,
1224    impl_id: ImplId,
1225) -> (EarlyBinder<'db, Ty<'db>>, Diagnostics) {
1226    let resolver = impl_id.resolver(db);
1227
1228    let impl_data = db.impl_signature(impl_id);
1229    let mut ctx = TyLoweringContext::new(
1230        db,
1231        &resolver,
1232        &impl_data.store,
1233        impl_id.into(),
1234        LifetimeElisionKind::AnonymousCreateParameter { report_in_path: true },
1235    );
1236    let ty = ctx.lower_ty(impl_data.self_ty);
1237    assert!(!ty.has_escaping_bound_vars());
1238    (EarlyBinder::bind(ty), create_diagnostics(ctx.diagnostics))
1239}
1240
1241pub(crate) fn impl_self_ty_with_diagnostics_cycle_result(
1242    db: &dyn HirDatabase,
1243    _impl_id: ImplId,
1244) -> (EarlyBinder<'_, Ty<'_>>, Diagnostics) {
1245    (EarlyBinder::bind(Ty::new_error(DbInterner::new_with(db, None, None), ErrorGuaranteed)), None)
1246}
1247
1248pub(crate) fn const_param_ty_query<'db>(db: &'db dyn HirDatabase, def: ConstParamId) -> Ty<'db> {
1249    db.const_param_ty_with_diagnostics(def).0
1250}
1251
1252pub(crate) fn const_param_ty_with_diagnostics_query<'db>(
1254    db: &'db dyn HirDatabase,
1255    def: ConstParamId,
1256) -> (Ty<'db>, Diagnostics) {
1257    let (parent_data, store) = db.generic_params_and_store(def.parent());
1258    let data = &parent_data[def.local_id()];
1259    let resolver = def.parent().resolver(db);
1260    let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
1261    let mut ctx = TyLoweringContext::new(
1262        db,
1263        &resolver,
1264        &store,
1265        def.parent(),
1266        LifetimeElisionKind::AnonymousReportError,
1267    );
1268    let ty = match data {
1269        TypeOrConstParamData::TypeParamData(_) => {
1270            never!();
1271            Ty::new_error(interner, ErrorGuaranteed)
1272        }
1273        TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(d.ty),
1274    };
1275    (ty, create_diagnostics(ctx.diagnostics))
1276}
1277
1278pub(crate) fn const_param_ty_with_diagnostics_cycle_result<'db>(
1279    db: &'db dyn HirDatabase,
1280    _: crate::db::HirDatabaseData,
1281    def: ConstParamId,
1282) -> (Ty<'db>, Diagnostics) {
1283    let resolver = def.parent().resolver(db);
1284    let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
1285    (Ty::new_error(interner, ErrorGuaranteed), None)
1286}
1287
1288pub(crate) fn field_types_query<'db>(
1289    db: &'db dyn HirDatabase,
1290    variant_id: VariantId,
1291) -> Arc<ArenaMap<LocalFieldId, EarlyBinder<'db, Ty<'db>>>> {
1292    db.field_types_with_diagnostics(variant_id).0
1293}
1294
1295pub(crate) fn field_types_with_diagnostics_query<'db>(
1297    db: &'db dyn HirDatabase,
1298    variant_id: VariantId,
1299) -> (Arc<ArenaMap<LocalFieldId, EarlyBinder<'db, Ty<'db>>>>, Diagnostics) {
1300    let var_data = variant_id.fields(db);
1301    let fields = var_data.fields();
1302    if fields.is_empty() {
1303        return (Arc::new(ArenaMap::default()), None);
1304    }
1305
1306    let (resolver, def): (_, GenericDefId) = match variant_id {
1307        VariantId::StructId(it) => (it.resolver(db), it.into()),
1308        VariantId::UnionId(it) => (it.resolver(db), it.into()),
1309        VariantId::EnumVariantId(it) => (it.resolver(db), it.lookup(db).parent.into()),
1310    };
1311    let mut res = ArenaMap::default();
1312    let mut ctx = TyLoweringContext::new(
1313        db,
1314        &resolver,
1315        &var_data.store,
1316        def,
1317        LifetimeElisionKind::AnonymousReportError,
1318    );
1319    for (field_id, field_data) in var_data.fields().iter() {
1320        res.insert(field_id, EarlyBinder::bind(ctx.lower_ty(field_data.type_ref)));
1321    }
1322    (Arc::new(res), create_diagnostics(ctx.diagnostics))
1323}
1324
1325#[tracing::instrument(skip(db), ret)]
1334pub(crate) fn generic_predicates_for_param_query<'db>(
1335    db: &'db dyn HirDatabase,
1336    def: GenericDefId,
1337    param_id: TypeOrConstParamId,
1338    assoc_name: Option<Name>,
1339) -> GenericPredicates<'db> {
1340    let generics = generics(db, def);
1341    let interner = DbInterner::new_with(db, None, None);
1342    let resolver = def.resolver(db);
1343    let mut ctx = TyLoweringContext::new(
1344        db,
1345        &resolver,
1346        generics.store(),
1347        def,
1348        LifetimeElisionKind::AnonymousReportError,
1349    );
1350
1351    let predicate = |pred: &_, ctx: &mut TyLoweringContext<'_, '_>| match pred {
1353        WherePredicate::ForLifetime { target, bound, .. }
1354        | WherePredicate::TypeBound { target, bound, .. } => {
1355            let invalid_target = { ctx.lower_ty_only_param(*target) != Some(param_id) };
1356            if invalid_target {
1357                let lower = || -> bool {
1362                    match bound {
1363                        TypeBound::Path(_, TraitBoundModifier::Maybe) => true,
1364                        TypeBound::Path(path, _) | TypeBound::ForLifetime(_, path) => {
1365                            let TypeRef::Path(path) = &ctx.store[path.type_ref()] else {
1366                                return false;
1367                            };
1368                            let Some(pointee_sized) =
1369                                LangItem::PointeeSized.resolve_trait(ctx.db, ctx.resolver.krate())
1370                            else {
1371                                return false;
1372                            };
1373                            ctx.resolver.resolve_path_in_type_ns_fully(ctx.db, path).is_some_and(
1376                                |it| matches!(it, TypeNs::TraitId(tr) if tr == pointee_sized),
1377                            )
1378                        }
1379                        _ => false,
1380                    }
1381                }();
1382                if lower {
1383                    ctx.lower_where_predicate(pred, true, &generics, PredicateFilter::All)
1384                        .for_each(drop);
1385                }
1386                return false;
1387            }
1388
1389            match bound {
1390                &TypeBound::ForLifetime(_, path) | &TypeBound::Path(path, _) => {
1391                    let path = &ctx.store[path];
1394
1395                    let Some(assoc_name) = &assoc_name else { return true };
1396                    let Some(TypeNs::TraitId(tr)) =
1397                        resolver.resolve_path_in_type_ns_fully(db, path)
1398                    else {
1399                        return false;
1400                    };
1401
1402                    rustc_type_ir::elaborate::supertrait_def_ids(interner, tr.into()).any(|tr| {
1403                        tr.0.trait_items(db).items.iter().any(|(name, item)| {
1404                            matches!(item, AssocItemId::TypeAliasId(_)) && name == assoc_name
1405                        })
1406                    })
1407                }
1408                TypeBound::Use(_) | TypeBound::Lifetime(_) | TypeBound::Error => false,
1409            }
1410        }
1411        WherePredicate::Lifetime { .. } => false,
1412    };
1413    let mut predicates = Vec::new();
1414    for maybe_parent_generics in
1415        std::iter::successors(Some(&generics), |generics| generics.parent_generics())
1416    {
1417        ctx.store = maybe_parent_generics.store();
1418        for pred in maybe_parent_generics.where_predicates() {
1419            if predicate(pred, &mut ctx) {
1420                predicates.extend(ctx.lower_where_predicate(
1421                    pred,
1422                    true,
1423                    maybe_parent_generics,
1424                    PredicateFilter::All,
1425                ));
1426            }
1427        }
1428    }
1429
1430    let args = GenericArgs::identity_for_item(interner, def.into());
1431    if !args.is_empty() {
1432        let explicitly_unsized_tys = ctx.unsized_types;
1433        if let Some(implicitly_sized_predicates) =
1434            implicitly_sized_clauses(db, param_id.parent, &explicitly_unsized_tys, &args, &resolver)
1435        {
1436            predicates.extend(implicitly_sized_predicates);
1437        };
1438    }
1439    GenericPredicates(predicates.is_empty().not().then(|| predicates.into()))
1440}
1441
1442pub(crate) fn generic_predicates_for_param_cycle_result(
1443    _db: &dyn HirDatabase,
1444    _def: GenericDefId,
1445    _param_id: TypeOrConstParamId,
1446    _assoc_name: Option<Name>,
1447) -> GenericPredicates<'_> {
1448    GenericPredicates(None)
1449}
1450
1451#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1452pub struct GenericPredicates<'db>(Option<Arc<[Clause<'db>]>>);
1453
1454impl<'db> GenericPredicates<'db> {
1455    #[inline]
1456    pub fn instantiate(
1457        &self,
1458        interner: DbInterner<'db>,
1459        args: GenericArgs<'db>,
1460    ) -> Option<impl Iterator<Item = Clause<'db>>> {
1461        self.0
1462            .as_ref()
1463            .map(|it| EarlyBinder::bind(it.iter().copied()).iter_instantiated(interner, args))
1464    }
1465
1466    #[inline]
1467    pub fn instantiate_identity(&self) -> Option<impl Iterator<Item = Clause<'db>>> {
1468        self.0.as_ref().map(|it| it.iter().copied())
1469    }
1470}
1471
1472impl<'db> ops::Deref for GenericPredicates<'db> {
1473    type Target = [Clause<'db>];
1474
1475    fn deref(&self) -> &Self::Target {
1476        self.0.as_deref().unwrap_or(&[])
1477    }
1478}
1479
1480pub(crate) fn trait_environment_for_body_query(
1481    db: &dyn HirDatabase,
1482    def: DefWithBodyId,
1483) -> Arc<TraitEnvironment<'_>> {
1484    let Some(def) = def.as_generic_def_id(db) else {
1485        let krate = def.module(db).krate();
1486        return TraitEnvironment::empty(krate);
1487    };
1488    db.trait_environment(def)
1489}
1490
1491pub(crate) fn trait_environment_query<'db>(
1492    db: &'db dyn HirDatabase,
1493    def: GenericDefId,
1494) -> Arc<TraitEnvironment<'db>> {
1495    let generics = generics(db, def);
1496    if generics.has_no_predicates() && generics.is_empty() {
1497        return TraitEnvironment::empty(def.krate(db));
1498    }
1499
1500    let resolver = def.resolver(db);
1501    let mut ctx = TyLoweringContext::new(
1502        db,
1503        &resolver,
1504        generics.store(),
1505        def,
1506        LifetimeElisionKind::AnonymousReportError,
1507    );
1508    let mut traits_in_scope = Vec::new();
1509    let mut clauses = Vec::new();
1510    for maybe_parent_generics in
1511        std::iter::successors(Some(&generics), |generics| generics.parent_generics())
1512    {
1513        ctx.store = maybe_parent_generics.store();
1514        for pred in maybe_parent_generics.where_predicates() {
1515            for pred in ctx.lower_where_predicate(pred, false, &generics, PredicateFilter::All) {
1516                if let rustc_type_ir::ClauseKind::Trait(tr) = pred.kind().skip_binder() {
1517                    traits_in_scope.push((tr.self_ty(), tr.def_id().0));
1518                }
1519                clauses.push(pred);
1520            }
1521        }
1522    }
1523
1524    if let Some(trait_id) = def.assoc_trait_container(db) {
1525        cov_mark::hit!(trait_self_implements_self);
1529        let trait_ref = TraitRef::identity(ctx.interner, trait_id.into());
1530        let clause = Clause(Predicate::new(
1531            ctx.interner,
1532            Binder::dummy(rustc_type_ir::PredicateKind::Clause(rustc_type_ir::ClauseKind::Trait(
1533                TraitPredicate { trait_ref, polarity: rustc_type_ir::PredicatePolarity::Positive },
1534            ))),
1535        ));
1536        clauses.push(clause);
1537    }
1538
1539    let explicitly_unsized_tys = ctx.unsized_types;
1540
1541    let sized_trait = LangItem::Sized.resolve_trait(db, resolver.krate());
1542    if let Some(sized_trait) = sized_trait {
1543        let (mut generics, mut def_id) =
1544            (crate::next_solver::generics::generics(db, def.into()), def);
1545        loop {
1546            let self_idx = trait_self_param_idx(db, def_id);
1547            for (idx, p) in generics.own_params.iter().enumerate() {
1548                if let Some(self_idx) = self_idx
1549                    && p.index() as usize == self_idx
1550                {
1551                    continue;
1552                }
1553                let GenericParamId::TypeParamId(param_id) = p.id else {
1554                    continue;
1555                };
1556                let idx = idx as u32 + generics.parent_count as u32;
1557                let param_ty = Ty::new_param(ctx.interner, param_id, idx);
1558                if explicitly_unsized_tys.contains(¶m_ty) {
1559                    continue;
1560                }
1561                let trait_ref = TraitRef::new_from_args(
1562                    ctx.interner,
1563                    sized_trait.into(),
1564                    GenericArgs::new_from_iter(ctx.interner, [param_ty.into()]),
1565                );
1566                let clause = Clause(Predicate::new(
1567                    ctx.interner,
1568                    Binder::dummy(rustc_type_ir::PredicateKind::Clause(
1569                        rustc_type_ir::ClauseKind::Trait(TraitPredicate {
1570                            trait_ref,
1571                            polarity: rustc_type_ir::PredicatePolarity::Positive,
1572                        }),
1573                    )),
1574                ));
1575                clauses.push(clause);
1576            }
1577
1578            if let Some(g) = generics.parent {
1579                generics = crate::next_solver::generics::generics(db, g.into());
1580                def_id = g;
1581            } else {
1582                break;
1583            }
1584        }
1585    }
1586
1587    let clauses = rustc_type_ir::elaborate::elaborate(ctx.interner, clauses);
1588    let clauses = Clauses::new_from_iter(ctx.interner, clauses);
1589    let env = ParamEnv { clauses };
1590
1591    TraitEnvironment::new(resolver.krate(), None, traits_in_scope.into_boxed_slice(), env)
1592}
1593
1594#[derive(Copy, Clone, Debug)]
1595pub(crate) enum PredicateFilter {
1596    SelfTrait,
1597    All,
1598}
1599
1600#[tracing::instrument(skip(db))]
1602pub(crate) fn generic_predicates_query<'db>(
1603    db: &'db dyn HirDatabase,
1604    def: GenericDefId,
1605) -> GenericPredicates<'db> {
1606    generic_predicates_filtered_by(db, def, PredicateFilter::All, |_| true).0
1607}
1608
1609pub(crate) fn generic_predicates_without_parent_query<'db>(
1610    db: &'db dyn HirDatabase,
1611    def: GenericDefId,
1612) -> GenericPredicates<'db> {
1613    generic_predicates_filtered_by(db, def, PredicateFilter::All, |d| d == def).0
1614}
1615
1616pub(crate) fn generic_predicates_without_parent_with_diagnostics_query<'db>(
1619    db: &'db dyn HirDatabase,
1620    def: GenericDefId,
1621) -> (GenericPredicates<'db>, Diagnostics) {
1622    generic_predicates_filtered_by(db, def, PredicateFilter::All, |d| d == def)
1623}
1624
1625#[tracing::instrument(skip(db, filter), ret)]
1628pub(crate) fn generic_predicates_filtered_by<'db, F>(
1629    db: &'db dyn HirDatabase,
1630    def: GenericDefId,
1631    predicate_filter: PredicateFilter,
1632    filter: F,
1633) -> (GenericPredicates<'db>, Diagnostics)
1634where
1635    F: Fn(GenericDefId) -> bool,
1636{
1637    let generics = generics(db, def);
1638    let resolver = def.resolver(db);
1639    let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
1640    let mut ctx = TyLoweringContext::new(
1641        db,
1642        &resolver,
1643        generics.store(),
1644        def,
1645        LifetimeElisionKind::AnonymousReportError,
1646    );
1647
1648    let mut predicates = Vec::new();
1649    for maybe_parent_generics in
1650        std::iter::successors(Some(&generics), |generics| generics.parent_generics())
1651    {
1652        ctx.store = maybe_parent_generics.store();
1653        for pred in maybe_parent_generics.where_predicates() {
1654            tracing::debug!(?pred);
1655            if filter(maybe_parent_generics.def()) {
1656                predicates.extend(ctx.lower_where_predicate(
1657                    pred,
1658                    false,
1659                    maybe_parent_generics,
1660                    predicate_filter,
1661                ));
1662            }
1663        }
1664    }
1665
1666    let explicitly_unsized_tys = ctx.unsized_types;
1667
1668    let sized_trait = LangItem::Sized.resolve_trait(db, resolver.krate());
1669    if let Some(sized_trait) = sized_trait {
1670        let mut add_sized_clause = |param_idx, param_id, param_data| {
1671            let (
1672                GenericParamId::TypeParamId(param_id),
1673                GenericParamDataRef::TypeParamData(param_data),
1674            ) = (param_id, param_data)
1675            else {
1676                return;
1677            };
1678
1679            if param_data.provenance == TypeParamProvenance::TraitSelf {
1680                return;
1681            }
1682
1683            let param_ty = Ty::new_param(interner, param_id, param_idx);
1684            if explicitly_unsized_tys.contains(¶m_ty) {
1685                return;
1686            }
1687            let trait_ref = TraitRef::new_from_args(
1688                interner,
1689                sized_trait.into(),
1690                GenericArgs::new_from_iter(interner, [param_ty.into()]),
1691            );
1692            let clause = Clause(Predicate::new(
1693                interner,
1694                Binder::dummy(rustc_type_ir::PredicateKind::Clause(
1695                    rustc_type_ir::ClauseKind::Trait(TraitPredicate {
1696                        trait_ref,
1697                        polarity: rustc_type_ir::PredicatePolarity::Positive,
1698                    }),
1699                )),
1700            ));
1701            predicates.push(clause);
1702        };
1703        if generics.parent_generics().is_some_and(|parent| filter(parent.def())) {
1704            generics.iter_parent().enumerate().for_each(|(param_idx, (param_id, param_data))| {
1705                add_sized_clause(param_idx as u32, param_id, param_data);
1706            });
1707        }
1708        if filter(def) {
1709            let parent_params_len = generics.len_parent();
1710            generics.iter_self().enumerate().for_each(|(param_idx, (param_id, param_data))| {
1711                add_sized_clause((param_idx + parent_params_len) as u32, param_id, param_data);
1712            });
1713        }
1714    }
1715
1716    (
1720        GenericPredicates(predicates.is_empty().not().then(|| predicates.into())),
1721        create_diagnostics(ctx.diagnostics),
1722    )
1723}
1724
1725fn implicitly_sized_clauses<'a, 'subst, 'db>(
1728    db: &'db dyn HirDatabase,
1729    def: GenericDefId,
1730    explicitly_unsized_tys: &'a FxHashSet<Ty<'db>>,
1731    args: &'subst GenericArgs<'db>,
1732    resolver: &Resolver<'db>,
1733) -> Option<impl Iterator<Item = Clause<'db>> + Captures<'a> + Captures<'subst>> {
1734    let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
1735    let sized_trait = LangItem::Sized.resolve_trait(db, resolver.krate())?;
1736
1737    let trait_self_idx = trait_self_param_idx(db, def);
1738
1739    Some(
1740        args.iter()
1741            .enumerate()
1742            .filter_map(
1743                move |(idx, generic_arg)| {
1744                    if Some(idx) == trait_self_idx { None } else { Some(generic_arg) }
1745                },
1746            )
1747            .filter_map(|generic_arg| generic_arg.as_type())
1748            .filter(move |self_ty| !explicitly_unsized_tys.contains(self_ty))
1749            .map(move |self_ty| {
1750                let trait_ref = TraitRef::new_from_args(
1751                    interner,
1752                    sized_trait.into(),
1753                    GenericArgs::new_from_iter(interner, [self_ty.into()]),
1754                );
1755                Clause(Predicate::new(
1756                    interner,
1757                    Binder::dummy(rustc_type_ir::PredicateKind::Clause(
1758                        rustc_type_ir::ClauseKind::Trait(TraitPredicate {
1759                            trait_ref,
1760                            polarity: rustc_type_ir::PredicatePolarity::Positive,
1761                        }),
1762                    )),
1763                ))
1764            }),
1765    )
1766}
1767
1768#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1769pub struct GenericDefaults<'db>(Option<Arc<[Option<EarlyBinder<'db, GenericArg<'db>>>]>>);
1770
1771impl<'db> GenericDefaults<'db> {
1772    #[inline]
1773    pub fn get(&self, idx: usize) -> Option<EarlyBinder<'db, GenericArg<'db>>> {
1774        self.0.as_ref()?[idx]
1775    }
1776}
1777
1778pub(crate) fn generic_defaults_query(
1779    db: &dyn HirDatabase,
1780    def: GenericDefId,
1781) -> GenericDefaults<'_> {
1782    db.generic_defaults_with_diagnostics(def).0
1783}
1784
1785pub(crate) fn generic_defaults_with_diagnostics_query(
1789    db: &dyn HirDatabase,
1790    def: GenericDefId,
1791) -> (GenericDefaults<'_>, Diagnostics) {
1792    let generic_params = generics(db, def);
1793    if generic_params.is_empty() {
1794        return (GenericDefaults(None), None);
1795    }
1796    let resolver = def.resolver(db);
1797
1798    let mut ctx = TyLoweringContext::new(
1799        db,
1800        &resolver,
1801        generic_params.store(),
1802        def,
1803        LifetimeElisionKind::AnonymousReportError,
1804    )
1805    .with_impl_trait_mode(ImplTraitLoweringMode::Disallowed);
1806    let mut idx = 0;
1807    let mut has_any_default = false;
1808    let mut defaults = generic_params
1809        .iter_parents_with_store()
1810        .map(|((_id, p), store)| {
1811            ctx.store = store;
1812            let (result, has_default) = handle_generic_param(&mut ctx, idx, p);
1813            has_any_default |= has_default;
1814            idx += 1;
1815            result
1816        })
1817        .collect::<Vec<_>>();
1818    ctx.diagnostics.clear(); defaults.extend(generic_params.iter_self().map(|(_id, p)| {
1820        let (result, has_default) = handle_generic_param(&mut ctx, idx, p);
1821        has_any_default |= has_default;
1822        idx += 1;
1823        result
1824    }));
1825    let diagnostics = create_diagnostics(mem::take(&mut ctx.diagnostics));
1826    let defaults = if has_any_default {
1827        GenericDefaults(Some(Arc::from_iter(defaults)))
1828    } else {
1829        GenericDefaults(None)
1830    };
1831    return (defaults, diagnostics);
1832
1833    fn handle_generic_param<'db>(
1834        ctx: &mut TyLoweringContext<'db, '_>,
1835        idx: usize,
1836        p: GenericParamDataRef<'_>,
1837    ) -> (Option<EarlyBinder<'db, GenericArg<'db>>>, bool) {
1838        ctx.lowering_param_default(idx as u32);
1839        match p {
1840            GenericParamDataRef::TypeParamData(p) => {
1841                let ty = p.default.map(|ty| ctx.lower_ty(ty));
1842                (ty.map(|ty| EarlyBinder::bind(ty.into())), p.default.is_some())
1843            }
1844            GenericParamDataRef::ConstParamData(p) => {
1845                let val = p.default.map(|c| {
1846                    let param_ty = ctx.lower_ty(p.ty);
1847                    let c = ctx.lower_const(c, param_ty);
1848                    c.into()
1849                });
1850                (val.map(EarlyBinder::bind), p.default.is_some())
1851            }
1852            GenericParamDataRef::LifetimeParamData(_) => (None, false),
1853        }
1854    }
1855}
1856
1857pub(crate) fn generic_defaults_with_diagnostics_cycle_result(
1858    _db: &dyn HirDatabase,
1859    _def: GenericDefId,
1860) -> (GenericDefaults<'_>, Diagnostics) {
1861    (GenericDefaults(None), None)
1862}
1863
1864pub(crate) fn callable_item_signature_query<'db>(
1866    db: &'db dyn HirDatabase,
1867    def: CallableDefId,
1868) -> EarlyBinder<'db, PolyFnSig<'db>> {
1869    match def {
1870        CallableDefId::FunctionId(f) => fn_sig_for_fn(db, f),
1871        CallableDefId::StructId(s) => fn_sig_for_struct_constructor(db, s),
1872        CallableDefId::EnumVariantId(e) => fn_sig_for_enum_variant_constructor(db, e),
1873    }
1874}
1875
1876fn fn_sig_for_fn<'db>(
1877    db: &'db dyn HirDatabase,
1878    def: FunctionId,
1879) -> EarlyBinder<'db, PolyFnSig<'db>> {
1880    let data = db.function_signature(def);
1881    let resolver = def.resolver(db);
1882    let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
1883    let mut ctx_params = TyLoweringContext::new(
1884        db,
1885        &resolver,
1886        &data.store,
1887        def.into(),
1888        LifetimeElisionKind::for_fn_params(&data),
1889    );
1890    let params = data.params.iter().map(|&tr| ctx_params.lower_ty(tr));
1891
1892    let ret = match data.ret_type {
1893        Some(ret_type) => {
1894            let mut ctx_ret = TyLoweringContext::new(
1895                db,
1896                &resolver,
1897                &data.store,
1898                def.into(),
1899                LifetimeElisionKind::for_fn_ret(interner),
1900            )
1901            .with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
1902            ctx_ret.lower_ty(ret_type)
1903        }
1904        None => Ty::new_tup(interner, &[]),
1905    };
1906
1907    let inputs_and_output = Tys::new_from_iter(interner, params.chain(Some(ret)));
1908    EarlyBinder::bind(rustc_type_ir::Binder::dummy(FnSig {
1910        abi: data.abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol),
1911        c_variadic: data.is_varargs(),
1912        safety: if data.is_unsafe() { Safety::Unsafe } else { Safety::Safe },
1913        inputs_and_output,
1914    }))
1915}
1916
1917fn type_for_adt<'db>(db: &'db dyn HirDatabase, adt: AdtId) -> EarlyBinder<'db, Ty<'db>> {
1918    let interner = DbInterner::new_with(db, None, None);
1919    let args = GenericArgs::identity_for_item(interner, adt.into());
1920    let ty = Ty::new_adt(interner, adt, args);
1921    EarlyBinder::bind(ty)
1922}
1923
1924fn fn_sig_for_struct_constructor<'db>(
1925    db: &'db dyn HirDatabase,
1926    def: StructId,
1927) -> EarlyBinder<'db, PolyFnSig<'db>> {
1928    let field_tys = db.field_types(def.into());
1929    let params = field_tys.iter().map(|(_, ty)| ty.skip_binder());
1930    let ret = type_for_adt(db, def.into()).skip_binder();
1931
1932    let inputs_and_output =
1933        Tys::new_from_iter(DbInterner::new_with(db, None, None), params.chain(Some(ret)));
1934    EarlyBinder::bind(Binder::dummy(FnSig {
1935        abi: FnAbi::RustCall,
1936        c_variadic: false,
1937        safety: Safety::Safe,
1938        inputs_and_output,
1939    }))
1940}
1941
1942fn fn_sig_for_enum_variant_constructor<'db>(
1943    db: &'db dyn HirDatabase,
1944    def: EnumVariantId,
1945) -> EarlyBinder<'db, PolyFnSig<'db>> {
1946    let field_tys = db.field_types(def.into());
1947    let params = field_tys.iter().map(|(_, ty)| ty.skip_binder());
1948    let parent = def.lookup(db).parent;
1949    let ret = type_for_adt(db, parent.into()).skip_binder();
1950
1951    let inputs_and_output =
1952        Tys::new_from_iter(DbInterner::new_with(db, None, None), params.chain(Some(ret)));
1953    EarlyBinder::bind(Binder::dummy(FnSig {
1954        abi: FnAbi::RustCall,
1955        c_variadic: false,
1956        safety: Safety::Safe,
1957        inputs_and_output,
1958    }))
1959}
1960
1961pub(crate) fn associated_ty_item_bounds<'db>(
1963    db: &'db dyn HirDatabase,
1964    type_alias: TypeAliasId,
1965) -> EarlyBinder<'db, BoundExistentialPredicates<'db>> {
1966    let type_alias_data = db.type_alias_signature(type_alias);
1967    let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db);
1968    let interner = DbInterner::new_with(db, Some(resolver.krate()), None);
1969    let mut ctx = TyLoweringContext::new(
1970        db,
1971        &resolver,
1972        &type_alias_data.store,
1973        type_alias.into(),
1974        LifetimeElisionKind::AnonymousReportError,
1975    );
1976    let self_ty = Ty::new_error(interner, ErrorGuaranteed);
1979
1980    let mut bounds = Vec::new();
1981    for bound in &type_alias_data.bounds {
1982        ctx.lower_type_bound(bound, self_ty, false).for_each(|pred| {
1983            if let Some(bound) = pred
1984                .kind()
1985                .map_bound(|c| match c {
1986                    rustc_type_ir::ClauseKind::Trait(t) => {
1987                        let id = t.def_id();
1988                        let is_auto = db.trait_signature(id.0).flags.contains(TraitFlags::AUTO);
1989                        if is_auto {
1990                            Some(ExistentialPredicate::AutoTrait(t.def_id()))
1991                        } else {
1992                            Some(ExistentialPredicate::Trait(ExistentialTraitRef::new_from_args(
1993                                interner,
1994                                t.def_id(),
1995                                GenericArgs::new_from_iter(
1996                                    interner,
1997                                    t.trait_ref.args.iter().skip(1),
1998                                ),
1999                            )))
2000                        }
2001                    }
2002                    rustc_type_ir::ClauseKind::Projection(p) => Some(
2003                        ExistentialPredicate::Projection(ExistentialProjection::new_from_args(
2004                            interner,
2005                            p.def_id(),
2006                            GenericArgs::new_from_iter(
2007                                interner,
2008                                p.projection_term.args.iter().skip(1),
2009                            ),
2010                            p.term,
2011                        )),
2012                    ),
2013                    rustc_type_ir::ClauseKind::TypeOutlives(_) => None,
2014                    rustc_type_ir::ClauseKind::RegionOutlives(_)
2015                    | rustc_type_ir::ClauseKind::ConstArgHasType(_, _)
2016                    | rustc_type_ir::ClauseKind::WellFormed(_)
2017                    | rustc_type_ir::ClauseKind::ConstEvaluatable(_)
2018                    | rustc_type_ir::ClauseKind::HostEffect(_)
2019                    | rustc_type_ir::ClauseKind::UnstableFeature(_) => unreachable!(),
2020                })
2021                .transpose()
2022            {
2023                bounds.push(bound);
2024            }
2025        });
2026    }
2027
2028    if !ctx.unsized_types.contains(&self_ty)
2029        && let Some(sized_trait) = LangItem::Sized.resolve_trait(db, resolver.krate())
2030    {
2031        let sized_clause = Binder::dummy(ExistentialPredicate::Trait(ExistentialTraitRef::new(
2032            interner,
2033            sized_trait.into(),
2034            [] as [GenericArg<'_>; 0],
2035        )));
2036        bounds.push(sized_clause);
2037    }
2038
2039    EarlyBinder::bind(BoundExistentialPredicates::new_from_iter(interner, bounds))
2040}
2041
2042pub(crate) fn associated_type_by_name_including_super_traits<'db>(
2043    db: &'db dyn HirDatabase,
2044    trait_ref: TraitRef<'db>,
2045    name: &Name,
2046) -> Option<(TraitRef<'db>, TypeAliasId)> {
2047    let interner = DbInterner::new_with(db, None, None);
2048    rustc_type_ir::elaborate::supertraits(interner, Binder::dummy(trait_ref)).find_map(|t| {
2049        let trait_id = t.as_ref().skip_binder().def_id.0;
2050        let assoc_type = trait_id.trait_items(db).associated_type_by_name(name)?;
2051        Some((t.skip_binder(), assoc_type))
2052    })
2053}
2054
2055pub fn associated_type_shorthand_candidates(
2056    db: &dyn HirDatabase,
2057    def: GenericDefId,
2058    res: TypeNs,
2059    mut cb: impl FnMut(&Name, TypeAliasId) -> bool,
2060) -> Option<TypeAliasId> {
2061    let interner = DbInterner::new_with(db, None, None);
2062    named_associated_type_shorthand_candidates(interner, def, res, None, |name, _, id| {
2063        cb(name, id).then_some(id)
2064    })
2065}
2066
2067#[tracing::instrument(skip(interner, check_alias))]
2068fn named_associated_type_shorthand_candidates<'db, R>(
2069    interner: DbInterner<'db>,
2070    def: GenericDefId,
2073    res: TypeNs,
2074    assoc_name: Option<Name>,
2075    mut check_alias: impl FnMut(&Name, TraitRef<'db>, TypeAliasId) -> Option<R>,
2076) -> Option<R> {
2077    let db = interner.db;
2078    let mut search = |t: TraitRef<'db>| -> Option<R> {
2079        let mut checked_traits = FxHashSet::default();
2080        let mut check_trait = |trait_ref: TraitRef<'db>| {
2081            let trait_id = trait_ref.def_id.0;
2082            let name = &db.trait_signature(trait_id).name;
2083            tracing::debug!(?trait_id, ?name);
2084            if !checked_traits.insert(trait_id) {
2085                return None;
2086            }
2087            let data = trait_id.trait_items(db);
2088
2089            tracing::debug!(?data.items);
2090            for (name, assoc_id) in &data.items {
2091                if let &AssocItemId::TypeAliasId(alias) = assoc_id
2092                    && let Some(ty) = check_alias(name, trait_ref, alias)
2093                {
2094                    return Some(ty);
2095                }
2096            }
2097            None
2098        };
2099        let mut stack: SmallVec<[_; 4]> = smallvec![t];
2100        while let Some(trait_ref) = stack.pop() {
2101            if let Some(alias) = check_trait(trait_ref) {
2102                return Some(alias);
2103            }
2104            for pred in generic_predicates_filtered_by(
2105                db,
2106                GenericDefId::TraitId(trait_ref.def_id.0),
2107                PredicateFilter::SelfTrait,
2108                |pred| pred != def && pred == GenericDefId::TraitId(trait_ref.def_id.0),
2113            )
2114            .0
2115            .deref()
2116            {
2117                tracing::debug!(?pred);
2118                let sup_trait_ref = match pred.kind().skip_binder() {
2119                    rustc_type_ir::ClauseKind::Trait(pred) => pred.trait_ref,
2120                    _ => continue,
2121                };
2122                let sup_trait_ref =
2123                    EarlyBinder::bind(sup_trait_ref).instantiate(interner, trait_ref.args);
2124                stack.push(sup_trait_ref);
2125            }
2126            tracing::debug!(?stack);
2127        }
2128
2129        None
2130    };
2131
2132    match res {
2133        TypeNs::SelfType(impl_id) => {
2134            let trait_ref = db.impl_trait(impl_id)?;
2135
2136            search(trait_ref.skip_binder())
2142        }
2143        TypeNs::GenericParam(param_id) => {
2144            if let GenericDefId::TraitId(trait_id) = param_id.parent() {
2148                let trait_name = &db.trait_signature(trait_id).name;
2149                tracing::debug!(?trait_name);
2150                let trait_generics = generics(db, trait_id.into());
2151                tracing::debug!(?trait_generics);
2152                if trait_generics[param_id.local_id()].is_trait_self() {
2153                    let args = GenericArgs::identity_for_item(interner, trait_id.into());
2154                    let trait_ref = TraitRef::new_from_args(interner, trait_id.into(), args);
2155                    tracing::debug!(?args, ?trait_ref);
2156                    return search(trait_ref);
2157                }
2158            }
2159
2160            let predicates =
2161                db.generic_predicates_for_param(def, param_id.into(), assoc_name.clone());
2162            predicates
2163                .iter()
2164                .find_map(|pred| match (*pred).kind().skip_binder() {
2165                    rustc_type_ir::ClauseKind::Trait(trait_predicate) => Some(trait_predicate),
2166                    _ => None,
2167                })
2168                .and_then(|trait_predicate| {
2169                    let trait_ref = trait_predicate.trait_ref;
2170                    assert!(
2171                        !trait_ref.has_escaping_bound_vars(),
2172                        "FIXME unexpected higher-ranked trait bound"
2173                    );
2174                    search(trait_ref)
2175                })
2176        }
2177        _ => None,
2178    }
2179}