Skip to main content

hir_ty/next_solver/
interner.rs

1//! Things related to the Interner in the next-trait-solver.
2
3use std::{fmt, ops::ControlFlow};
4
5use either::Either;
6use intern::{Interned, InternedRef, InternedSliceRef, impl_internable};
7use macros::GenericTypeVisitable;
8use rustc_abi::ReprOptions;
9use rustc_ast_ir::{FloatTy, IntTy, UintTy};
10pub use tls_cache::clear_tls_solver_cache;
11pub use tls_db::{attach_db, attach_db_allow_change, with_attached_db};
12
13use base_db::Crate;
14use hir_def::{
15    AdtId, CallableDefId, EnumId, GenericParamId, HasModule, ItemContainerId, StructId, TraitId,
16    TypeAliasId, UnionId, VariantId,
17    attrs::AttrFlags,
18    expr_store::{ExpressionStore, StoreVisitor},
19    hir::{ClosureKind as HirClosureKind, CoroutineKind as HirCoroutineKind, ExprId, PatId},
20    lang_item::LangItems,
21    signatures::{
22        EnumFlags, EnumSignature, FnFlags, FunctionSignature, ImplFlags, ImplSignature,
23        StructFlags, StructSignature, TraitFlags, TraitSignature, UnionSignature,
24    },
25};
26use rustc_abi::ExternAbi;
27use rustc_hash::FxHashSet;
28use rustc_index::bit_set::DenseBitSet;
29use rustc_type_ir::{
30    AliasTy, BoundVar, CoroutineWitnessTypes, DebruijnIndex, EarlyBinder, FlagComputation, Flags,
31    FnSigKind, GenericArgKind, GenericTypeVisitable, ImplPolarity, InferTy, Interner, TraitRef,
32    TypeFlags, TypeVisitableExt, Upcast, Variance, VisitorResult,
33    elaborate::elaborate,
34    error::TypeError,
35    fast_reject,
36    inherent::{self, Const as _, GenericsOf, IntoKind, SliceLike as _, Span as _, Ty as _},
37    lang_items::{SolverAdtLangItem, SolverProjectionLangItem, SolverTraitLangItem},
38    solve::{AdtDestructorKind, SizedTraitKind},
39    try_visit,
40};
41
42use crate::{
43    InferBodyId, Span,
44    db::{HirDatabase, InternedClosure, InternedCoroutineId},
45    lower::GenericPredicates,
46    method_resolution::TraitImpls,
47    next_solver::{
48        AdtIdWrapper, AliasTermKind, AliasTyKind, AnyImplId, BoundConst, CallableIdWrapper,
49        CanonicalVarKind, ClosureIdWrapper, Consts, CoroutineClosureIdWrapper, CoroutineIdWrapper,
50        Ctor, FnSig, FreeConstAliasId, FreeTermAliasId, FreeTyAliasId, FxIndexMap,
51        GeneralConstIdWrapper, ImplOrTraitAssocConstId, ImplOrTraitAssocTermId,
52        ImplOrTraitAssocTyId, InherentAssocConstId, InherentAssocTermId, InherentAssocTyId,
53        LateParamRegion, OpaqueTyIdWrapper, OpaqueTypeKey, RegionAssumptions, ScalarInt,
54        SimplifiedType, SolverContext, SolverDefIds, TermId, TraitAssocConstId, TraitAssocTermId,
55        TraitAssocTyId, TraitIdWrapper, TypeAliasIdWrapper, UnevaluatedConst, Unnormalized,
56        util::{explicit_item_bounds, explicit_item_self_bounds},
57    },
58};
59
60use super::{
61    Binder, BoundExistentialPredicates, BoundTy, BoundTyKind, Clause, ClauseKind, Clauses, Const,
62    ErrorGuaranteed, ExprConst, ExternalConstraints, GenericArg, GenericArgs, ParamConst, ParamEnv,
63    ParamTy, PredefinedOpaques, Predicate, SolverDefId, Term, Ty, TyKind, Tys, ValTree, ValueConst,
64    abi::Safety,
65    fold::{BoundVarReplacer, BoundVarReplacerDelegate, FnMutDelegate},
66    generics::{Generics, generics},
67    region::{BoundRegion, BoundRegionKind, EarlyParamRegion, Region},
68    util::sizedness_constraint_for_ty,
69};
70
71macro_rules! interned_slice {
72    ($storage:ident, $name:ident, $stored_name:ident, $default_types_field:ident, $ty_db:ty, $ty_static:ty $(,)?) => {
73        const _: () = {
74            #[allow(unused_lifetimes)]
75            fn _ensure_correct_types<'db: 'static>(v: $ty_db) -> $ty_static { v }
76        };
77
78        ::intern::impl_slice_internable!(gc; $storage, (), $ty_static);
79
80        #[derive(Clone, Copy, PartialEq, Eq, Hash)]
81        pub struct $name<'db> {
82            interned: ::intern::InternedSliceRef<'db, $storage>,
83        }
84
85        impl<'db> std::fmt::Debug for $name<'db> {
86            fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87                self.as_slice().fmt(fmt)
88            }
89        }
90
91        impl<'db> $name<'db> {
92            #[inline]
93            pub fn empty() -> Self {
94                $crate::next_solver::default_types().empty.$default_types_field
95            }
96
97            #[inline]
98            pub fn new_from_slice(slice: &[$ty_db]) -> Self {
99                let slice = unsafe { ::std::mem::transmute::<&[$ty_db], &[$ty_static]>(slice) };
100                Self { interned: ::intern::InternedSlice::from_header_and_slice((), slice) }
101            }
102
103            #[inline]
104            pub fn new_from_iter<I, T>(_interner: DbInterner<'db>, args: I) -> T::Output
105            where
106                I: IntoIterator<Item = T>,
107                T: ::rustc_type_ir::CollectAndApply<$ty_db, Self>,
108            {
109                ::rustc_type_ir::CollectAndApply::collect_and_apply(args.into_iter(), |g| {
110                    Self::new_from_slice(g)
111                })
112            }
113
114            #[inline]
115            pub fn as_slice(self) -> &'db [$ty_db] {
116                let slice = &self.interned.get().slice;
117                unsafe { ::std::mem::transmute::<&[$ty_static], &[$ty_db]>(slice) }
118            }
119
120            #[inline]
121            pub fn iter(self) -> ::std::iter::Copied<::std::slice::Iter<'db, $ty_db>> {
122                self.as_slice().iter().copied()
123            }
124
125            #[inline]
126            pub fn len(self) -> usize {
127                self.as_slice().len()
128            }
129
130            #[inline]
131            pub fn is_empty(self) -> bool {
132                self.as_slice().is_empty()
133            }
134        }
135
136        impl<'db> IntoIterator for $name<'db> {
137            type IntoIter = ::std::iter::Copied<::std::slice::Iter<'db, $ty_db>>;
138            type Item = $ty_db;
139            #[inline]
140            fn into_iter(self) -> Self::IntoIter { self.iter() }
141        }
142
143        impl<'db> ::std::ops::Deref for $name<'db> {
144            type Target = [$ty_db];
145
146            #[inline]
147            fn deref(&self) -> &Self::Target {
148                (*self).as_slice()
149            }
150        }
151
152        impl<'db> rustc_type_ir::inherent::SliceLike for $name<'db> {
153            type Item = $ty_db;
154
155            type IntoIter = ::std::iter::Copied<::std::slice::Iter<'db, $ty_db>>;
156
157            #[inline]
158            fn iter(self) -> Self::IntoIter {
159                self.iter()
160            }
161
162            #[inline]
163            fn as_slice(&self) -> &[Self::Item] {
164                (*self).as_slice()
165            }
166        }
167
168        impl<'db> Default for $name<'db> {
169            #[inline]
170            fn default() -> Self {
171                $name::empty()
172            }
173        }
174
175
176        impl<'db, V: $crate::next_solver::interner::WorldExposer>
177            rustc_type_ir::GenericTypeVisitable<V> for $name<'db>
178        {
179            #[inline]
180            fn generic_visit_with(&self, visitor: &mut V) {
181                if visitor.on_interned_slice(self.interned).is_continue() {
182                    self.as_slice().iter().for_each(|it| it.generic_visit_with(visitor));
183                }
184            }
185        }
186
187        $crate::next_solver::interner::impl_stored_interned_slice!($storage, $name, $stored_name);
188    };
189}
190pub(crate) use interned_slice;
191
192macro_rules! impl_stored_interned_slice {
193    ( $storage:ident, $name:ident, $stored_name:ident $(,)? ) => {
194        #[derive(Clone, PartialEq, Eq, Hash)]
195        pub struct $stored_name {
196            interned: ::intern::InternedSlice<$storage>,
197        }
198
199        impl $stored_name {
200            #[inline]
201            fn new(it: $name<'_>) -> Self {
202                Self { interned: it.interned.to_owned() }
203            }
204
205            // FIXME: This transmute is not safe as is!
206            #[inline]
207            pub fn as_ref<'a, 'db>(&'a self) -> $name<'db> {
208                let it = $name { interned: self.interned.as_ref() };
209                unsafe { std::mem::transmute::<$name<'a>, $name<'db>>(it) }
210            }
211        }
212
213        // SAFETY: It is safe to store this type in queries (but not `$name`).
214        unsafe impl salsa::SalsaValue for $stored_name {}
215
216        impl std::fmt::Debug for $stored_name {
217            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
218                self.as_ref().fmt(f)
219            }
220        }
221
222        impl $name<'_> {
223            #[inline]
224            pub fn store(self) -> $stored_name {
225                $stored_name::new(self)
226            }
227        }
228    };
229}
230pub(crate) use impl_stored_interned_slice;
231
232macro_rules! impl_foldable_for_interned_slice {
233    ($name:ident) => {
234        impl<'db> ::rustc_type_ir::TypeVisitable<DbInterner<'db>> for $name<'db> {
235            fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
236                &self,
237                visitor: &mut V,
238            ) -> V::Result {
239                use rustc_ast_ir::visit::VisitorResult;
240                rustc_ast_ir::walk_visitable_list!(visitor, (*self).iter());
241                V::Result::output()
242            }
243        }
244
245        impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for $name<'db> {
246            fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
247                self,
248                folder: &mut F,
249            ) -> Result<Self, F::Error> {
250                Self::new_from_iter(folder.cx(), self.iter().map(|it| it.try_fold_with(folder)))
251            }
252            fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(
253                self,
254                folder: &mut F,
255            ) -> Self {
256                Self::new_from_iter(folder.cx(), self.iter().map(|it| it.fold_with(folder)))
257            }
258        }
259    };
260}
261pub(crate) use impl_foldable_for_interned_slice;
262
263macro_rules! impl_foldable_for_stored_type {
264    ($name:ident) => {
265        impl<'db> ::rustc_type_ir::TypeVisitable<DbInterner<'db>> for $name {
266            fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
267                &self,
268                visitor: &mut V,
269            ) -> V::Result {
270                self.as_ref().visit_with(visitor)
271            }
272        }
273
274        impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for $name {
275            fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
276                self,
277                folder: &mut F,
278            ) -> Result<Self, F::Error> {
279                Ok(self.as_ref().try_fold_with(folder)?.store())
280            }
281            fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(
282                self,
283                folder: &mut F,
284            ) -> Self {
285                self.as_ref().fold_with(folder).store()
286            }
287        }
288    };
289}
290pub(crate) use impl_foldable_for_stored_type;
291
292macro_rules! impl_stored_interned {
293    ( $storage:ident, $name:ident, $stored_name:ident $(,)? ) => {
294        #[derive(Clone, PartialEq, Eq, Hash, ::salsa::SalsaValue)]
295        pub struct $stored_name {
296            interned: ::intern::Interned<$storage>,
297        }
298
299        impl $stored_name {
300            #[inline]
301            fn new(it: $name<'_>) -> Self {
302                Self { interned: it.interned.to_owned() }
303            }
304
305            #[inline]
306            pub fn as_ref<'a, 'db>(&'a self) -> $name<'db> {
307                let it = $name { interned: self.interned.as_ref() };
308                unsafe { std::mem::transmute::<$name<'a>, $name<'db>>(it) }
309            }
310        }
311
312        impl std::fmt::Debug for $stored_name {
313            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
314                self.as_ref().fmt(f)
315            }
316        }
317
318        impl $name<'_> {
319            #[inline]
320            pub fn store(self) -> $stored_name {
321                $stored_name::new(self)
322            }
323        }
324    };
325}
326pub(crate) use impl_stored_interned;
327
328/// This is a visitor trait that treats any interned thing specifically. Visitables are expected to call
329/// the trait's methods when encountering an interned. This is used to implement marking in GC.
330pub trait WorldExposer {
331    fn on_interned<T: intern::Internable>(
332        &mut self,
333        interned: InternedRef<'_, T>,
334    ) -> ControlFlow<()>;
335    fn on_interned_slice<T: intern::SliceInternable>(
336        &mut self,
337        interned: InternedSliceRef<'_, T>,
338    ) -> ControlFlow<()>;
339}
340
341#[derive(Debug, Copy, Clone)]
342pub struct DbInterner<'db> {
343    pub(crate) db: &'db dyn HirDatabase,
344    krate: Option<Crate>,
345    lang_items: Option<&'db LangItems>,
346}
347
348// FIXME: very wrong, see https://github.com/rust-lang/rust/pull/144808
349unsafe impl Send for DbInterner<'_> {}
350unsafe impl Sync for DbInterner<'_> {}
351
352impl<'db> DbInterner<'db> {
353    // FIXME(next-solver): remove this method
354    #[doc(hidden)]
355    pub fn conjure() -> DbInterner<'db> {
356        // Here we can not reinit the cache since we do that when we attach the db.
357        crate::with_attached_db(|db| DbInterner {
358            db: unsafe { std::mem::transmute::<&dyn HirDatabase, &'db dyn HirDatabase>(db) },
359            krate: None,
360            lang_items: None,
361        })
362    }
363
364    /// Creates a new interner without an active crate. Good only for interning things, not for trait solving etc..
365    /// As a rule of thumb, when you create an `InferCtxt`, you need to provide the crate (and the block).
366    ///
367    /// Elaboration is a special kind: it needs lang items (for `Sized`), therefore it needs `new_with()`.
368    pub fn new_no_crate(db: &'db dyn HirDatabase) -> Self {
369        // We do not reinit the cache here, since anything accessing the cache needs an InferCtxt,
370        // and we panic when trying to construct an InferCtxt for an Interner without a crate.
371        DbInterner { db, krate: None, lang_items: None }
372    }
373
374    pub fn new_with(db: &'db dyn HirDatabase, krate: Crate) -> DbInterner<'db> {
375        tls_cache::reinit_cache(db);
376        DbInterner {
377            db,
378            krate: Some(krate),
379            // As an approximation, when we call `new_with` we're trait solving, therefore we need the lang items.
380            // This is also convenient since here we have a starting crate but not in `new_no_crate`.
381            lang_items: Some(hir_def::lang_item::lang_items(db, krate)),
382        }
383    }
384
385    #[inline]
386    pub fn db(&self) -> &'db dyn HirDatabase {
387        self.db
388    }
389
390    #[inline]
391    #[track_caller]
392    pub fn lang_items(&self) -> &'db LangItems {
393        self.lang_items.expect(
394            "Must have `DbInterner::lang_items`.\n\n\
395            Note: you might have called `DbInterner::new_no_crate()` \
396            where you should've called `DbInterner::new_with()`",
397        )
398    }
399
400    #[inline]
401    pub fn default_types(&self) -> &'db crate::next_solver::DefaultAny<'db> {
402        crate::next_solver::default_types()
403    }
404
405    #[inline]
406    pub(crate) fn expect_crate(&self) -> Crate {
407        self.krate.expect("should have a crate")
408    }
409}
410
411impl<'db> inherent::Span<DbInterner<'db>> for Span {
412    fn dummy() -> Self {
413        Span::Dummy
414    }
415}
416
417interned_slice!(
418    BoundVarKindsStorage,
419    BoundVarKinds,
420    StoredBoundVarKinds,
421    bound_var_kinds,
422    BoundVariableKind<'db>,
423    BoundVariableKind<'static>,
424);
425
426pub type BoundVariableKind<'db> = rustc_type_ir::BoundVariableKind<DbInterner<'db>>;
427
428interned_slice!(
429    CanonicalVarsStorage,
430    CanonicalVarKinds,
431    StoredCanonicalVars,
432    canonical_vars,
433    CanonicalVarKind<'db>,
434    CanonicalVarKind<'static>
435);
436
437pub struct DepNodeIndex;
438
439#[derive(Debug)]
440pub struct Tracked<T: fmt::Debug + Clone>(T);
441
442#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
443pub struct AllocId;
444
445interned_slice!(VariancesOfStorage, VariancesOf, StoredVariancesOf, variances, Variance, Variance);
446
447bitflags::bitflags! {
448    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
449    struct AdtFlags: u8 {
450        const IS_FUNDAMENTAL = 1 << 0;
451        const IS_PACKED = 1 << 1;
452        const HAS_REPR = 1 << 2;
453        const IS_PHANTOM_DATA = 1 << 3;
454        const IS_MANUALLY_DROP = 1 << 4;
455        const IS_BOX = 1 << 5;
456    }
457}
458
459#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
460enum AdtDefInner {
461    Struct { id: StructId, flags: AdtFlags },
462    Union { id: UnionId, flags: AdtFlags },
463    Enum { id: EnumId, flags: AdtFlags },
464}
465
466#[derive(Clone, Copy, PartialEq, Eq, Hash)]
467pub struct AdtDef(AdtDefInner);
468
469const _: () = assert!(size_of::<AdtDef>() == 12);
470
471impl AdtDef {
472    pub fn new<'db>(def_id: AdtId, interner: DbInterner<'db>) -> Self {
473        let db = interner.db();
474        let inner = match def_id {
475            AdtId::StructId(id) => {
476                let data = StructSignature::of(db, id);
477                let mut flags = AdtFlags::empty();
478                if data.flags.contains(StructFlags::FUNDAMENTAL) {
479                    flags.insert(AdtFlags::IS_FUNDAMENTAL);
480                }
481                if data.flags.contains(StructFlags::IS_PHANTOM_DATA) {
482                    flags.insert(AdtFlags::IS_PHANTOM_DATA);
483                }
484                if data.flags.contains(StructFlags::IS_MANUALLY_DROP) {
485                    flags.insert(AdtFlags::IS_MANUALLY_DROP);
486                }
487                if data.flags.contains(StructFlags::IS_BOX) {
488                    flags.insert(AdtFlags::IS_BOX);
489                }
490                if data.flags.contains(StructFlags::HAS_REPR) {
491                    flags.insert(AdtFlags::HAS_REPR);
492                    if data.repr(db, id).is_some_and(|repr| repr.packed()) {
493                        flags.insert(AdtFlags::IS_PACKED);
494                    }
495                }
496                AdtDefInner::Struct { id, flags }
497            }
498            AdtId::UnionId(id) => {
499                let data = UnionSignature::of(db, id);
500                let mut flags = AdtFlags::empty();
501                if data.flags.contains(StructFlags::FUNDAMENTAL) {
502                    flags.insert(AdtFlags::IS_FUNDAMENTAL);
503                }
504                if data.flags.contains(StructFlags::HAS_REPR) {
505                    flags.insert(AdtFlags::HAS_REPR);
506                    if data.repr(db, id).is_some_and(|repr| repr.packed()) {
507                        flags.insert(AdtFlags::IS_PACKED);
508                    }
509                }
510                AdtDefInner::Union { id, flags }
511            }
512            AdtId::EnumId(id) => {
513                let data = EnumSignature::of(db, id);
514                let mut flags = AdtFlags::empty();
515                if data.flags.contains(EnumFlags::FUNDAMENTAL) {
516                    flags.insert(AdtFlags::IS_FUNDAMENTAL);
517                }
518                if data.flags.contains(EnumFlags::HAS_REPR) {
519                    flags.insert(AdtFlags::HAS_REPR);
520                    if data.repr(db, id).is_some_and(|repr| repr.packed()) {
521                        flags.insert(AdtFlags::IS_PACKED);
522                    }
523                }
524                AdtDefInner::Enum { id, flags }
525            }
526        };
527        AdtDef(inner)
528    }
529
530    #[inline]
531    pub fn def_id(self) -> AdtId {
532        match self.0 {
533            AdtDefInner::Struct { id, .. } => AdtId::StructId(id),
534            AdtDefInner::Union { id, .. } => AdtId::UnionId(id),
535            AdtDefInner::Enum { id, .. } => AdtId::EnumId(id),
536        }
537    }
538
539    #[inline]
540    fn flags(self) -> AdtFlags {
541        match self.0 {
542            AdtDefInner::Struct { flags, .. }
543            | AdtDefInner::Union { flags, .. }
544            | AdtDefInner::Enum { flags, .. } => flags,
545        }
546    }
547
548    #[inline]
549    pub fn is_struct(self) -> bool {
550        matches!(self.0, AdtDefInner::Struct { .. })
551    }
552
553    #[inline]
554    pub fn is_union(self) -> bool {
555        matches!(self.0, AdtDefInner::Union { .. })
556    }
557
558    #[inline]
559    pub fn is_enum(self) -> bool {
560        matches!(self.0, AdtDefInner::Enum { .. })
561    }
562
563    #[inline]
564    pub fn is_box(self) -> bool {
565        matches!(self.0, AdtDefInner::Struct { flags, .. } if flags.contains(AdtFlags::IS_BOX))
566    }
567
568    #[inline]
569    pub fn repr(self, db: &dyn HirDatabase) -> ReprOptions {
570        if self.flags().contains(AdtFlags::HAS_REPR) {
571            AttrFlags::repr_assume_has(db, self.def_id()).unwrap_or_default()
572        } else {
573            ReprOptions::default()
574        }
575    }
576}
577
578impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
579    fn def_id(self) -> AdtIdWrapper {
580        self.def_id().into()
581    }
582
583    fn is_struct(self) -> bool {
584        self.is_struct()
585    }
586
587    fn is_phantom_data(self) -> bool {
588        matches!(self.0, AdtDefInner::Struct { flags, .. } if flags.contains(AdtFlags::IS_PHANTOM_DATA))
589    }
590
591    fn is_manually_drop(self) -> bool {
592        matches!(self.0, AdtDefInner::Struct { flags, .. } if flags.contains(AdtFlags::IS_MANUALLY_DROP))
593    }
594
595    fn is_packed(self) -> bool {
596        self.flags().contains(AdtFlags::IS_PACKED)
597    }
598
599    fn is_fundamental(self) -> bool {
600        self.flags().contains(AdtFlags::IS_FUNDAMENTAL)
601    }
602
603    fn struct_tail_ty(
604        self,
605        interner: DbInterner<'db>,
606    ) -> Option<EarlyBinder<DbInterner<'db>, Ty<'db>>> {
607        let hir_def::AdtId::StructId(struct_id) = self.def_id() else {
608            return None;
609        };
610        let id: VariantId = struct_id.into();
611        let field_types = interner.db().field_types(id);
612
613        field_types.iter().last().map(|f| f.1.ty())
614    }
615
616    fn all_field_tys(
617        self,
618        interner: DbInterner<'db>,
619    ) -> EarlyBinder<DbInterner<'db>, impl IntoIterator<Item = Ty<'db>>> {
620        let db = interner.db();
621        let field_tys =
622            |id: VariantId| db.field_types(id).iter().map(|(_, ty)| ty.ty().skip_binder());
623        let tys = match self.def_id() {
624            hir_def::AdtId::StructId(id) => Either::Left(field_tys(id.into())),
625            hir_def::AdtId::UnionId(id) => Either::Left(field_tys(id.into())),
626            hir_def::AdtId::EnumId(id) => Either::Right(
627                id.enum_variants(db)
628                    .variants
629                    .values()
630                    .flat_map(move |&(variant_id, _)| field_tys(variant_id.into())),
631            ),
632        };
633
634        EarlyBinder::bind(tys)
635    }
636
637    fn sizedness_constraint(
638        self,
639        interner: DbInterner<'db>,
640        sizedness: SizedTraitKind,
641    ) -> Option<EarlyBinder<DbInterner<'db>, Ty<'db>>> {
642        let tail_ty = self.struct_tail_ty(interner)?;
643        tail_ty
644            .map_bound(|tail_ty| sizedness_constraint_for_ty(interner, sizedness, tail_ty))
645            .transpose()
646    }
647
648    fn destructor(self, interner: DbInterner<'db>) -> Option<AdtDestructorKind> {
649        crate::drop::destructor(interner.db, self.def_id()).map(|_| AdtDestructorKind::NotConst)
650    }
651
652    fn field_representing_type_info(
653        self,
654        _interner: DbInterner<'db>,
655        _args: GenericArgs<'db>,
656    ) -> Option<rustc_type_ir::FieldInfo<DbInterner<'db>>> {
657        // FIXME
658        None
659    }
660}
661
662impl fmt::Debug for AdtDef {
663    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
664        crate::with_attached_db(|db| match self.0 {
665            AdtDefInner::Struct { id, .. } => {
666                let data = StructSignature::of(db, id);
667                f.write_str(data.name.as_str())
668            }
669            AdtDefInner::Union { id, .. } => {
670                let data = UnionSignature::of(db, id);
671                f.write_str(data.name.as_str())
672            }
673            AdtDefInner::Enum { id, .. } => {
674                let data = EnumSignature::of(db, id);
675                f.write_str(data.name.as_str())
676            }
677        })
678    }
679}
680
681#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
682pub struct Features;
683
684impl<'db> inherent::Features<DbInterner<'db>> for Features {
685    fn generic_const_exprs(self) -> bool {
686        false
687    }
688
689    fn coroutine_clone(self) -> bool {
690        false
691    }
692
693    fn generic_const_args(self) -> bool {
694        false
695    }
696
697    fn feature_bound_holds_in_crate(self, _symbol: Symbol) -> bool {
698        false
699    }
700}
701
702#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, GenericTypeVisitable)]
703pub struct Symbol;
704
705impl<'db> inherent::Symbol<DbInterner<'db>> for Symbol {
706    fn is_kw_underscore_lifetime(self) -> bool {
707        false
708    }
709}
710
711#[derive(Debug, Clone, Eq, PartialEq, Hash)]
712pub struct UnsizingParams(pub(crate) DenseBitSet<u32>);
713
714impl std::ops::Deref for UnsizingParams {
715    type Target = DenseBitSet<u32>;
716
717    fn deref(&self) -> &Self::Target {
718        &self.0
719    }
720}
721
722pub type PatternKind<'db> = rustc_type_ir::PatternKind<DbInterner<'db>>;
723
724#[derive(Clone, Copy, PartialEq, Eq, Hash)]
725pub struct Pattern<'db> {
726    interned: InternedRef<'db, PatternInterned>,
727}
728
729#[derive(PartialEq, Eq, Hash, GenericTypeVisitable)]
730struct PatternInterned(PatternKind<'static>);
731
732impl_internable!(gc; PatternInterned);
733
734const _: () = {
735    const fn is_copy<T: Copy>() {}
736    is_copy::<Pattern<'static>>();
737};
738
739impl<'db> Pattern<'db> {
740    pub fn new(_interner: DbInterner<'db>, kind: PatternKind<'db>) -> Self {
741        let kind = unsafe { std::mem::transmute::<PatternKind<'db>, PatternKind<'static>>(kind) };
742        Self { interned: Interned::new_gc(PatternInterned(kind)) }
743    }
744
745    pub fn inner(&self) -> &PatternKind<'db> {
746        let inner = &self.interned.0;
747        unsafe { std::mem::transmute::<&PatternKind<'static>, &PatternKind<'db>>(inner) }
748    }
749}
750
751impl<'db> std::fmt::Debug for Pattern<'db> {
752    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
753        self.kind().fmt(f)
754    }
755}
756
757impl<'db> Flags for Pattern<'db> {
758    fn flags(&self) -> TypeFlags {
759        match self.inner() {
760            PatternKind::Range { start, end } => {
761                FlagComputation::for_const_kind(&start.kind()).flags
762                    | FlagComputation::for_const_kind(&end.kind()).flags
763            }
764            PatternKind::Or(pats) => {
765                let mut flags = pats.as_slice()[0].flags();
766                for pat in pats.as_slice()[1..].iter() {
767                    flags |= pat.flags();
768                }
769                flags
770            }
771            PatternKind::NotNull => TypeFlags::empty(),
772        }
773    }
774
775    fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex {
776        match self.inner() {
777            PatternKind::Range { start, end } => {
778                start.outer_exclusive_binder().max(end.outer_exclusive_binder())
779            }
780            PatternKind::Or(pats) => {
781                let mut idx = pats.as_slice()[0].outer_exclusive_binder();
782                for pat in pats.as_slice()[1..].iter() {
783                    idx = idx.max(pat.outer_exclusive_binder());
784                }
785                idx
786            }
787            PatternKind::NotNull => rustc_type_ir::INNERMOST,
788        }
789    }
790}
791
792impl<'db> rustc_type_ir::inherent::IntoKind for Pattern<'db> {
793    type Kind = rustc_type_ir::PatternKind<DbInterner<'db>>;
794    fn kind(self) -> Self::Kind {
795        *self.inner()
796    }
797}
798
799impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for Pattern<'db> {
800    fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
801        &self,
802        visitor: &mut V,
803    ) -> V::Result {
804        self.kind().visit_with(visitor)
805    }
806}
807
808impl<'db, V: WorldExposer> rustc_type_ir::GenericTypeVisitable<V> for Pattern<'db> {
809    fn generic_visit_with(&self, visitor: &mut V) {
810        if visitor.on_interned(self.interned).is_continue() {
811            self.kind().generic_visit_with(visitor);
812        }
813    }
814}
815
816impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for Pattern<'db> {
817    fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
818        self,
819        folder: &mut F,
820    ) -> Result<Self, F::Error> {
821        Ok(Pattern::new(folder.cx(), self.kind().try_fold_with(folder)?))
822    }
823
824    fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
825        Pattern::new(folder.cx(), self.kind().fold_with(folder))
826    }
827}
828
829impl<'db> rustc_type_ir::relate::Relate<DbInterner<'db>> for Pattern<'db> {
830    fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>(
831        relation: &mut R,
832        a: Self,
833        b: Self,
834    ) -> rustc_type_ir::relate::RelateResult<DbInterner<'db>, Self> {
835        let tcx = relation.cx();
836        match (a.kind(), b.kind()) {
837            (
838                PatternKind::Range { start: start_a, end: end_a },
839                PatternKind::Range { start: start_b, end: end_b },
840            ) => {
841                let start = relation.relate(start_a, start_b)?;
842                let end = relation.relate(end_a, end_b)?;
843                Ok(Pattern::new(tcx, PatternKind::Range { start, end }))
844            }
845            (PatternKind::Or(a), PatternKind::Or(b)) => {
846                if a.len() != b.len() {
847                    return Err(TypeError::Mismatch);
848                }
849                let pats = PatList::new_from_iter(
850                    relation.cx(),
851                    std::iter::zip(a.iter(), b.iter()).map(|(a, b)| relation.relate(a, b)),
852                )?;
853                Ok(Pattern::new(tcx, PatternKind::Or(pats)))
854            }
855            (PatternKind::NotNull, PatternKind::NotNull) => Ok(a),
856            (PatternKind::Range { .. } | PatternKind::Or(_) | PatternKind::NotNull, _) => {
857                Err(TypeError::Mismatch)
858            }
859        }
860    }
861}
862
863interned_slice!(PatListStorage, PatList, StoredPatList, pat_list, Pattern<'db>, Pattern<'static>);
864impl_foldable_for_interned_slice!(PatList);
865
866macro_rules! as_lang_item {
867    (
868        $solver_enum:ident, $self:ident, $def_id:expr, $id_ty:ty;
869
870        $( $variant:ident ),* $(,)?
871    ) => {{
872        let lang_items = $self.lang_items();
873        // Ensure exhaustiveness.
874        if let Some(it) = None::<$solver_enum> {
875            match it {
876                $( $solver_enum::$variant => {} )*
877            }
878        }
879        match $def_id {
880            $( def_id if let Some(it) = lang_items.$variant && <$id_ty>::from(it) == def_id => Some($solver_enum::$variant), )*
881            _ => None
882        }
883    }};
884}
885
886macro_rules! is_lang_item {
887    (
888        $solver_enum:ident, $self:ident, $def_id:expr, $expected_variant:ident;
889
890        $( $variant:ident ),* $(,)?
891    ) => {{
892        let lang_items = $self.lang_items();
893        let def_id = $def_id;
894        match $expected_variant {
895            $( $solver_enum::$variant => lang_items.$variant.is_some_and(|it| it == def_id), )*
896        }
897    }};
898}
899
900impl<'db> Interner for DbInterner<'db> {
901    type DefId = SolverDefId<'db>;
902    type LocalDefId = SolverDefId<'db>;
903    type LocalDefIds = SolverDefIds<'db>;
904    type TraitId = TraitIdWrapper;
905    type ForeignId = TypeAliasIdWrapper;
906    type FunctionId = CallableIdWrapper;
907    type ClosureId = ClosureIdWrapper<'db>;
908    type CoroutineClosureId = CoroutineClosureIdWrapper<'db>;
909    type CoroutineId = CoroutineIdWrapper<'db>;
910    type AdtId = AdtIdWrapper;
911    type ImplId = AnyImplId;
912    type UnevaluatedConstId = GeneralConstIdWrapper<'db>;
913    type TraitAssocTyId = TraitAssocTyId;
914    type TraitAssocConstId = TraitAssocConstId;
915    type TraitAssocTermId = TraitAssocTermId;
916    type OpaqueTyId = OpaqueTyIdWrapper<'db>;
917    type LocalOpaqueTyId = OpaqueTyIdWrapper<'db>;
918    type FreeTyAliasId = FreeTyAliasId;
919    type FreeConstAliasId = FreeConstAliasId;
920    type FreeTermAliasId = FreeTermAliasId;
921    type ImplOrTraitAssocTyId = ImplOrTraitAssocTyId;
922    type ImplOrTraitAssocConstId = ImplOrTraitAssocConstId;
923    type ImplOrTraitAssocTermId = ImplOrTraitAssocTermId;
924    type InherentAssocTyId = InherentAssocTyId;
925    type InherentAssocConstId = InherentAssocConstId;
926    type InherentAssocTermId = InherentAssocTermId;
927    type Span = Span;
928
929    type GenericArgs = GenericArgs<'db>;
930    type GenericArgsSlice = &'db [GenericArg<'db>];
931    type GenericArg = GenericArg<'db>;
932
933    type Term = Term<'db>;
934
935    type BoundVarKinds = BoundVarKinds<'db>;
936
937    type PredefinedOpaques = PredefinedOpaques<'db>;
938
939    fn mk_predefined_opaques_in_body(
940        self,
941        data: &[(OpaqueTypeKey<'db>, Self::Ty)],
942    ) -> Self::PredefinedOpaques {
943        PredefinedOpaques::new_from_slice(data)
944    }
945
946    type CanonicalVarKinds = CanonicalVarKinds<'db>;
947
948    fn mk_canonical_var_kinds(
949        self,
950        kinds: &[rustc_type_ir::CanonicalVarKind<Self>],
951    ) -> Self::CanonicalVarKinds {
952        CanonicalVarKinds::new_from_slice(kinds)
953    }
954
955    type ExternalConstraints = ExternalConstraints<'db>;
956
957    fn mk_external_constraints(
958        self,
959        data: rustc_type_ir::solve::ExternalConstraintsData<Self>,
960    ) -> Self::ExternalConstraints {
961        ExternalConstraints::new(self, data)
962    }
963
964    type DepNodeIndex = DepNodeIndex;
965
966    type Tracked<T: fmt::Debug + Clone> = Tracked<T>;
967
968    type Ty = Ty<'db>;
969    type Tys = Tys<'db>;
970    type FnInputTys = &'db [Ty<'db>];
971    type ParamTy = ParamTy;
972    type Symbol = Symbol;
973
974    type ErrorGuaranteed = ErrorGuaranteed;
975    type BoundExistentialPredicates = BoundExistentialPredicates<'db>;
976    type AllocId = AllocId;
977    type Pat = Pattern<'db>;
978    type PatList = PatList<'db>;
979    type Safety = Safety;
980
981    type Const = Const<'db>;
982    type ParamConst = ParamConst;
983    type ValueConst = ValueConst<'db>;
984    type ValTree = ValTree<'db>;
985    type Consts = Consts<'db>;
986    type ScalarInt = ScalarInt;
987    type ExprConst = ExprConst;
988
989    type Region = Region<'db>;
990    type EarlyParamRegion = EarlyParamRegion;
991    type LateParamRegion = LateParamRegion<'db>;
992
993    type RegionAssumptions = RegionAssumptions<'db>;
994
995    type ParamEnv = ParamEnv<'db>;
996    type Predicate = Predicate<'db>;
997    type Clause = Clause<'db>;
998    type Clauses = Clauses<'db>;
999
1000    type GenericsOf = Generics<'db>;
1001
1002    type VariancesOf = VariancesOf<'db>;
1003
1004    type AdtDef = AdtDef;
1005
1006    type Features = Features;
1007
1008    fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs {
1009        GenericArgs::new_from_slice(args)
1010    }
1011
1012    fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
1013    where
1014        I: Iterator<Item = T>,
1015        T: rustc_type_ir::CollectAndApply<Self::GenericArg, Self::GenericArgs>,
1016    {
1017        GenericArgs::new_from_iter(self, args)
1018    }
1019
1020    type UnsizingParams = UnsizingParams;
1021
1022    fn mk_tracked<T: fmt::Debug + Clone>(
1023        self,
1024        data: T,
1025        _dep_node: Self::DepNodeIndex,
1026    ) -> Self::Tracked<T> {
1027        Tracked(data)
1028    }
1029
1030    fn get_tracked<T: fmt::Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T {
1031        tracked.0.clone()
1032    }
1033
1034    fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, Self::DepNodeIndex) {
1035        (task(), DepNodeIndex)
1036    }
1037
1038    fn with_global_cache<R>(
1039        self,
1040        f: impl FnOnce(&mut rustc_type_ir::search_graph::GlobalCache<Self>) -> R,
1041    ) -> R {
1042        // We make sure to reinit the cache when constructing the Interner.
1043        tls_cache::borrow_assume_valid(self.db, f)
1044    }
1045
1046    fn canonical_param_env_cache_get_or_insert<R>(
1047        self,
1048        _param_env: Self::ParamEnv,
1049        f: impl FnOnce() -> rustc_type_ir::CanonicalParamEnvCacheEntry<Self>,
1050        from_entry: impl FnOnce(&rustc_type_ir::CanonicalParamEnvCacheEntry<Self>) -> R,
1051    ) -> R {
1052        from_entry(&f())
1053    }
1054
1055    fn assert_evaluation_is_concurrent(&self) {
1056        // Turns out, the assumption for this function isn't perfect.
1057        // See https://github.com/rust-lang/trait-system-refactor-initiative/issues/234
1058    }
1059
1060    fn expand_abstract_consts<T: rustc_type_ir::TypeFoldable<Self>>(self, _: T) -> T {
1061        unreachable!("only used by the old trait solver in rustc");
1062    }
1063
1064    fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf {
1065        generics(self, def_id)
1066    }
1067
1068    fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf {
1069        let generic_def = match def_id {
1070            SolverDefId::Ctor(Ctor::Enum(def_id)) | SolverDefId::EnumVariantId(def_id) => {
1071                def_id.loc(self.db).parent.into()
1072            }
1073            SolverDefId::InternedOpaqueTyId(_def_id) => {
1074                // FIXME(next-solver): track variances
1075                //
1076                // We compute them based on the only `Ty` level info in rustc,
1077                // move `variances_of_opaque` into `rustc_next_trait_solver` for reuse.
1078                return VariancesOf::new_from_iter(
1079                    self,
1080                    (0..self.generics_of(def_id).count()).map(|_| Variance::Invariant),
1081                );
1082            }
1083            SolverDefId::Ctor(Ctor::Struct(def_id)) => def_id.into(),
1084            SolverDefId::AdtId(def_id) => def_id.into(),
1085            SolverDefId::FunctionId(def_id) => def_id.into(),
1086            SolverDefId::ConstId(_)
1087            | SolverDefId::StaticId(_)
1088            | SolverDefId::TraitId(_)
1089            | SolverDefId::TypeAliasId(_)
1090            | SolverDefId::ImplId(_)
1091            | SolverDefId::BuiltinDeriveImplId(_)
1092            | SolverDefId::InternedClosureId(_)
1093            | SolverDefId::InternedCoroutineId(_)
1094            | SolverDefId::InternedCoroutineClosureId(_)
1095            | SolverDefId::AnonConstId(_) => {
1096                return VariancesOf::empty();
1097            }
1098        };
1099        self.db.variances_of(generic_def)
1100    }
1101
1102    fn type_of(self, def_id: Self::DefId) -> EarlyBinder<Self, Self::Ty> {
1103        match def_id {
1104            SolverDefId::TypeAliasId(id) => self.db().ty(id.into()),
1105            SolverDefId::AdtId(id) => self.db().ty(id.into()),
1106            // FIXME(next-solver): This uses the types of `query mir_borrowck` in rustc.
1107            //
1108            // We currently always use the type from HIR typeck which ignores regions. This
1109            // should be fine.
1110            SolverDefId::InternedOpaqueTyId(def_id) => {
1111                self.type_of_opaque_hir_typeck(def_id.into())
1112            }
1113            SolverDefId::FunctionId(id) => self.db.value_ty(id.into()).unwrap(),
1114            SolverDefId::Ctor(id) => {
1115                let id = match id {
1116                    Ctor::Struct(id) => id.into(),
1117                    Ctor::Enum(id) => id.into(),
1118                };
1119                self.db.value_ty(id).expect("`SolverDefId::Ctor` should have a function-like ctor")
1120            }
1121            _ => panic!("Unexpected def_id `{def_id:?}` provided for `type_of`"),
1122        }
1123    }
1124
1125    fn adt_def(self, def_id: Self::AdtId) -> Self::AdtDef {
1126        AdtDef::new(def_id.0, self)
1127    }
1128
1129    fn alias_term_kind_from_def_id(self, def_id: SolverDefId<'db>) -> AliasTermKind<'db> {
1130        match def_id {
1131            SolverDefId::InternedOpaqueTyId(def_id) => {
1132                AliasTermKind::OpaqueTy { def_id: def_id.into() }
1133            }
1134            SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container {
1135                ItemContainerId::ImplId(impl_)
1136                    if ImplSignature::of(self.db, impl_).target_trait.is_none() =>
1137                {
1138                    AliasTermKind::InherentTy { def_id: type_alias.into() }
1139                }
1140                ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => {
1141                    AliasTermKind::ProjectionTy { def_id: type_alias.into() }
1142                }
1143                _ => AliasTermKind::FreeTy { def_id: type_alias.into() },
1144            },
1145            // rustc creates an `AnonConst` for consts, and evaluates them with CTFE (normalizing projections
1146            // via selection, similar to ours `find_matching_impl()`, and not with the trait solver), so mimic it.
1147            SolverDefId::ConstId(def_id) => {
1148                AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) }
1149            }
1150            SolverDefId::StaticId(def_id) => {
1151                AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) }
1152            }
1153            SolverDefId::AnonConstId(def_id) => {
1154                AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) }
1155            }
1156            _ => unimplemented!("Unexpected alias: {:?}", def_id),
1157        }
1158    }
1159
1160    fn trait_ref_and_own_args_for_alias(
1161        self,
1162        def_id: Self::TraitAssocTermId,
1163        args: Self::GenericArgs,
1164    ) -> (rustc_type_ir::TraitRef<Self>, Self::GenericArgsSlice) {
1165        let trait_def_id = self.projection_parent(def_id).0;
1166        let trait_generics = crate::generics::generics(self.db, trait_def_id.into());
1167        let trait_generics_len = trait_generics.len(true);
1168        let trait_args = GenericArgs::new_from_slice(&args.as_slice()[..trait_generics_len]);
1169        let alias_args = &args.as_slice()[trait_generics_len..];
1170        (TraitRef::new_from_args(self, trait_def_id.into(), trait_args), alias_args)
1171    }
1172
1173    fn check_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs) -> bool {
1174        let generics = self.generics_of(def_id);
1175        generics.count() == args.len()
1176            && std::iter::zip(generics.iter(), args).all(|((param, _), arg)| {
1177                matches!(
1178                    (param, arg.kind()),
1179                    (GenericParamId::LifetimeParamId(_), GenericArgKind::Lifetime(_))
1180                        | (GenericParamId::TypeParamId(_), GenericArgKind::Type(_))
1181                        | (GenericParamId::ConstParamId(_), GenericArgKind::Const(_))
1182                )
1183            })
1184    }
1185
1186    fn debug_assert_args_compatible(self, _def_id: Self::DefId, _args: Self::GenericArgs) {}
1187
1188    fn debug_assert_existential_args_compatible(
1189        self,
1190        _def_id: Self::DefId,
1191        _args: Self::GenericArgs,
1192    ) {
1193    }
1194
1195    fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
1196    where
1197        I: Iterator<Item = T>,
1198        T: rustc_type_ir::CollectAndApply<Self::Ty, Self::Tys>,
1199    {
1200        Tys::new_from_iter(self, args)
1201    }
1202
1203    fn projection_parent(self, def_id: Self::TraitAssocTermId) -> Self::TraitId {
1204        let container = match def_id.0 {
1205            TermId::TypeAliasId(def_id) => def_id.loc(self.db).container,
1206            TermId::ConstId(def_id) => def_id.loc(self.db).container,
1207        };
1208        let ItemContainerId::TraitId(trait_) = container else {
1209            panic!("a TraitAssocTermId can only come from a trait")
1210        };
1211        trait_.into()
1212    }
1213
1214    fn impl_or_trait_assoc_term_parent(self, def_id: Self::ImplOrTraitAssocTermId) -> Self::DefId {
1215        let container = match def_id.0 {
1216            TermId::TypeAliasId(def_id) => def_id.loc(self.db).container,
1217            TermId::ConstId(def_id) => def_id.loc(self.db).container,
1218        };
1219        match container {
1220            ItemContainerId::ImplId(impl_) => impl_.into(),
1221            ItemContainerId::TraitId(trait_) => trait_.into(),
1222            ItemContainerId::ExternBlockId(_) | ItemContainerId::ModuleId(_) => {
1223                panic!("only impl or trait can be the parent of ImplOrTraitAssocTermId")
1224            }
1225        }
1226    }
1227
1228    fn inherent_alias_term_parent(self, def_id: Self::InherentAssocTermId) -> Self::ImplId {
1229        let container = match def_id.0 {
1230            TermId::TypeAliasId(def_id) => def_id.loc(self.db).container,
1231            TermId::ConstId(def_id) => def_id.loc(self.db).container,
1232        };
1233        match container {
1234            ItemContainerId::ImplId(impl_) => impl_.into(),
1235            ItemContainerId::ExternBlockId(_)
1236            | ItemContainerId::ModuleId(_)
1237            | ItemContainerId::TraitId(_) => {
1238                panic!("only impl can be the parent of InherentAliasTermId")
1239            }
1240        }
1241    }
1242
1243    fn recursion_limit(self) -> usize {
1244        50
1245    }
1246
1247    fn is_type_const(self, _def_id: Self::DefId) -> bool {
1248        false
1249    }
1250
1251    fn features(self) -> Features {
1252        Features
1253    }
1254
1255    fn fn_sig(
1256        self,
1257        def_id: Self::FunctionId,
1258    ) -> EarlyBinder<Self, rustc_type_ir::Binder<Self, rustc_type_ir::FnSig<Self>>> {
1259        self.db().callable_item_signature(def_id.0)
1260    }
1261
1262    fn coroutine_movability(self, def_id: Self::CoroutineId) -> rustc_ast_ir::Movability {
1263        match def_id.0.loc(self.db).kind {
1264            hir_def::hir::ClosureKind::OldCoroutine(movability) => match movability {
1265                hir_def::hir::Movability::Static => rustc_ast_ir::Movability::Static,
1266                hir_def::hir::Movability::Movable => rustc_ast_ir::Movability::Movable,
1267            },
1268            hir_def::hir::ClosureKind::Coroutine { .. } => rustc_ast_ir::Movability::Static,
1269            kind => panic!("unexpected kind for a coroutine: {kind:?}"),
1270        }
1271    }
1272
1273    fn coroutine_for_closure(self, def_id: Self::CoroutineClosureId) -> Self::CoroutineId {
1274        let InternedClosure { owner, expr: coroutine_closure_expr, kind: coroutine_closure_kind } =
1275            def_id.0.loc(self.db);
1276        let coroutine_closure_kind = match coroutine_closure_kind {
1277            HirClosureKind::CoroutineClosure(it) => it,
1278            _ => {
1279                panic!("invalid kind closure kind {coroutine_closure_kind:?} for coroutine closure")
1280            }
1281        };
1282        let coroutine_expr = ExpressionStore::coroutine_for_closure(coroutine_closure_expr);
1283        let coroutine_kind = hir_def::hir::ClosureKind::Coroutine {
1284            kind: coroutine_closure_kind,
1285            source: hir_def::hir::CoroutineSource::Closure,
1286        };
1287        InternedCoroutineId::new(
1288            self.db,
1289            InternedClosure { owner, expr: coroutine_expr, kind: coroutine_kind },
1290        )
1291        .into()
1292    }
1293
1294    fn generics_require_sized_self(self, def_id: Self::DefId) -> bool {
1295        let sized_trait = self.lang_items().Sized;
1296        let Some(sized_id) = sized_trait else {
1297            return false; /* No Sized trait, can't require it! */
1298        };
1299        let sized_def_id = sized_id.into();
1300
1301        // Search for a predicate like `Self : Sized` amongst the trait bounds.
1302        let predicates = self.predicates_of(def_id);
1303        elaborate(self, predicates.iter_identity().map(Unnormalized::skip_norm_wip)).any(|pred| {
1304            match pred.kind().skip_binder() {
1305                ClauseKind::Trait(ref trait_pred) => {
1306                    trait_pred.def_id() == sized_def_id
1307                        && matches!(
1308                            trait_pred.self_ty().kind(),
1309                            TyKind::Param(ParamTy { index: 0, .. })
1310                        )
1311                }
1312                ClauseKind::RegionOutlives(_)
1313                | ClauseKind::TypeOutlives(_)
1314                | ClauseKind::Projection(_)
1315                | ClauseKind::ConstArgHasType(_, _)
1316                | ClauseKind::WellFormed(_)
1317                | ClauseKind::ConstEvaluatable(_)
1318                | ClauseKind::HostEffect(..)
1319                | ClauseKind::UnstableFeature(_) => false,
1320            }
1321        })
1322    }
1323
1324    #[tracing::instrument(skip(self))]
1325    fn item_bounds(
1326        self,
1327        def_id: Self::DefId,
1328    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1329        explicit_item_bounds(self, def_id).map_bound(|bounds| elaborate(self, bounds))
1330    }
1331
1332    #[tracing::instrument(skip(self))]
1333    fn item_self_bounds(
1334        self,
1335        def_id: Self::DefId,
1336    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1337        explicit_item_self_bounds(self, def_id)
1338            .map_bound(|bounds| elaborate(self, bounds).filter_only_self())
1339    }
1340
1341    fn item_non_self_bounds(
1342        self,
1343        def_id: Self::DefId,
1344    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1345        let all_bounds: FxHashSet<_> = self.item_bounds(def_id).skip_binder().into_iter().collect();
1346        let own_bounds: FxHashSet<_> =
1347            self.item_self_bounds(def_id).skip_binder().into_iter().collect();
1348        if all_bounds.len() == own_bounds.len() {
1349            EarlyBinder::bind(Clauses::empty())
1350        } else {
1351            EarlyBinder::bind(Clauses::new_from_iter(
1352                self,
1353                all_bounds.difference(&own_bounds).cloned(),
1354            ))
1355        }
1356    }
1357
1358    fn predicates_of(
1359        self,
1360        def_id: Self::DefId,
1361    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1362        predicates_of(self.db, def_id).all_predicates()
1363    }
1364
1365    fn own_predicates_of(
1366        self,
1367        def_id: Self::DefId,
1368    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1369        predicates_of(self.db, def_id).own_explicit_predicates()
1370    }
1371
1372    fn explicit_super_predicates_of(
1373        self,
1374        def_id: Self::TraitId,
1375    ) -> EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> {
1376        GenericPredicates::query(self.db, def_id.0.into())
1377            .explicit_non_assoc_types_predicates()
1378            .map_bound(move |predicates| {
1379                predicates.filter(|p| is_clause_at_ty(p, is_ty_self)).map(|p| (p, Span::dummy()))
1380            })
1381    }
1382
1383    fn explicit_implied_predicates_of(
1384        self,
1385        def_id: Self::DefId,
1386    ) -> EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> {
1387        fn is_ty_assoc_of_self(ty: Ty<'_>) -> bool {
1388            // FIXME: Is this correct wrt. combined kind of assoc type bounds, i.e. `where Self::Assoc: Trait<Assoc2: Trait>`
1389            // wrt. `Assoc2`, which we should exclude?
1390            if let TyKind::Alias(alias @ AliasTy { kind: AliasTyKind::Projection { .. }, .. }) =
1391                ty.kind()
1392            {
1393                is_ty_assoc_of_self(alias.self_ty())
1394            } else {
1395                is_ty_self(ty)
1396            }
1397        }
1398
1399        let predicates = predicates_of(self.db, def_id);
1400        let non_assoc_types = predicates
1401            .explicit_non_assoc_types_predicates()
1402            .skip_binder()
1403            .filter(|p| is_clause_at_ty(p, is_ty_self));
1404        let assoc_types = predicates
1405            .explicit_assoc_types_predicates()
1406            .skip_binder()
1407            .filter(|p| is_clause_at_ty(p, is_ty_assoc_of_self));
1408        EarlyBinder::bind(non_assoc_types.chain(assoc_types).map(|it| (it, Span::dummy())))
1409    }
1410
1411    fn impl_super_outlives(
1412        self,
1413        impl_id: Self::ImplId,
1414    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1415        let trait_ref = self.impl_trait_ref(impl_id);
1416        trait_ref.map_bound(|trait_ref| {
1417            let clause: Clause<'_> = trait_ref.upcast(self);
1418            elaborate(self, [clause]).filter(|clause| {
1419                matches!(
1420                    clause.kind().skip_binder(),
1421                    ClauseKind::TypeOutlives(_) | ClauseKind::RegionOutlives(_)
1422                )
1423            })
1424        })
1425    }
1426
1427    #[expect(unreachable_code)]
1428    fn const_conditions(
1429        self,
1430        _def_id: Self::DefId,
1431    ) -> EarlyBinder<
1432        Self,
1433        impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>,
1434    > {
1435        EarlyBinder::bind([unimplemented!()])
1436    }
1437
1438    fn has_target_features(self, _def_id: Self::FunctionId) -> bool {
1439        false
1440    }
1441
1442    fn require_projection_lang_item(
1443        self,
1444        lang_item: SolverProjectionLangItem,
1445    ) -> Self::TraitAssocTyId {
1446        let lang_items = self.lang_items();
1447        let lang_item = match lang_item {
1448            SolverProjectionLangItem::AsyncFnKindUpvars => lang_items.AsyncFnKindUpvars,
1449            SolverProjectionLangItem::AsyncFnOnceOutput => lang_items.AsyncFnOnceOutput,
1450            SolverProjectionLangItem::CallOnceFuture => lang_items.CallOnceFuture,
1451            SolverProjectionLangItem::CallRefFuture => lang_items.CallRefFuture,
1452            SolverProjectionLangItem::CoroutineReturn => lang_items.CoroutineReturn,
1453            SolverProjectionLangItem::CoroutineYield => lang_items.CoroutineYield,
1454            SolverProjectionLangItem::FutureOutput => lang_items.FutureOutput,
1455            SolverProjectionLangItem::Metadata => lang_items.Metadata,
1456            SolverProjectionLangItem::FieldBase => lang_items.FieldBase,
1457            SolverProjectionLangItem::FieldType => lang_items.FieldType,
1458        };
1459        lang_item.expect("Lang item required but not found.").into()
1460    }
1461
1462    fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> TraitIdWrapper {
1463        let lang_items = self.lang_items();
1464        let lang_item = match lang_item {
1465            SolverTraitLangItem::AsyncFn => lang_items.AsyncFn,
1466            SolverTraitLangItem::AsyncFnKindHelper => lang_items.AsyncFnKindHelper,
1467            SolverTraitLangItem::AsyncFnMut => lang_items.AsyncFnMut,
1468            SolverTraitLangItem::AsyncFnOnce => lang_items.AsyncFnOnce,
1469            SolverTraitLangItem::AsyncIterator => lang_items.AsyncIterator,
1470            SolverTraitLangItem::Clone => lang_items.Clone,
1471            SolverTraitLangItem::Copy => lang_items.Copy,
1472            SolverTraitLangItem::Coroutine => lang_items.Coroutine,
1473            SolverTraitLangItem::Destruct => lang_items.Destruct,
1474            SolverTraitLangItem::DiscriminantKind => lang_items.DiscriminantKind,
1475            SolverTraitLangItem::Drop => lang_items.Drop,
1476            SolverTraitLangItem::Fn => lang_items.Fn,
1477            SolverTraitLangItem::FnMut => lang_items.FnMut,
1478            SolverTraitLangItem::FnOnce => lang_items.FnOnce,
1479            SolverTraitLangItem::FnPtrTrait => lang_items.FnPtrTrait,
1480            SolverTraitLangItem::FusedIterator => lang_items.FusedIterator,
1481            SolverTraitLangItem::Future => lang_items.Future,
1482            SolverTraitLangItem::Iterator => lang_items.Iterator,
1483            SolverTraitLangItem::PointeeTrait => lang_items.PointeeTrait,
1484            SolverTraitLangItem::Sized => lang_items.Sized,
1485            SolverTraitLangItem::MetaSized => lang_items.MetaSized,
1486            SolverTraitLangItem::PointeeSized => lang_items.PointeeSized,
1487            SolverTraitLangItem::TransmuteTrait => lang_items.TransmuteTrait,
1488            SolverTraitLangItem::Tuple => lang_items.Tuple,
1489            SolverTraitLangItem::Unpin => lang_items.Unpin,
1490            SolverTraitLangItem::Unsize => lang_items.Unsize,
1491            SolverTraitLangItem::BikeshedGuaranteedNoDrop => lang_items.BikeshedGuaranteedNoDrop,
1492            SolverTraitLangItem::TrivialClone => lang_items.TrivialClone,
1493            SolverTraitLangItem::Field => lang_items.Field,
1494        };
1495        lang_item.expect("Lang item required but not found.").into()
1496    }
1497
1498    fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> AdtIdWrapper {
1499        let lang_items = self.lang_items();
1500        let lang_item = match lang_item {
1501            SolverAdtLangItem::Option => lang_items.Option.map(Into::into),
1502            SolverAdtLangItem::Poll => lang_items.Poll.map(Into::into),
1503            SolverAdtLangItem::DynMetadata => lang_items.DynMetadata.map(Into::into),
1504        };
1505        AdtIdWrapper(lang_item.expect("Lang item required but not found."))
1506    }
1507
1508    fn is_projection_lang_item(
1509        self,
1510        def_id: Self::TraitAssocTyId,
1511        lang_item: SolverProjectionLangItem,
1512    ) -> bool {
1513        self.as_projection_lang_item(def_id)
1514            .map_or(false, |l| std::mem::discriminant(&l) == std::mem::discriminant(&lang_item))
1515    }
1516
1517    fn is_trait_lang_item(self, def_id: Self::TraitId, lang_item: SolverTraitLangItem) -> bool {
1518        is_lang_item!(
1519            SolverTraitLangItem, self, def_id.0, lang_item;
1520
1521            Sized,
1522            MetaSized,
1523            PointeeSized,
1524            Unsize,
1525            Copy,
1526            Clone,
1527            DiscriminantKind,
1528            PointeeTrait,
1529            FnPtrTrait,
1530            Drop,
1531            Destruct,
1532            TransmuteTrait,
1533            Fn,
1534            FnMut,
1535            FnOnce,
1536            Future,
1537            Coroutine,
1538            Unpin,
1539            Tuple,
1540            Iterator,
1541            AsyncFn,
1542            AsyncFnMut,
1543            AsyncFnOnce,
1544            TrivialClone,
1545            AsyncFnKindHelper,
1546            AsyncIterator,
1547            BikeshedGuaranteedNoDrop,
1548            FusedIterator,
1549            Field,
1550        )
1551    }
1552
1553    fn is_adt_lang_item(self, def_id: Self::AdtId, lang_item: SolverAdtLangItem) -> bool {
1554        // FIXME: derive PartialEq on SolverTraitLangItem
1555        self.as_adt_lang_item(def_id)
1556            .map_or(false, |l| std::mem::discriminant(&l) == std::mem::discriminant(&lang_item))
1557    }
1558
1559    fn as_projection_lang_item(
1560        self,
1561        def_id: Self::TraitAssocTyId,
1562    ) -> Option<SolverProjectionLangItem> {
1563        as_lang_item!(
1564            SolverProjectionLangItem, self, def_id.0, TypeAliasId;
1565
1566            Metadata,
1567            CoroutineReturn,
1568            CoroutineYield,
1569            FutureOutput,
1570            CallRefFuture,
1571            CallOnceFuture,
1572            AsyncFnOnceOutput,
1573            AsyncFnKindUpvars,
1574            FieldBase,
1575            FieldType,
1576        )
1577    }
1578
1579    fn as_trait_lang_item(self, def_id: Self::TraitId) -> Option<SolverTraitLangItem> {
1580        as_lang_item!(
1581            SolverTraitLangItem, self, def_id.0, TraitId;
1582
1583            Sized,
1584            MetaSized,
1585            PointeeSized,
1586            Unsize,
1587            Copy,
1588            Clone,
1589            DiscriminantKind,
1590            PointeeTrait,
1591            FnPtrTrait,
1592            Drop,
1593            Destruct,
1594            TransmuteTrait,
1595            Fn,
1596            FnMut,
1597            FnOnce,
1598            Future,
1599            Coroutine,
1600            Unpin,
1601            Tuple,
1602            Iterator,
1603            AsyncFn,
1604            AsyncFnMut,
1605            AsyncFnOnce,
1606            TrivialClone,
1607            AsyncFnKindHelper,
1608            AsyncIterator,
1609            BikeshedGuaranteedNoDrop,
1610            FusedIterator,
1611            Field,
1612        )
1613    }
1614
1615    fn as_adt_lang_item(self, def_id: Self::AdtId) -> Option<SolverAdtLangItem> {
1616        as_lang_item!(
1617            SolverAdtLangItem, self, def_id.0, AdtId;
1618
1619            Option,
1620            Poll,
1621            DynMetadata,
1622        )
1623    }
1624
1625    fn associated_type_def_ids(
1626        self,
1627        def_id: Self::TraitId,
1628    ) -> impl IntoIterator<Item = Self::DefId> {
1629        def_id.0.trait_items(self.db()).associated_types().map(|id| id.into())
1630    }
1631
1632    fn for_each_relevant_impl<R: VisitorResult>(
1633        self,
1634        trait_def_id: Self::TraitId,
1635        self_ty: Self::Ty,
1636        mut f: impl FnMut(Self::ImplId) -> R,
1637    ) -> R {
1638        let krate = self.krate.expect("trait solving requires setting `DbInterner::krate`");
1639        let trait_block = trait_def_id.0.loc(self.db).container.block(self.db);
1640        let mut consider_impls_for_simplified_type = |simp: SimplifiedType<'_>| {
1641            let type_block = simp.def().and_then(|def_id| {
1642                let module = match def_id {
1643                    SolverDefId::AdtId(AdtId::StructId(id)) => id.module(self.db),
1644                    SolverDefId::AdtId(AdtId::EnumId(id)) => id.module(self.db),
1645                    SolverDefId::AdtId(AdtId::UnionId(id)) => id.module(self.db),
1646                    SolverDefId::TraitId(id) => id.module(self.db),
1647                    SolverDefId::TypeAliasId(id) => id.module(self.db),
1648                    SolverDefId::ConstId(_)
1649                    | SolverDefId::FunctionId(_)
1650                    | SolverDefId::ImplId(_)
1651                    | SolverDefId::BuiltinDeriveImplId(_)
1652                    | SolverDefId::StaticId(_)
1653                    | SolverDefId::InternedClosureId(_)
1654                    | SolverDefId::InternedCoroutineId(_)
1655                    | SolverDefId::InternedCoroutineClosureId(_)
1656                    | SolverDefId::InternedOpaqueTyId(_)
1657                    | SolverDefId::EnumVariantId(_)
1658                    | SolverDefId::AnonConstId(_)
1659                    | SolverDefId::Ctor(_) => return None,
1660                };
1661                module.block(self.db)
1662            });
1663            TraitImpls::for_each_crate_and_block_trait_and_type(
1664                self.db,
1665                krate,
1666                type_block,
1667                trait_block,
1668                &mut |impls| {
1669                    let (regular_impls, builtin_derive_impls) =
1670                        impls.for_trait_and_self_ty(trait_def_id.0, &simp);
1671                    for &impl_ in regular_impls {
1672                        try_visit!(f(impl_.into()));
1673                    }
1674                    for &impl_ in builtin_derive_impls {
1675                        try_visit!(f(impl_.into()));
1676                    }
1677                    R::output()
1678                },
1679            )
1680        };
1681
1682        match self_ty.kind() {
1683            TyKind::Bool
1684            | TyKind::Char
1685            | TyKind::Int(_)
1686            | TyKind::Uint(_)
1687            | TyKind::Float(_)
1688            | TyKind::Adt(_, _)
1689            | TyKind::Foreign(_)
1690            | TyKind::Str
1691            | TyKind::Array(_, _)
1692            | TyKind::Pat(_, _)
1693            | TyKind::Slice(_)
1694            | TyKind::RawPtr(_, _)
1695            | TyKind::Ref(_, _, _)
1696            | TyKind::FnDef(_, _)
1697            | TyKind::FnPtr(..)
1698            | TyKind::Dynamic(_, _)
1699            | TyKind::Closure(..)
1700            | TyKind::CoroutineClosure(..)
1701            | TyKind::Coroutine(_, _)
1702            | TyKind::Never
1703            | TyKind::Tuple(_)
1704            | TyKind::UnsafeBinder(_) => {
1705                let simp =
1706                    fast_reject::simplify_type(self, self_ty, fast_reject::TreatParams::AsRigid)
1707                        .unwrap();
1708                try_visit!(consider_impls_for_simplified_type(simp));
1709            }
1710
1711            // HACK: For integer and float variables we have to manually look at all impls
1712            // which have some integer or float as a self type.
1713            TyKind::Infer(InferTy::IntVar(_)) => {
1714                use IntTy::*;
1715                use UintTy::*;
1716                // This causes a compiler error if any new integer kinds are added.
1717                let (I8 | I16 | I32 | I64 | I128 | Isize): IntTy;
1718                let (U8 | U16 | U32 | U64 | U128 | Usize): UintTy;
1719                let possible_integers = [
1720                    // signed integers
1721                    SimplifiedType::Int(I8),
1722                    SimplifiedType::Int(I16),
1723                    SimplifiedType::Int(I32),
1724                    SimplifiedType::Int(I64),
1725                    SimplifiedType::Int(I128),
1726                    SimplifiedType::Int(Isize),
1727                    // unsigned integers
1728                    SimplifiedType::Uint(U8),
1729                    SimplifiedType::Uint(U16),
1730                    SimplifiedType::Uint(U32),
1731                    SimplifiedType::Uint(U64),
1732                    SimplifiedType::Uint(U128),
1733                    SimplifiedType::Uint(Usize),
1734                ];
1735                for simp in possible_integers {
1736                    try_visit!(consider_impls_for_simplified_type(simp));
1737                }
1738            }
1739
1740            TyKind::Infer(InferTy::FloatVar(_)) => {
1741                // This causes a compiler error if any new float kinds are added.
1742                let (FloatTy::F16 | FloatTy::F32 | FloatTy::F64 | FloatTy::F128);
1743                let possible_floats = [
1744                    SimplifiedType::Float(FloatTy::F16),
1745                    SimplifiedType::Float(FloatTy::F32),
1746                    SimplifiedType::Float(FloatTy::F64),
1747                    SimplifiedType::Float(FloatTy::F128),
1748                ];
1749
1750                for simp in possible_floats {
1751                    try_visit!(consider_impls_for_simplified_type(simp));
1752                }
1753            }
1754
1755            // The only traits applying to aliases and placeholders are blanket impls.
1756            //
1757            // Impls which apply to an alias after normalization are handled by
1758            // `assemble_candidates_after_normalizing_self_ty`.
1759            TyKind::Alias(..) | TyKind::Placeholder(..) | TyKind::Error(_) => (),
1760
1761            // FIXME: These should ideally not exist as a self type. It would be nice for
1762            // the builtin auto trait impls of coroutines to instead directly recurse
1763            // into the witness.
1764            TyKind::CoroutineWitness(..) => (),
1765
1766            // These variants should not exist as a self type.
1767            TyKind::Infer(
1768                InferTy::TyVar(_)
1769                | InferTy::FreshTy(_)
1770                | InferTy::FreshIntTy(_)
1771                | InferTy::FreshFloatTy(_),
1772            )
1773            | TyKind::Param(_)
1774            | TyKind::Bound(_, _) => panic!("unexpected self type: {self_ty:?}"),
1775        }
1776
1777        self.for_each_blanket_impl(trait_def_id, f)
1778    }
1779
1780    fn for_each_blanket_impl<R: VisitorResult>(
1781        self,
1782        trait_def_id: Self::TraitId,
1783        mut f: impl FnMut(Self::ImplId) -> R,
1784    ) -> R {
1785        let Some(krate) = self.krate else {
1786            return R::output();
1787        };
1788        let block = trait_def_id.0.loc(self.db).container.block(self.db);
1789
1790        TraitImpls::for_each_crate_and_block(self.db, krate, block, &mut |impls| {
1791            for &impl_ in impls.blanket_impls(trait_def_id.0) {
1792                try_visit!(f(impl_.into()));
1793            }
1794            R::output()
1795        })
1796    }
1797
1798    fn has_item_definition(self, _def_id: Self::ImplOrTraitAssocTermId) -> bool {
1799        // FIXME(next-solver): should check if the associated item has a value.
1800        true
1801    }
1802
1803    fn impl_is_default(self, impl_def_id: Self::ImplId) -> bool {
1804        match impl_def_id {
1805            AnyImplId::ImplId(impl_id) => ImplSignature::of(self.db, impl_id).is_default(),
1806            AnyImplId::BuiltinDeriveImplId(_) => false,
1807        }
1808    }
1809
1810    #[tracing::instrument(skip(self), ret)]
1811    fn impl_trait_ref(
1812        self,
1813        impl_id: Self::ImplId,
1814    ) -> EarlyBinder<Self, rustc_type_ir::TraitRef<Self>> {
1815        match impl_id {
1816            AnyImplId::ImplId(impl_id) => {
1817                let db = self.db();
1818                db.impl_trait(impl_id)
1819                    // ImplIds for impls where the trait ref can't be resolved should never reach trait solving
1820                    .expect("invalid impl passed to trait solver")
1821            }
1822            AnyImplId::BuiltinDeriveImplId(impl_id) => {
1823                crate::builtin_derive::impl_trait(self, impl_id)
1824            }
1825        }
1826    }
1827
1828    fn impl_polarity(self, impl_id: Self::ImplId) -> rustc_type_ir::ImplPolarity {
1829        let AnyImplId::ImplId(impl_id) = impl_id else {
1830            return ImplPolarity::Positive;
1831        };
1832        let impl_data = ImplSignature::of(self.db(), impl_id);
1833        if impl_data.flags.contains(ImplFlags::NEGATIVE) {
1834            ImplPolarity::Negative
1835        } else {
1836            ImplPolarity::Positive
1837        }
1838    }
1839
1840    fn trait_is_auto(self, trait_: Self::TraitId) -> bool {
1841        let trait_data = TraitSignature::of(self.db(), trait_.0);
1842        trait_data.flags.contains(TraitFlags::AUTO)
1843    }
1844
1845    fn trait_is_alias(self, trait_: Self::TraitId) -> bool {
1846        let trait_data = TraitSignature::of(self.db(), trait_.0);
1847        trait_data.flags.contains(TraitFlags::ALIAS)
1848    }
1849
1850    fn trait_is_dyn_compatible(self, trait_: Self::TraitId) -> bool {
1851        crate::dyn_compatibility::dyn_compatibility(self.db(), trait_.0).is_none()
1852    }
1853
1854    fn trait_is_fundamental(self, trait_: Self::TraitId) -> bool {
1855        let trait_data = TraitSignature::of(self.db(), trait_.0);
1856        trait_data.flags.contains(TraitFlags::FUNDAMENTAL)
1857    }
1858
1859    fn is_impl_trait_in_trait(self, _def_id: Self::DefId) -> bool {
1860        // FIXME(next-solver)
1861        false
1862    }
1863
1864    fn delay_bug(self, _msg: impl ToString) -> Self::ErrorGuaranteed {
1865        ErrorGuaranteed
1866    }
1867
1868    fn is_general_coroutine(self, def_id: Self::CoroutineId) -> bool {
1869        matches!(def_id.0.loc(self.db).kind, HirClosureKind::OldCoroutine(_))
1870    }
1871
1872    fn coroutine_is_async(self, def_id: Self::CoroutineId) -> bool {
1873        matches!(
1874            def_id.0.loc(self.db).kind,
1875            HirClosureKind::Coroutine { kind: HirCoroutineKind::Async, .. }
1876        )
1877    }
1878
1879    fn coroutine_is_gen(self, def_id: Self::CoroutineId) -> bool {
1880        matches!(
1881            def_id.0.loc(self.db).kind,
1882            HirClosureKind::Coroutine { kind: HirCoroutineKind::Gen, .. }
1883        )
1884    }
1885
1886    fn coroutine_is_async_gen(self, def_id: Self::CoroutineId) -> bool {
1887        matches!(
1888            def_id.0.loc(self.db).kind,
1889            HirClosureKind::Coroutine { kind: HirCoroutineKind::AsyncGen, .. }
1890        )
1891    }
1892
1893    fn unsizing_params_for_adt(self, id: Self::AdtId) -> Self::UnsizingParams {
1894        let def = AdtDef::new(id.0, self);
1895        let num_params = self.generics_of(id.into()).count();
1896
1897        let maybe_unsizing_param_idx = |arg: GenericArg<'db>| match arg.kind() {
1898            GenericArgKind::Type(ty) => match ty.kind() {
1899                rustc_type_ir::TyKind::Param(p) => Some(p.index),
1900                _ => None,
1901            },
1902            GenericArgKind::Lifetime(_) => None,
1903            GenericArgKind::Const(ct) => match ct.kind() {
1904                rustc_type_ir::ConstKind::Param(p) => Some(p.index),
1905                _ => None,
1906            },
1907        };
1908
1909        // The last field of the structure has to exist and contain type/const parameters.
1910        let variant = match def.def_id() {
1911            AdtId::StructId(id) => VariantId::from(id),
1912            AdtId::UnionId(id) => id.into(),
1913            AdtId::EnumId(_) => panic!("expected a struct or a union"),
1914        };
1915        let fields = variant.fields(self.db());
1916        let mut prefix_fields = fields.fields().iter();
1917        let Some(tail_field) = prefix_fields.next_back() else {
1918            return UnsizingParams(DenseBitSet::new_empty(num_params));
1919        };
1920
1921        let field_types = self.db().field_types(variant);
1922        let mut unsizing_params = DenseBitSet::new_empty(num_params);
1923        let ty = field_types[tail_field.0].ty();
1924        for arg in ty.instantiate_identity().skip_norm_wip().walk() {
1925            if let Some(i) = maybe_unsizing_param_idx(arg) {
1926                unsizing_params.insert(i);
1927            }
1928        }
1929
1930        // Ensure none of the other fields mention the parameters used
1931        // in unsizing.
1932        for field in prefix_fields {
1933            for arg in field_types[field.0].ty().instantiate_identity().skip_norm_wip().walk() {
1934                if let Some(i) = maybe_unsizing_param_idx(arg) {
1935                    unsizing_params.remove(i);
1936                }
1937            }
1938        }
1939
1940        UnsizingParams(unsizing_params)
1941    }
1942
1943    fn anonymize_bound_vars<T: rustc_type_ir::TypeFoldable<Self>>(
1944        self,
1945        value: rustc_type_ir::Binder<Self, T>,
1946    ) -> rustc_type_ir::Binder<Self, T> {
1947        struct Anonymize<'a, 'db> {
1948            interner: DbInterner<'db>,
1949            map: &'a mut FxIndexMap<BoundVar, BoundVariableKind<'db>>,
1950        }
1951        impl<'db> BoundVarReplacerDelegate<'db> for Anonymize<'_, 'db> {
1952            fn replace_region(&mut self, br: BoundRegion<'db>) -> Region<'db> {
1953                let entry = self.map.entry(br.var);
1954                let index = entry.index();
1955                let var = BoundVar::from_usize(index);
1956                let kind = (*entry
1957                    .or_insert_with(|| BoundVariableKind::Region(BoundRegionKind::Anon)))
1958                .expect_region();
1959                let br = BoundRegion { var, kind };
1960                Region::new_bound(self.interner, DebruijnIndex::ZERO, br)
1961            }
1962            fn replace_ty(&mut self, bt: BoundTy<'db>) -> Ty<'db> {
1963                let entry = self.map.entry(bt.var);
1964                let index = entry.index();
1965                let var = BoundVar::from_usize(index);
1966                let kind = (*entry.or_insert_with(|| BoundVariableKind::Ty(BoundTyKind::Anon)))
1967                    .expect_ty();
1968                Ty::new_bound(self.interner, DebruijnIndex::ZERO, BoundTy { var, kind })
1969            }
1970            fn replace_const(&mut self, bv: BoundConst<'db>) -> Const<'db> {
1971                let entry = self.map.entry(bv.var);
1972                let index = entry.index();
1973                let var = BoundVar::from_usize(index);
1974                let () = (*entry.or_insert_with(|| BoundVariableKind::Const)).expect_const();
1975                Const::new_bound(self.interner, DebruijnIndex::ZERO, BoundConst::new(var))
1976            }
1977        }
1978
1979        let mut map = Default::default();
1980        let delegate = Anonymize { interner: self, map: &mut map };
1981        let inner = self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate);
1982        let bound_vars = BoundVarKinds::new_from_iter(self, map.into_values());
1983        Binder::bind_with_vars(inner, bound_vars)
1984    }
1985
1986    fn opaque_types_defined_by(self, def_id: Self::LocalDefId) -> Self::LocalDefIds {
1987        let Ok(def_id) = InferBodyId::try_from(def_id) else {
1988            return SolverDefIds::default();
1989        };
1990        let mut result = Vec::new();
1991        crate::opaques::opaque_types_defined_by(self.db, def_id, &mut result);
1992        SolverDefIds::new_from_slice(&result)
1993    }
1994
1995    fn opaque_types_and_coroutines_defined_by(self, def_id: Self::LocalDefId) -> Self::LocalDefIds {
1996        let db = self.db;
1997
1998        let Ok(def_id) = InferBodyId::try_from(def_id) else {
1999            return SolverDefIds::default();
2000        };
2001        let mut result = Vec::new();
2002
2003        crate::opaques::opaque_types_defined_by(db, def_id, &mut result);
2004
2005        // Collect coroutines.
2006        let (store, root_expr) = def_id.store_and_root_expr(db);
2007        // We can't just visit all exprs, since this may end up in unrelated anon consts.
2008        CoroutinesVisitor { db: self.db, owner: def_id, store, coroutines: &mut result }
2009            .on_expr(root_expr);
2010
2011        return SolverDefIds::new_from_slice(&result);
2012
2013        struct CoroutinesVisitor<'a, 'db> {
2014            db: &'db dyn HirDatabase,
2015            owner: InferBodyId<'db>,
2016            store: &'db ExpressionStore,
2017            coroutines: &'a mut Vec<SolverDefId<'db>>,
2018        }
2019
2020        impl<'db> StoreVisitor for CoroutinesVisitor<'_, 'db> {
2021            fn on_expr(&mut self, expr: ExprId) {
2022                if let hir_def::hir::Expr::Closure {
2023                    closure_kind:
2024                        kind @ (hir_def::hir::ClosureKind::Coroutine { .. }
2025                        | hir_def::hir::ClosureKind::OldCoroutine(_)),
2026                    ..
2027                } = self.store[expr]
2028                {
2029                    let coroutine = InternedCoroutineId::new(
2030                        self.db,
2031                        InternedClosure { owner: self.owner, expr, kind },
2032                    );
2033                    self.coroutines.push(coroutine.into());
2034                }
2035
2036                self.store.visit_expr_children(expr, self);
2037            }
2038            fn on_pat(&mut self, pat: PatId) {
2039                self.store.visit_pat_children(pat, self);
2040            }
2041            // Do not visit anon consts, they're separate bodies.
2042            fn on_anon_const_expr(&mut self, _expr: ExprId) {}
2043        }
2044    }
2045
2046    fn alias_has_const_conditions(self, _def_id: Self::DefId) -> bool {
2047        // FIXME(next-solver)
2048        false
2049    }
2050
2051    fn explicit_implied_const_bounds(
2052        self,
2053        _def_id: Self::DefId,
2054    ) -> EarlyBinder<
2055        Self,
2056        impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>,
2057    > {
2058        // FIXME(next-solver)
2059        EarlyBinder::bind([])
2060    }
2061
2062    fn fn_is_const(self, id: Self::FunctionId) -> bool {
2063        let id = match id.0 {
2064            CallableDefId::FunctionId(id) => id,
2065            _ => return false,
2066        };
2067        FunctionSignature::of(self.db(), id).flags.contains(FnFlags::CONST)
2068    }
2069
2070    fn impl_is_const(self, _def_id: Self::ImplId) -> bool {
2071        false
2072    }
2073
2074    fn opt_alias_variances(
2075        self,
2076        _kind: impl Into<AliasTermKind<'db>>,
2077    ) -> Option<Self::VariancesOf> {
2078        None
2079    }
2080
2081    fn type_of_opaque_hir_typeck(
2082        self,
2083        opaque: Self::LocalOpaqueTyId,
2084    ) -> EarlyBinder<Self, Self::Ty> {
2085        let impl_trait_id = opaque.0.loc(self.db);
2086        // The entry is missing when this call cycles back into the still-running inference
2087        // of the defining body, as the cycle fallback is an empty result.
2088        let hidden_type = match impl_trait_id {
2089            crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => {
2090                crate::opaques::rpit_hidden_types(self.db, func).get(idx)
2091            }
2092            crate::ImplTraitId::TypeAliasImplTrait(type_alias, idx) => {
2093                crate::opaques::tait_hidden_types(self.db, type_alias).get(idx)
2094            }
2095        };
2096        match hidden_type {
2097            Some(hidden_type) => hidden_type.get(),
2098            None => EarlyBinder::bind(Ty::new_error(self, ErrorGuaranteed)),
2099        }
2100    }
2101
2102    fn coroutine_hidden_types(
2103        self,
2104        _def_id: Self::CoroutineId,
2105    ) -> EarlyBinder<Self, Binder<'db, CoroutineWitnessTypes<Self>>> {
2106        // FIXME: Actually implement this.
2107        EarlyBinder::bind(Binder::dummy(CoroutineWitnessTypes {
2108            types: Tys::default(),
2109            assumptions: RegionAssumptions::default(),
2110        }))
2111    }
2112
2113    fn is_default_trait(self, def_id: Self::TraitId) -> bool {
2114        self.as_trait_lang_item(def_id).map_or(false, |l| matches!(l, SolverTraitLangItem::Sized))
2115    }
2116
2117    fn trait_is_coinductive(self, trait_: Self::TraitId) -> bool {
2118        TraitSignature::of(self.db(), trait_.0).flags.contains(TraitFlags::COINDUCTIVE)
2119    }
2120
2121    fn trait_is_unsafe(self, trait_: Self::TraitId) -> bool {
2122        TraitSignature::of(self.db(), trait_.0).flags.contains(TraitFlags::UNSAFE)
2123    }
2124
2125    fn impl_self_is_guaranteed_unsized(self, _def_id: Self::ImplId) -> bool {
2126        false
2127    }
2128
2129    fn impl_specializes(
2130        self,
2131        specializing_impl_def_id: Self::ImplId,
2132        parent_impl_def_id: Self::ImplId,
2133    ) -> bool {
2134        let (AnyImplId::ImplId(specializing_impl_def_id), AnyImplId::ImplId(parent_impl_def_id)) =
2135            (specializing_impl_def_id, parent_impl_def_id)
2136        else {
2137            // No builtin derive allow specialization currently.
2138            return false;
2139        };
2140        crate::specialization::specializes(self.db, specializing_impl_def_id, parent_impl_def_id)
2141    }
2142
2143    fn next_trait_solver_globally(self) -> bool {
2144        true
2145    }
2146
2147    type Probe = rustc_type_ir::solve::inspect::Probe<DbInterner<'db>>;
2148    fn mk_probe(self, probe: rustc_type_ir::solve::inspect::Probe<Self>) -> Self::Probe {
2149        probe
2150    }
2151    fn evaluate_root_goal_for_proof_tree_raw(
2152        self,
2153        canonical_goal: rustc_type_ir::solve::CanonicalInput<Self>,
2154    ) -> (rustc_type_ir::solve::QueryResult<Self>, Self::Probe) {
2155        rustc_next_trait_solver::solve::evaluate_root_goal_for_proof_tree_raw_provider::<
2156            SolverContext<'db>,
2157            Self,
2158        >(self, canonical_goal)
2159    }
2160
2161    fn is_sizedness_trait(self, def_id: Self::TraitId) -> bool {
2162        matches!(
2163            self.as_trait_lang_item(def_id),
2164            Some(SolverTraitLangItem::Sized | SolverTraitLangItem::MetaSized)
2165        )
2166    }
2167
2168    fn const_of_item(self, def_id: Self::DefId) -> rustc_type_ir::EarlyBinder<Self, Self::Const> {
2169        let id = match def_id {
2170            SolverDefId::StaticId(id) => id.into(),
2171            SolverDefId::ConstId(id) => id.into(),
2172            _ => unreachable!(),
2173        };
2174        EarlyBinder::bind(Const::new_unevaluated(
2175            self,
2176            UnevaluatedConst { def: GeneralConstIdWrapper(id), args: GenericArgs::empty() },
2177        ))
2178    }
2179
2180    fn anon_const_kind(self, _def_id: Self::DefId) -> rustc_type_ir::AnonConstKind {
2181        // FIXME
2182        rustc_type_ir::AnonConstKind::GCE
2183    }
2184
2185    fn alias_ty_kind_from_def_id(self, def_id: Self::DefId) -> AliasTyKind<'db> {
2186        match def_id {
2187            SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container {
2188                ItemContainerId::ExternBlockId(_) | ItemContainerId::ModuleId(_) => {
2189                    AliasTyKind::Free { def_id: type_alias.into() }
2190                }
2191                ItemContainerId::ImplId(_) => AliasTyKind::Inherent { def_id: type_alias.into() },
2192                ItemContainerId::TraitId(_) => {
2193                    AliasTyKind::Projection { def_id: type_alias.into() }
2194                }
2195            },
2196            SolverDefId::InternedOpaqueTyId(def_id) => {
2197                AliasTyKind::Opaque { def_id: def_id.into() }
2198            }
2199            _ => unreachable!(),
2200        }
2201    }
2202
2203    fn closure_is_const(self, _def_id: Self::ClosureId) -> bool {
2204        // FIXME
2205        false
2206    }
2207
2208    fn item_name(self, _item_index: Self::DefId) -> Self::Symbol {
2209        Symbol
2210    }
2211}
2212
2213fn is_ty_self(ty: Ty<'_>) -> bool {
2214    match ty.kind() {
2215        TyKind::Param(param) => param.index == 0,
2216        _ => false,
2217    }
2218}
2219fn is_clause_at_ty(p: &Clause<'_>, filter: impl FnOnce(Ty<'_>) -> bool) -> bool {
2220    match p.kind().skip_binder() {
2221        // rustc has the following assertion:
2222        // https://github.com/rust-lang/rust/blob/52618eb338609df44978b0ca4451ab7941fd1c7a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs#L525-L608
2223        ClauseKind::Trait(it) => filter(it.self_ty()),
2224        ClauseKind::TypeOutlives(it) => filter(it.0),
2225        ClauseKind::Projection(it) => filter(it.self_ty()),
2226        ClauseKind::HostEffect(it) => filter(it.self_ty()),
2227        _ => false,
2228    }
2229}
2230
2231impl<'db> DbInterner<'db> {
2232    pub fn shift_bound_var_indices<T>(self, bound_vars: usize, value: T) -> T
2233    where
2234        T: rustc_type_ir::TypeFoldable<Self>,
2235    {
2236        let shift_bv = |bv: BoundVar| BoundVar::from_usize(bv.as_usize() + bound_vars);
2237        self.replace_escaping_bound_vars_uncached(
2238            value,
2239            FnMutDelegate {
2240                regions: &mut |r: BoundRegion<'db>| {
2241                    Region::new_bound(
2242                        self,
2243                        DebruijnIndex::ZERO,
2244                        BoundRegion { var: shift_bv(r.var), kind: r.kind },
2245                    )
2246                },
2247                types: &mut |t: BoundTy<'db>| {
2248                    Ty::new_bound(
2249                        self,
2250                        DebruijnIndex::ZERO,
2251                        BoundTy { var: shift_bv(t.var), kind: t.kind },
2252                    )
2253                },
2254                consts: &mut |c| {
2255                    Const::new_bound(self, DebruijnIndex::ZERO, BoundConst::new(shift_bv(c.var)))
2256                },
2257            },
2258        )
2259    }
2260
2261    pub fn replace_escaping_bound_vars_uncached<T: rustc_type_ir::TypeFoldable<DbInterner<'db>>>(
2262        self,
2263        value: T,
2264        delegate: impl BoundVarReplacerDelegate<'db>,
2265    ) -> T {
2266        if !value.has_escaping_bound_vars() {
2267            value
2268        } else {
2269            let mut replacer = BoundVarReplacer::new(self, delegate);
2270            value.fold_with(&mut replacer)
2271        }
2272    }
2273
2274    pub fn replace_bound_vars_uncached<T: rustc_type_ir::TypeFoldable<DbInterner<'db>>>(
2275        self,
2276        value: Binder<'db, T>,
2277        delegate: impl BoundVarReplacerDelegate<'db>,
2278    ) -> T {
2279        self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate)
2280    }
2281
2282    // FIXME: add splat support when the experiment is complete
2283    pub fn mk_fn_sig<I>(
2284        self,
2285        inputs: I,
2286        output: Ty<'db>,
2287        c_variadic: bool,
2288        safety: Safety,
2289        abi: ExternAbi,
2290    ) -> FnSig<'db>
2291    where
2292        I: IntoIterator<Item = Ty<'db>>,
2293    {
2294        FnSig {
2295            inputs_and_output: Tys::new_from_iter(
2296                self,
2297                inputs.into_iter().chain(std::iter::once(output)),
2298            ),
2299            fn_sig_kind: FnSigKind::new(abi, safety, c_variadic),
2300        }
2301    }
2302
2303    /// `mk_fn_sig`, but with a safe Rust ABI, and no C-variadic argument.
2304    pub fn mk_fn_sig_safe_rust_abi<I>(self, inputs: I, output: Ty<'db>) -> FnSig<'db>
2305    where
2306        I: IntoIterator<Item = Ty<'db>>,
2307    {
2308        self.mk_fn_sig(inputs, output, false, Safety::Safe, ExternAbi::Rust)
2309    }
2310}
2311
2312fn predicates_of<'db>(
2313    db: &'db dyn HirDatabase,
2314    def_id: SolverDefId<'db>,
2315) -> &'db GenericPredicates {
2316    match def_id {
2317        SolverDefId::BuiltinDeriveImplId(impl_) => crate::builtin_derive::predicates(db, impl_),
2318        SolverDefId::AnonConstId(anon_const) => {
2319            let loc = anon_const.loc(db);
2320            if loc.allow_using_generic_params {
2321                GenericPredicates::query(db, loc.owner.generic_def(db))
2322            } else {
2323                GenericPredicates::empty()
2324            }
2325        }
2326        _ => GenericPredicates::query(db, def_id.try_into().unwrap()),
2327    }
2328}
2329
2330macro_rules! TrivialTypeTraversalImpls {
2331    ($($ty:ty,)+) => {
2332        $(
2333            impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for $ty {
2334                fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
2335                    self,
2336                    _: &mut F,
2337                ) -> ::std::result::Result<Self, F::Error> {
2338                    Ok(self)
2339                }
2340
2341                #[inline]
2342                fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(
2343                    self,
2344                    _: &mut F,
2345                ) -> Self {
2346                    self
2347                }
2348            }
2349
2350            impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for $ty {
2351                #[inline]
2352                fn visit_with<F: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
2353                    &self,
2354                    _: &mut F)
2355                    -> F::Result
2356                {
2357                    <F::Result as rustc_ast_ir::visit::VisitorResult>::output()
2358                }
2359            }
2360
2361            impl<V> rustc_type_ir::GenericTypeVisitable<V> for $ty {
2362                #[inline]
2363                fn generic_visit_with(&self, _visitor: &mut V) {}
2364            }
2365        )+
2366    };
2367}
2368
2369TrivialTypeTraversalImpls! {
2370    SolverDefId<'_>,
2371    TraitIdWrapper,
2372    TypeAliasIdWrapper,
2373    CallableIdWrapper,
2374    ClosureIdWrapper<'_>,
2375    CoroutineIdWrapper<'_>,
2376    CoroutineClosureIdWrapper<'_>,
2377    AdtIdWrapper,
2378    TraitAssocTyId,
2379    TraitAssocConstId,
2380    TraitAssocTermId,
2381    ImplOrTraitAssocTyId,
2382    ImplOrTraitAssocConstId,
2383    ImplOrTraitAssocTermId,
2384    FreeTyAliasId,
2385    FreeConstAliasId,
2386    FreeTermAliasId,
2387    InherentAssocTyId,
2388    InherentAssocConstId,
2389    InherentAssocTermId,
2390    OpaqueTyIdWrapper<'_>,
2391    AnyImplId,
2392    GeneralConstIdWrapper<'_>,
2393    Safety,
2394    Span,
2395    ParamConst,
2396    ParamTy,
2397    EarlyParamRegion,
2398    AdtDef,
2399    ScalarInt,
2400}
2401
2402mod tls_db {
2403    use std::{cell::Cell, ptr::NonNull};
2404
2405    use crate::db::HirDatabase;
2406
2407    struct Attached {
2408        database: Cell<Option<NonNull<dyn HirDatabase>>>,
2409    }
2410
2411    impl Attached {
2412        #[inline]
2413        fn attach<R>(&self, db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2414            struct DbGuard<'s> {
2415                state: Option<&'s Attached>,
2416            }
2417
2418            impl<'s> DbGuard<'s> {
2419                #[inline]
2420                fn new(attached: &'s Attached, db: &dyn HirDatabase) -> Self {
2421                    match attached.database.get() {
2422                        Some(current_db) => {
2423                            let new_db = NonNull::from(db);
2424                            if !std::ptr::addr_eq(current_db.as_ptr(), new_db.as_ptr()) {
2425                                panic!(
2426                                    "Cannot change attached database. This is likely a bug.\n\
2427                                    If this is not a bug, you can use `attach_db_allow_change()`."
2428                                );
2429                            }
2430                            Self { state: None }
2431                        }
2432                        None => {
2433                            // Otherwise, set the database.
2434                            attached.database.set(Some(NonNull::from(db)));
2435                            Self { state: Some(attached) }
2436                        }
2437                    }
2438                }
2439            }
2440
2441            impl Drop for DbGuard<'_> {
2442                #[inline]
2443                fn drop(&mut self) {
2444                    // Reset database to null if we did anything in `DbGuard::new`.
2445                    if let Some(attached) = self.state {
2446                        attached.database.set(None);
2447                    }
2448                }
2449            }
2450
2451            let _guard = DbGuard::new(self, db);
2452            super::tls_cache::reinit_cache(db);
2453            op()
2454        }
2455
2456        #[inline]
2457        fn attach_allow_change<R>(&self, db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2458            struct DbGuard<'s> {
2459                state: &'s Attached,
2460                prev: Option<NonNull<dyn HirDatabase>>,
2461            }
2462
2463            impl<'s> DbGuard<'s> {
2464                #[inline]
2465                fn new(attached: &'s Attached, db: &dyn HirDatabase) -> Self {
2466                    let prev = attached.database.replace(Some(NonNull::from(db)));
2467                    Self { state: attached, prev }
2468                }
2469            }
2470
2471            impl Drop for DbGuard<'_> {
2472                #[inline]
2473                fn drop(&mut self) {
2474                    self.state.database.set(self.prev);
2475                    if let Some(prev) = self.prev {
2476                        super::tls_cache::reinit_cache(unsafe { prev.as_ref() });
2477                    }
2478                }
2479            }
2480
2481            let _guard = DbGuard::new(self, db);
2482            super::tls_cache::reinit_cache(db);
2483            op()
2484        }
2485
2486        #[inline]
2487        fn with<R>(&self, op: impl FnOnce(&dyn HirDatabase) -> R) -> R {
2488            let db = self.database.get().expect("Try to use attached db, but not db is attached");
2489
2490            // SAFETY: The db is attached, so it must be valid.
2491            op(unsafe { db.as_ref() })
2492        }
2493    }
2494
2495    thread_local! {
2496        static GLOBAL_DB: Attached = const { Attached { database: Cell::new(None) } };
2497    }
2498
2499    #[inline]
2500    pub fn attach_db<R>(db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2501        GLOBAL_DB.with(|global_db| global_db.attach(db, op))
2502    }
2503
2504    #[inline]
2505    pub fn attach_db_allow_change<R>(db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2506        GLOBAL_DB.with(|global_db| global_db.attach_allow_change(db, op))
2507    }
2508
2509    #[inline]
2510    pub fn with_attached_db<R>(op: impl FnOnce(&dyn HirDatabase) -> R) -> R {
2511        GLOBAL_DB.with(
2512            #[inline]
2513            |a| a.with(op),
2514        )
2515    }
2516}
2517
2518mod tls_cache {
2519    use crate::db::HirDatabase;
2520
2521    use super::DbInterner;
2522    use base_db::Nonce;
2523    use rustc_type_ir::search_graph::GlobalCache;
2524    use salsa::Revision;
2525    use std::cell::RefCell;
2526
2527    struct Cache {
2528        cache: GlobalCache<DbInterner<'static>>,
2529        revision: Revision,
2530        db_nonce: Nonce,
2531    }
2532
2533    impl Cache {
2534        const fn default() -> Cache {
2535            Cache {
2536                cache: GlobalCache::new(),
2537                revision: Revision::max(),
2538                db_nonce: Nonce::invalid(),
2539            }
2540        }
2541    }
2542
2543    thread_local! {
2544        static GLOBAL_CACHE: RefCell<Cache> = const { RefCell::new(Cache::default()) };
2545    }
2546
2547    pub(super) fn reinit_cache(db: &dyn HirDatabase) {
2548        GLOBAL_CACHE.with_borrow_mut(|handle| {
2549            let (db_nonce, revision) = db.nonce_and_revision();
2550            if handle.revision != revision || db_nonce != handle.db_nonce {
2551                *handle = Cache { cache: GlobalCache::default(), revision, db_nonce };
2552            }
2553        })
2554    }
2555
2556    #[inline]
2557    pub(super) fn borrow_assume_valid<'db, T>(
2558        db: &'db dyn HirDatabase,
2559        f: impl FnOnce(&mut GlobalCache<DbInterner<'db>>) -> T,
2560    ) -> T {
2561        if cfg!(debug_assertions) {
2562            let get_state =
2563                || GLOBAL_CACHE.with_borrow(|handle| (handle.db_nonce, handle.revision));
2564            let old_state = get_state();
2565            reinit_cache(db);
2566            let new_state = get_state();
2567            assert_eq!(old_state, new_state, "you assumed the cache is valid!");
2568        }
2569
2570        GLOBAL_CACHE.with_borrow_mut(|handle| {
2571            // SAFETY: No idea
2572            f(unsafe {
2573                std::mem::transmute::<
2574                    &mut GlobalCache<DbInterner<'static>>,
2575                    &mut GlobalCache<DbInterner<'db>>,
2576                >(&mut handle.cache)
2577            })
2578        })
2579    }
2580
2581    /// Clears the thread-local trait solver cache.
2582    ///
2583    /// Should be called before getting memory usage estimations, as the solver cache
2584    /// is per-revision and usually should be excluded from estimations.
2585    pub fn clear_tls_solver_cache() {
2586        GLOBAL_CACHE.with_borrow_mut(|handle| *handle = Cache::default());
2587    }
2588}
2589
2590impl WorldExposer for intern::GarbageCollector {
2591    fn on_interned<T: intern::Internable>(
2592        &mut self,
2593        interned: InternedRef<'_, T>,
2594    ) -> ControlFlow<()> {
2595        self.mark_interned_alive(interned)
2596    }
2597
2598    fn on_interned_slice<T: intern::SliceInternable>(
2599        &mut self,
2600        interned: InternedSliceRef<'_, T>,
2601    ) -> ControlFlow<()> {
2602        self.mark_interned_slice_alive(interned)
2603    }
2604}
2605
2606/// # Safety
2607///
2608/// This cannot be called if there are some not-yet-recorded type values. Generally, if you have a mutable
2609/// reference to the database, and there are no other database - then you can call this safely, but you
2610/// also need to make sure to maintain the mutable reference while this is running.
2611pub unsafe fn collect_ty_garbage() {
2612    let mut gc = intern::GarbageCollector::default();
2613
2614    gc.add_storage::<super::consts::ConstInterned>();
2615    gc.add_storage::<super::consts::ValTreeInterned>();
2616    gc.add_storage::<super::allocation::AllocationInterned>();
2617    gc.add_storage::<PatternInterned>();
2618    gc.add_storage::<super::opaques::ExternalConstraintsInterned>();
2619    gc.add_storage::<super::predicate::PredicateInterned>();
2620    gc.add_storage::<super::region::RegionInterned>();
2621    gc.add_storage::<super::ty::TyInterned>();
2622
2623    gc.add_slice_storage::<super::consts::ConstsStorage>();
2624    gc.add_slice_storage::<super::predicate::ClausesStorage>();
2625    gc.add_slice_storage::<super::generic_arg::GenericArgsStorage>();
2626    gc.add_slice_storage::<BoundVarKindsStorage>();
2627    gc.add_slice_storage::<VariancesOfStorage>();
2628    gc.add_slice_storage::<CanonicalVarsStorage>();
2629    gc.add_slice_storage::<PatListStorage>();
2630    gc.add_slice_storage::<super::opaques::PredefinedOpaquesStorage>();
2631    gc.add_slice_storage::<super::opaques::SolverDefIdsStorage>();
2632    gc.add_slice_storage::<super::predicate::BoundExistentialPredicatesStorage>();
2633    gc.add_slice_storage::<super::region::RegionAssumptionsStorage>();
2634    gc.add_slice_storage::<super::ty::TysStorage>();
2635    gc.add_slice_storage::<crate::mir::ProjectionStorage>();
2636
2637    // SAFETY:
2638    //  - By our precondition, there are no unrecorded types.
2639    //  - We implement `GcInternedVisit` and `GcInternedSliceVisit` correctly for all types.
2640    //  - We added all storages (FIXME: it's too easy to forget to add a new storage here).
2641    unsafe { gc.collect() };
2642}
2643
2644macro_rules! impl_gc_visit {
2645    ( $($ty:ty),* $(,)? ) => {
2646        $(
2647            impl ::intern::GcInternedVisit for $ty {
2648                #[inline]
2649                fn visit_with(&self, gc: &mut ::intern::GarbageCollector) {
2650                    self.generic_visit_with(gc);
2651                }
2652            }
2653        )*
2654    };
2655}
2656
2657impl_gc_visit!(
2658    super::consts::ConstInterned,
2659    super::consts::ValTreeInterned,
2660    super::allocation::AllocationInterned,
2661    PatternInterned,
2662    super::opaques::ExternalConstraintsInterned,
2663    super::predicate::PredicateInterned,
2664    super::region::RegionInterned,
2665    super::ty::TyInterned,
2666    super::predicate::ClausesCachedTypeInfo,
2667);
2668
2669macro_rules! impl_gc_visit_slice {
2670    ( $($ty:ty),* $(,)? ) => {
2671        $(
2672            impl ::intern::GcInternedSliceVisit for $ty {
2673                #[inline]
2674                fn visit_header(header: &<Self as ::intern::SliceInternable>::Header, gc: &mut ::intern::GarbageCollector) {
2675                    header.generic_visit_with(gc);
2676                }
2677
2678                #[inline]
2679                fn visit_slice(slice: &[<Self as ::intern::SliceInternable>::SliceType], gc: &mut ::intern::GarbageCollector) {
2680                    slice.generic_visit_with(gc);
2681                }
2682            }
2683        )*
2684    };
2685}
2686
2687impl_gc_visit_slice!(
2688    super::predicate::ClausesStorage,
2689    super::generic_arg::GenericArgsStorage,
2690    BoundVarKindsStorage,
2691    VariancesOfStorage,
2692    CanonicalVarsStorage,
2693    PatListStorage,
2694    super::opaques::PredefinedOpaquesStorage,
2695    super::opaques::SolverDefIdsStorage,
2696    super::predicate::BoundExistentialPredicatesStorage,
2697    super::region::RegionAssumptionsStorage,
2698    super::ty::TysStorage,
2699    super::consts::ConstsStorage,
2700    crate::mir::ProjectionStorage,
2701);