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(interner: DbInterner<'db>) -> Self {
94                interner.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(DbInterner::conjure())
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(self.db)
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        panic!("evaluation shouldn't be concurrent yet")
1057    }
1058
1059    fn expand_abstract_consts<T: rustc_type_ir::TypeFoldable<Self>>(self, _: T) -> T {
1060        unreachable!("only used by the old trait solver in rustc");
1061    }
1062
1063    fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf {
1064        generics(self, def_id)
1065    }
1066
1067    fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf {
1068        let generic_def = match def_id {
1069            SolverDefId::Ctor(Ctor::Enum(def_id)) | SolverDefId::EnumVariantId(def_id) => {
1070                def_id.loc(self.db).parent.into()
1071            }
1072            SolverDefId::InternedOpaqueTyId(_def_id) => {
1073                // FIXME(next-solver): track variances
1074                //
1075                // We compute them based on the only `Ty` level info in rustc,
1076                // move `variances_of_opaque` into `rustc_next_trait_solver` for reuse.
1077                return VariancesOf::new_from_iter(
1078                    self,
1079                    (0..self.generics_of(def_id).count()).map(|_| Variance::Invariant),
1080                );
1081            }
1082            SolverDefId::Ctor(Ctor::Struct(def_id)) => def_id.into(),
1083            SolverDefId::AdtId(def_id) => def_id.into(),
1084            SolverDefId::FunctionId(def_id) => def_id.into(),
1085            SolverDefId::ConstId(_)
1086            | SolverDefId::StaticId(_)
1087            | SolverDefId::TraitId(_)
1088            | SolverDefId::TypeAliasId(_)
1089            | SolverDefId::ImplId(_)
1090            | SolverDefId::BuiltinDeriveImplId(_)
1091            | SolverDefId::InternedClosureId(_)
1092            | SolverDefId::InternedCoroutineId(_)
1093            | SolverDefId::InternedCoroutineClosureId(_)
1094            | SolverDefId::AnonConstId(_) => {
1095                return VariancesOf::empty(self);
1096            }
1097        };
1098        self.db.variances_of(generic_def)
1099    }
1100
1101    fn type_of(self, def_id: Self::DefId) -> EarlyBinder<Self, Self::Ty> {
1102        match def_id {
1103            SolverDefId::TypeAliasId(id) => self.db().ty(id.into()),
1104            SolverDefId::AdtId(id) => self.db().ty(id.into()),
1105            // FIXME(next-solver): This uses the types of `query mir_borrowck` in rustc.
1106            //
1107            // We currently always use the type from HIR typeck which ignores regions. This
1108            // should be fine.
1109            SolverDefId::InternedOpaqueTyId(def_id) => {
1110                self.type_of_opaque_hir_typeck(def_id.into())
1111            }
1112            SolverDefId::FunctionId(id) => self.db.value_ty(id.into()).unwrap(),
1113            SolverDefId::Ctor(id) => {
1114                let id = match id {
1115                    Ctor::Struct(id) => id.into(),
1116                    Ctor::Enum(id) => id.into(),
1117                };
1118                self.db.value_ty(id).expect("`SolverDefId::Ctor` should have a function-like ctor")
1119            }
1120            _ => panic!("Unexpected def_id `{def_id:?}` provided for `type_of`"),
1121        }
1122    }
1123
1124    fn adt_def(self, def_id: Self::AdtId) -> Self::AdtDef {
1125        AdtDef::new(def_id.0, self)
1126    }
1127
1128    fn alias_term_kind_from_def_id(self, def_id: SolverDefId<'db>) -> AliasTermKind<'db> {
1129        match def_id {
1130            SolverDefId::InternedOpaqueTyId(def_id) => {
1131                AliasTermKind::OpaqueTy { def_id: def_id.into() }
1132            }
1133            SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container {
1134                ItemContainerId::ImplId(impl_)
1135                    if ImplSignature::of(self.db, impl_).target_trait.is_none() =>
1136                {
1137                    AliasTermKind::InherentTy { def_id: type_alias.into() }
1138                }
1139                ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => {
1140                    AliasTermKind::ProjectionTy { def_id: type_alias.into() }
1141                }
1142                _ => AliasTermKind::FreeTy { def_id: type_alias.into() },
1143            },
1144            // rustc creates an `AnonConst` for consts, and evaluates them with CTFE (normalizing projections
1145            // via selection, similar to ours `find_matching_impl()`, and not with the trait solver), so mimic it.
1146            SolverDefId::ConstId(def_id) => {
1147                AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) }
1148            }
1149            SolverDefId::StaticId(def_id) => {
1150                AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) }
1151            }
1152            SolverDefId::AnonConstId(def_id) => {
1153                AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) }
1154            }
1155            _ => unimplemented!("Unexpected alias: {:?}", def_id),
1156        }
1157    }
1158
1159    fn trait_ref_and_own_args_for_alias(
1160        self,
1161        def_id: Self::TraitAssocTermId,
1162        args: Self::GenericArgs,
1163    ) -> (rustc_type_ir::TraitRef<Self>, Self::GenericArgsSlice) {
1164        let trait_def_id = self.projection_parent(def_id).0;
1165        let trait_generics = crate::generics::generics(self.db, trait_def_id.into());
1166        let trait_generics_len = trait_generics.len(true);
1167        let trait_args = GenericArgs::new_from_slice(&args.as_slice()[..trait_generics_len]);
1168        let alias_args = &args.as_slice()[trait_generics_len..];
1169        (TraitRef::new_from_args(self, trait_def_id.into(), trait_args), alias_args)
1170    }
1171
1172    fn check_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs) -> bool {
1173        let generics = self.generics_of(def_id);
1174        generics.count() == args.len()
1175            && std::iter::zip(generics.iter(), args).all(|((param, _), arg)| {
1176                matches!(
1177                    (param, arg.kind()),
1178                    (GenericParamId::LifetimeParamId(_), GenericArgKind::Lifetime(_))
1179                        | (GenericParamId::TypeParamId(_), GenericArgKind::Type(_))
1180                        | (GenericParamId::ConstParamId(_), GenericArgKind::Const(_))
1181                )
1182            })
1183    }
1184
1185    fn debug_assert_args_compatible(self, _def_id: Self::DefId, _args: Self::GenericArgs) {}
1186
1187    fn debug_assert_existential_args_compatible(
1188        self,
1189        _def_id: Self::DefId,
1190        _args: Self::GenericArgs,
1191    ) {
1192    }
1193
1194    fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
1195    where
1196        I: Iterator<Item = T>,
1197        T: rustc_type_ir::CollectAndApply<Self::Ty, Self::Tys>,
1198    {
1199        Tys::new_from_iter(self, args)
1200    }
1201
1202    fn projection_parent(self, def_id: Self::TraitAssocTermId) -> Self::TraitId {
1203        let container = match def_id.0 {
1204            TermId::TypeAliasId(def_id) => def_id.loc(self.db).container,
1205            TermId::ConstId(def_id) => def_id.loc(self.db).container,
1206        };
1207        let ItemContainerId::TraitId(trait_) = container else {
1208            panic!("a TraitAssocTermId can only come from a trait")
1209        };
1210        trait_.into()
1211    }
1212
1213    fn impl_or_trait_assoc_term_parent(self, def_id: Self::ImplOrTraitAssocTermId) -> Self::DefId {
1214        let container = match def_id.0 {
1215            TermId::TypeAliasId(def_id) => def_id.loc(self.db).container,
1216            TermId::ConstId(def_id) => def_id.loc(self.db).container,
1217        };
1218        match container {
1219            ItemContainerId::ImplId(impl_) => impl_.into(),
1220            ItemContainerId::TraitId(trait_) => trait_.into(),
1221            ItemContainerId::ExternBlockId(_) | ItemContainerId::ModuleId(_) => {
1222                panic!("only impl or trait can be the parent of ImplOrTraitAssocTermId")
1223            }
1224        }
1225    }
1226
1227    fn inherent_alias_term_parent(self, def_id: Self::InherentAssocTermId) -> Self::ImplId {
1228        let container = match def_id.0 {
1229            TermId::TypeAliasId(def_id) => def_id.loc(self.db).container,
1230            TermId::ConstId(def_id) => def_id.loc(self.db).container,
1231        };
1232        match container {
1233            ItemContainerId::ImplId(impl_) => impl_.into(),
1234            ItemContainerId::ExternBlockId(_)
1235            | ItemContainerId::ModuleId(_)
1236            | ItemContainerId::TraitId(_) => {
1237                panic!("only impl can be the parent of InherentAliasTermId")
1238            }
1239        }
1240    }
1241
1242    fn recursion_limit(self) -> usize {
1243        50
1244    }
1245
1246    fn is_type_const(self, _def_id: Self::DefId) -> bool {
1247        false
1248    }
1249
1250    fn features(self) -> Features {
1251        Features
1252    }
1253
1254    fn fn_sig(
1255        self,
1256        def_id: Self::FunctionId,
1257    ) -> EarlyBinder<Self, rustc_type_ir::Binder<Self, rustc_type_ir::FnSig<Self>>> {
1258        self.db().callable_item_signature(def_id.0)
1259    }
1260
1261    fn coroutine_movability(self, def_id: Self::CoroutineId) -> rustc_ast_ir::Movability {
1262        match def_id.0.loc(self.db).kind {
1263            hir_def::hir::ClosureKind::OldCoroutine(movability) => match movability {
1264                hir_def::hir::Movability::Static => rustc_ast_ir::Movability::Static,
1265                hir_def::hir::Movability::Movable => rustc_ast_ir::Movability::Movable,
1266            },
1267            hir_def::hir::ClosureKind::Coroutine { .. } => rustc_ast_ir::Movability::Static,
1268            kind => panic!("unexpected kind for a coroutine: {kind:?}"),
1269        }
1270    }
1271
1272    fn coroutine_for_closure(self, def_id: Self::CoroutineClosureId) -> Self::CoroutineId {
1273        let InternedClosure { owner, expr: coroutine_closure_expr, kind: coroutine_closure_kind } =
1274            def_id.0.loc(self.db);
1275        let coroutine_closure_kind = match coroutine_closure_kind {
1276            HirClosureKind::CoroutineClosure(it) => it,
1277            _ => {
1278                panic!("invalid kind closure kind {coroutine_closure_kind:?} for coroutine closure")
1279            }
1280        };
1281        let coroutine_expr = ExpressionStore::coroutine_for_closure(coroutine_closure_expr);
1282        let coroutine_kind = hir_def::hir::ClosureKind::Coroutine {
1283            kind: coroutine_closure_kind,
1284            source: hir_def::hir::CoroutineSource::Closure,
1285        };
1286        InternedCoroutineId::new(
1287            self.db,
1288            InternedClosure { owner, expr: coroutine_expr, kind: coroutine_kind },
1289        )
1290        .into()
1291    }
1292
1293    fn generics_require_sized_self(self, def_id: Self::DefId) -> bool {
1294        let sized_trait = self.lang_items().Sized;
1295        let Some(sized_id) = sized_trait else {
1296            return false; /* No Sized trait, can't require it! */
1297        };
1298        let sized_def_id = sized_id.into();
1299
1300        // Search for a predicate like `Self : Sized` amongst the trait bounds.
1301        let predicates = self.predicates_of(def_id);
1302        elaborate(self, predicates.iter_identity().map(Unnormalized::skip_norm_wip)).any(|pred| {
1303            match pred.kind().skip_binder() {
1304                ClauseKind::Trait(ref trait_pred) => {
1305                    trait_pred.def_id() == sized_def_id
1306                        && matches!(
1307                            trait_pred.self_ty().kind(),
1308                            TyKind::Param(ParamTy { index: 0, .. })
1309                        )
1310                }
1311                ClauseKind::RegionOutlives(_)
1312                | ClauseKind::TypeOutlives(_)
1313                | ClauseKind::Projection(_)
1314                | ClauseKind::ConstArgHasType(_, _)
1315                | ClauseKind::WellFormed(_)
1316                | ClauseKind::ConstEvaluatable(_)
1317                | ClauseKind::HostEffect(..)
1318                | ClauseKind::UnstableFeature(_) => false,
1319            }
1320        })
1321    }
1322
1323    #[tracing::instrument(skip(self))]
1324    fn item_bounds(
1325        self,
1326        def_id: Self::DefId,
1327    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1328        explicit_item_bounds(self, def_id).map_bound(|bounds| elaborate(self, bounds))
1329    }
1330
1331    #[tracing::instrument(skip(self))]
1332    fn item_self_bounds(
1333        self,
1334        def_id: Self::DefId,
1335    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1336        explicit_item_self_bounds(self, def_id)
1337            .map_bound(|bounds| elaborate(self, bounds).filter_only_self())
1338    }
1339
1340    fn item_non_self_bounds(
1341        self,
1342        def_id: Self::DefId,
1343    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1344        let all_bounds: FxHashSet<_> = self.item_bounds(def_id).skip_binder().into_iter().collect();
1345        let own_bounds: FxHashSet<_> =
1346            self.item_self_bounds(def_id).skip_binder().into_iter().collect();
1347        if all_bounds.len() == own_bounds.len() {
1348            EarlyBinder::bind(Clauses::empty(self))
1349        } else {
1350            EarlyBinder::bind(Clauses::new_from_iter(
1351                self,
1352                all_bounds.difference(&own_bounds).cloned(),
1353            ))
1354        }
1355    }
1356
1357    fn predicates_of(
1358        self,
1359        def_id: Self::DefId,
1360    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1361        predicates_of(self.db, def_id).all_predicates()
1362    }
1363
1364    fn own_predicates_of(
1365        self,
1366        def_id: Self::DefId,
1367    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1368        predicates_of(self.db, def_id).own_explicit_predicates()
1369    }
1370
1371    fn explicit_super_predicates_of(
1372        self,
1373        def_id: Self::TraitId,
1374    ) -> EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> {
1375        GenericPredicates::query(self.db, def_id.0.into())
1376            .explicit_non_assoc_types_predicates()
1377            .map_bound(move |predicates| {
1378                predicates.filter(|p| is_clause_at_ty(p, is_ty_self)).map(|p| (p, Span::dummy()))
1379            })
1380    }
1381
1382    fn explicit_implied_predicates_of(
1383        self,
1384        def_id: Self::DefId,
1385    ) -> EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> {
1386        fn is_ty_assoc_of_self(ty: Ty<'_>) -> bool {
1387            // FIXME: Is this correct wrt. combined kind of assoc type bounds, i.e. `where Self::Assoc: Trait<Assoc2: Trait>`
1388            // wrt. `Assoc2`, which we should exclude?
1389            if let TyKind::Alias(alias @ AliasTy { kind: AliasTyKind::Projection { .. }, .. }) =
1390                ty.kind()
1391            {
1392                is_ty_assoc_of_self(alias.self_ty())
1393            } else {
1394                is_ty_self(ty)
1395            }
1396        }
1397
1398        let predicates = predicates_of(self.db, def_id);
1399        let non_assoc_types = predicates
1400            .explicit_non_assoc_types_predicates()
1401            .skip_binder()
1402            .filter(|p| is_clause_at_ty(p, is_ty_self));
1403        let assoc_types = predicates
1404            .explicit_assoc_types_predicates()
1405            .skip_binder()
1406            .filter(|p| is_clause_at_ty(p, is_ty_assoc_of_self));
1407        EarlyBinder::bind(non_assoc_types.chain(assoc_types).map(|it| (it, Span::dummy())))
1408    }
1409
1410    fn impl_super_outlives(
1411        self,
1412        impl_id: Self::ImplId,
1413    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1414        let trait_ref = self.impl_trait_ref(impl_id);
1415        trait_ref.map_bound(|trait_ref| {
1416            let clause: Clause<'_> = trait_ref.upcast(self);
1417            elaborate(self, [clause]).filter(|clause| {
1418                matches!(
1419                    clause.kind().skip_binder(),
1420                    ClauseKind::TypeOutlives(_) | ClauseKind::RegionOutlives(_)
1421                )
1422            })
1423        })
1424    }
1425
1426    #[expect(unreachable_code)]
1427    fn const_conditions(
1428        self,
1429        _def_id: Self::DefId,
1430    ) -> EarlyBinder<
1431        Self,
1432        impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>,
1433    > {
1434        EarlyBinder::bind([unimplemented!()])
1435    }
1436
1437    fn has_target_features(self, _def_id: Self::FunctionId) -> bool {
1438        false
1439    }
1440
1441    fn require_projection_lang_item(
1442        self,
1443        lang_item: SolverProjectionLangItem,
1444    ) -> Self::TraitAssocTyId {
1445        let lang_items = self.lang_items();
1446        let lang_item = match lang_item {
1447            SolverProjectionLangItem::AsyncFnKindUpvars => lang_items.AsyncFnKindUpvars,
1448            SolverProjectionLangItem::AsyncFnOnceOutput => lang_items.AsyncFnOnceOutput,
1449            SolverProjectionLangItem::CallOnceFuture => lang_items.CallOnceFuture,
1450            SolverProjectionLangItem::CallRefFuture => lang_items.CallRefFuture,
1451            SolverProjectionLangItem::CoroutineReturn => lang_items.CoroutineReturn,
1452            SolverProjectionLangItem::CoroutineYield => lang_items.CoroutineYield,
1453            SolverProjectionLangItem::FutureOutput => lang_items.FutureOutput,
1454            SolverProjectionLangItem::Metadata => lang_items.Metadata,
1455            SolverProjectionLangItem::FieldBase => lang_items.FieldBase,
1456            SolverProjectionLangItem::FieldType => lang_items.FieldType,
1457        };
1458        lang_item.expect("Lang item required but not found.").into()
1459    }
1460
1461    fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> TraitIdWrapper {
1462        let lang_items = self.lang_items();
1463        let lang_item = match lang_item {
1464            SolverTraitLangItem::AsyncFn => lang_items.AsyncFn,
1465            SolverTraitLangItem::AsyncFnKindHelper => lang_items.AsyncFnKindHelper,
1466            SolverTraitLangItem::AsyncFnMut => lang_items.AsyncFnMut,
1467            SolverTraitLangItem::AsyncFnOnce => lang_items.AsyncFnOnce,
1468            SolverTraitLangItem::AsyncIterator => lang_items.AsyncIterator,
1469            SolverTraitLangItem::Clone => lang_items.Clone,
1470            SolverTraitLangItem::Copy => lang_items.Copy,
1471            SolverTraitLangItem::Coroutine => lang_items.Coroutine,
1472            SolverTraitLangItem::Destruct => lang_items.Destruct,
1473            SolverTraitLangItem::DiscriminantKind => lang_items.DiscriminantKind,
1474            SolverTraitLangItem::Drop => lang_items.Drop,
1475            SolverTraitLangItem::Fn => lang_items.Fn,
1476            SolverTraitLangItem::FnMut => lang_items.FnMut,
1477            SolverTraitLangItem::FnOnce => lang_items.FnOnce,
1478            SolverTraitLangItem::FnPtrTrait => lang_items.FnPtrTrait,
1479            SolverTraitLangItem::FusedIterator => lang_items.FusedIterator,
1480            SolverTraitLangItem::Future => lang_items.Future,
1481            SolverTraitLangItem::Iterator => lang_items.Iterator,
1482            SolverTraitLangItem::PointeeTrait => lang_items.PointeeTrait,
1483            SolverTraitLangItem::Sized => lang_items.Sized,
1484            SolverTraitLangItem::MetaSized => lang_items.MetaSized,
1485            SolverTraitLangItem::PointeeSized => lang_items.PointeeSized,
1486            SolverTraitLangItem::TransmuteTrait => lang_items.TransmuteTrait,
1487            SolverTraitLangItem::Tuple => lang_items.Tuple,
1488            SolverTraitLangItem::Unpin => lang_items.Unpin,
1489            SolverTraitLangItem::Unsize => lang_items.Unsize,
1490            SolverTraitLangItem::BikeshedGuaranteedNoDrop => lang_items.BikeshedGuaranteedNoDrop,
1491            SolverTraitLangItem::TrivialClone => lang_items.TrivialClone,
1492            SolverTraitLangItem::Field => lang_items.Field,
1493        };
1494        lang_item.expect("Lang item required but not found.").into()
1495    }
1496
1497    fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> AdtIdWrapper {
1498        let lang_items = self.lang_items();
1499        let lang_item = match lang_item {
1500            SolverAdtLangItem::Option => lang_items.Option.map(Into::into),
1501            SolverAdtLangItem::Poll => lang_items.Poll.map(Into::into),
1502            SolverAdtLangItem::DynMetadata => lang_items.DynMetadata.map(Into::into),
1503        };
1504        AdtIdWrapper(lang_item.expect("Lang item required but not found."))
1505    }
1506
1507    fn is_projection_lang_item(
1508        self,
1509        def_id: Self::TraitAssocTyId,
1510        lang_item: SolverProjectionLangItem,
1511    ) -> bool {
1512        self.as_projection_lang_item(def_id)
1513            .map_or(false, |l| std::mem::discriminant(&l) == std::mem::discriminant(&lang_item))
1514    }
1515
1516    fn is_trait_lang_item(self, def_id: Self::TraitId, lang_item: SolverTraitLangItem) -> bool {
1517        is_lang_item!(
1518            SolverTraitLangItem, self, def_id.0, lang_item;
1519
1520            Sized,
1521            MetaSized,
1522            PointeeSized,
1523            Unsize,
1524            Copy,
1525            Clone,
1526            DiscriminantKind,
1527            PointeeTrait,
1528            FnPtrTrait,
1529            Drop,
1530            Destruct,
1531            TransmuteTrait,
1532            Fn,
1533            FnMut,
1534            FnOnce,
1535            Future,
1536            Coroutine,
1537            Unpin,
1538            Tuple,
1539            Iterator,
1540            AsyncFn,
1541            AsyncFnMut,
1542            AsyncFnOnce,
1543            TrivialClone,
1544            AsyncFnKindHelper,
1545            AsyncIterator,
1546            BikeshedGuaranteedNoDrop,
1547            FusedIterator,
1548            Field,
1549        )
1550    }
1551
1552    fn is_adt_lang_item(self, def_id: Self::AdtId, lang_item: SolverAdtLangItem) -> bool {
1553        // FIXME: derive PartialEq on SolverTraitLangItem
1554        self.as_adt_lang_item(def_id)
1555            .map_or(false, |l| std::mem::discriminant(&l) == std::mem::discriminant(&lang_item))
1556    }
1557
1558    fn as_projection_lang_item(
1559        self,
1560        def_id: Self::TraitAssocTyId,
1561    ) -> Option<SolverProjectionLangItem> {
1562        as_lang_item!(
1563            SolverProjectionLangItem, self, def_id.0, TypeAliasId;
1564
1565            Metadata,
1566            CoroutineReturn,
1567            CoroutineYield,
1568            FutureOutput,
1569            CallRefFuture,
1570            CallOnceFuture,
1571            AsyncFnOnceOutput,
1572            AsyncFnKindUpvars,
1573            FieldBase,
1574            FieldType,
1575        )
1576    }
1577
1578    fn as_trait_lang_item(self, def_id: Self::TraitId) -> Option<SolverTraitLangItem> {
1579        as_lang_item!(
1580            SolverTraitLangItem, self, def_id.0, TraitId;
1581
1582            Sized,
1583            MetaSized,
1584            PointeeSized,
1585            Unsize,
1586            Copy,
1587            Clone,
1588            DiscriminantKind,
1589            PointeeTrait,
1590            FnPtrTrait,
1591            Drop,
1592            Destruct,
1593            TransmuteTrait,
1594            Fn,
1595            FnMut,
1596            FnOnce,
1597            Future,
1598            Coroutine,
1599            Unpin,
1600            Tuple,
1601            Iterator,
1602            AsyncFn,
1603            AsyncFnMut,
1604            AsyncFnOnce,
1605            TrivialClone,
1606            AsyncFnKindHelper,
1607            AsyncIterator,
1608            BikeshedGuaranteedNoDrop,
1609            FusedIterator,
1610            Field,
1611        )
1612    }
1613
1614    fn as_adt_lang_item(self, def_id: Self::AdtId) -> Option<SolverAdtLangItem> {
1615        as_lang_item!(
1616            SolverAdtLangItem, self, def_id.0, AdtId;
1617
1618            Option,
1619            Poll,
1620            DynMetadata,
1621        )
1622    }
1623
1624    fn associated_type_def_ids(
1625        self,
1626        def_id: Self::TraitId,
1627    ) -> impl IntoIterator<Item = Self::DefId> {
1628        def_id.0.trait_items(self.db()).associated_types().map(|id| id.into())
1629    }
1630
1631    fn for_each_relevant_impl<R: VisitorResult>(
1632        self,
1633        trait_def_id: Self::TraitId,
1634        self_ty: Self::Ty,
1635        mut f: impl FnMut(Self::ImplId) -> R,
1636    ) -> R {
1637        let krate = self.krate.expect("trait solving requires setting `DbInterner::krate`");
1638        let trait_block = trait_def_id.0.loc(self.db).container.block(self.db);
1639        let mut consider_impls_for_simplified_type = |simp: SimplifiedType<'_>| {
1640            let type_block = simp.def().and_then(|def_id| {
1641                let module = match def_id {
1642                    SolverDefId::AdtId(AdtId::StructId(id)) => id.module(self.db),
1643                    SolverDefId::AdtId(AdtId::EnumId(id)) => id.module(self.db),
1644                    SolverDefId::AdtId(AdtId::UnionId(id)) => id.module(self.db),
1645                    SolverDefId::TraitId(id) => id.module(self.db),
1646                    SolverDefId::TypeAliasId(id) => id.module(self.db),
1647                    SolverDefId::ConstId(_)
1648                    | SolverDefId::FunctionId(_)
1649                    | SolverDefId::ImplId(_)
1650                    | SolverDefId::BuiltinDeriveImplId(_)
1651                    | SolverDefId::StaticId(_)
1652                    | SolverDefId::InternedClosureId(_)
1653                    | SolverDefId::InternedCoroutineId(_)
1654                    | SolverDefId::InternedCoroutineClosureId(_)
1655                    | SolverDefId::InternedOpaqueTyId(_)
1656                    | SolverDefId::EnumVariantId(_)
1657                    | SolverDefId::AnonConstId(_)
1658                    | SolverDefId::Ctor(_) => return None,
1659                };
1660                module.block(self.db)
1661            });
1662            TraitImpls::for_each_crate_and_block_trait_and_type(
1663                self.db,
1664                krate,
1665                type_block,
1666                trait_block,
1667                &mut |impls| {
1668                    let (regular_impls, builtin_derive_impls) =
1669                        impls.for_trait_and_self_ty(trait_def_id.0, &simp);
1670                    for &impl_ in regular_impls {
1671                        try_visit!(f(impl_.into()));
1672                    }
1673                    for &impl_ in builtin_derive_impls {
1674                        try_visit!(f(impl_.into()));
1675                    }
1676                    R::output()
1677                },
1678            )
1679        };
1680
1681        match self_ty.kind() {
1682            TyKind::Bool
1683            | TyKind::Char
1684            | TyKind::Int(_)
1685            | TyKind::Uint(_)
1686            | TyKind::Float(_)
1687            | TyKind::Adt(_, _)
1688            | TyKind::Foreign(_)
1689            | TyKind::Str
1690            | TyKind::Array(_, _)
1691            | TyKind::Pat(_, _)
1692            | TyKind::Slice(_)
1693            | TyKind::RawPtr(_, _)
1694            | TyKind::Ref(_, _, _)
1695            | TyKind::FnDef(_, _)
1696            | TyKind::FnPtr(..)
1697            | TyKind::Dynamic(_, _)
1698            | TyKind::Closure(..)
1699            | TyKind::CoroutineClosure(..)
1700            | TyKind::Coroutine(_, _)
1701            | TyKind::Never
1702            | TyKind::Tuple(_)
1703            | TyKind::UnsafeBinder(_) => {
1704                let simp =
1705                    fast_reject::simplify_type(self, self_ty, fast_reject::TreatParams::AsRigid)
1706                        .unwrap();
1707                try_visit!(consider_impls_for_simplified_type(simp));
1708            }
1709
1710            // HACK: For integer and float variables we have to manually look at all impls
1711            // which have some integer or float as a self type.
1712            TyKind::Infer(InferTy::IntVar(_)) => {
1713                use IntTy::*;
1714                use UintTy::*;
1715                // This causes a compiler error if any new integer kinds are added.
1716                let (I8 | I16 | I32 | I64 | I128 | Isize): IntTy;
1717                let (U8 | U16 | U32 | U64 | U128 | Usize): UintTy;
1718                let possible_integers = [
1719                    // signed integers
1720                    SimplifiedType::Int(I8),
1721                    SimplifiedType::Int(I16),
1722                    SimplifiedType::Int(I32),
1723                    SimplifiedType::Int(I64),
1724                    SimplifiedType::Int(I128),
1725                    SimplifiedType::Int(Isize),
1726                    // unsigned integers
1727                    SimplifiedType::Uint(U8),
1728                    SimplifiedType::Uint(U16),
1729                    SimplifiedType::Uint(U32),
1730                    SimplifiedType::Uint(U64),
1731                    SimplifiedType::Uint(U128),
1732                    SimplifiedType::Uint(Usize),
1733                ];
1734                for simp in possible_integers {
1735                    try_visit!(consider_impls_for_simplified_type(simp));
1736                }
1737            }
1738
1739            TyKind::Infer(InferTy::FloatVar(_)) => {
1740                // This causes a compiler error if any new float kinds are added.
1741                let (FloatTy::F16 | FloatTy::F32 | FloatTy::F64 | FloatTy::F128);
1742                let possible_floats = [
1743                    SimplifiedType::Float(FloatTy::F16),
1744                    SimplifiedType::Float(FloatTy::F32),
1745                    SimplifiedType::Float(FloatTy::F64),
1746                    SimplifiedType::Float(FloatTy::F128),
1747                ];
1748
1749                for simp in possible_floats {
1750                    try_visit!(consider_impls_for_simplified_type(simp));
1751                }
1752            }
1753
1754            // The only traits applying to aliases and placeholders are blanket impls.
1755            //
1756            // Impls which apply to an alias after normalization are handled by
1757            // `assemble_candidates_after_normalizing_self_ty`.
1758            TyKind::Alias(..) | TyKind::Placeholder(..) | TyKind::Error(_) => (),
1759
1760            // FIXME: These should ideally not exist as a self type. It would be nice for
1761            // the builtin auto trait impls of coroutines to instead directly recurse
1762            // into the witness.
1763            TyKind::CoroutineWitness(..) => (),
1764
1765            // These variants should not exist as a self type.
1766            TyKind::Infer(
1767                InferTy::TyVar(_)
1768                | InferTy::FreshTy(_)
1769                | InferTy::FreshIntTy(_)
1770                | InferTy::FreshFloatTy(_),
1771            )
1772            | TyKind::Param(_)
1773            | TyKind::Bound(_, _) => panic!("unexpected self type: {self_ty:?}"),
1774        }
1775
1776        self.for_each_blanket_impl(trait_def_id, f)
1777    }
1778
1779    fn for_each_blanket_impl<R: VisitorResult>(
1780        self,
1781        trait_def_id: Self::TraitId,
1782        mut f: impl FnMut(Self::ImplId) -> R,
1783    ) -> R {
1784        let Some(krate) = self.krate else {
1785            return R::output();
1786        };
1787        let block = trait_def_id.0.loc(self.db).container.block(self.db);
1788
1789        TraitImpls::for_each_crate_and_block(self.db, krate, block, &mut |impls| {
1790            for &impl_ in impls.blanket_impls(trait_def_id.0) {
1791                try_visit!(f(impl_.into()));
1792            }
1793            R::output()
1794        })
1795    }
1796
1797    fn has_item_definition(self, _def_id: Self::ImplOrTraitAssocTermId) -> bool {
1798        // FIXME(next-solver): should check if the associated item has a value.
1799        true
1800    }
1801
1802    fn impl_is_default(self, impl_def_id: Self::ImplId) -> bool {
1803        match impl_def_id {
1804            AnyImplId::ImplId(impl_id) => ImplSignature::of(self.db, impl_id).is_default(),
1805            AnyImplId::BuiltinDeriveImplId(_) => false,
1806        }
1807    }
1808
1809    #[tracing::instrument(skip(self), ret)]
1810    fn impl_trait_ref(
1811        self,
1812        impl_id: Self::ImplId,
1813    ) -> EarlyBinder<Self, rustc_type_ir::TraitRef<Self>> {
1814        match impl_id {
1815            AnyImplId::ImplId(impl_id) => {
1816                let db = self.db();
1817                db.impl_trait(impl_id)
1818                    // ImplIds for impls where the trait ref can't be resolved should never reach trait solving
1819                    .expect("invalid impl passed to trait solver")
1820            }
1821            AnyImplId::BuiltinDeriveImplId(impl_id) => {
1822                crate::builtin_derive::impl_trait(self, impl_id)
1823            }
1824        }
1825    }
1826
1827    fn impl_polarity(self, impl_id: Self::ImplId) -> rustc_type_ir::ImplPolarity {
1828        let AnyImplId::ImplId(impl_id) = impl_id else {
1829            return ImplPolarity::Positive;
1830        };
1831        let impl_data = ImplSignature::of(self.db(), impl_id);
1832        if impl_data.flags.contains(ImplFlags::NEGATIVE) {
1833            ImplPolarity::Negative
1834        } else {
1835            ImplPolarity::Positive
1836        }
1837    }
1838
1839    fn trait_is_auto(self, trait_: Self::TraitId) -> bool {
1840        let trait_data = TraitSignature::of(self.db(), trait_.0);
1841        trait_data.flags.contains(TraitFlags::AUTO)
1842    }
1843
1844    fn trait_is_alias(self, trait_: Self::TraitId) -> bool {
1845        let trait_data = TraitSignature::of(self.db(), trait_.0);
1846        trait_data.flags.contains(TraitFlags::ALIAS)
1847    }
1848
1849    fn trait_is_dyn_compatible(self, trait_: Self::TraitId) -> bool {
1850        crate::dyn_compatibility::dyn_compatibility(self.db(), trait_.0).is_none()
1851    }
1852
1853    fn trait_is_fundamental(self, trait_: Self::TraitId) -> bool {
1854        let trait_data = TraitSignature::of(self.db(), trait_.0);
1855        trait_data.flags.contains(TraitFlags::FUNDAMENTAL)
1856    }
1857
1858    fn is_impl_trait_in_trait(self, _def_id: Self::DefId) -> bool {
1859        // FIXME(next-solver)
1860        false
1861    }
1862
1863    fn delay_bug(self, _msg: impl ToString) -> Self::ErrorGuaranteed {
1864        ErrorGuaranteed
1865    }
1866
1867    fn is_general_coroutine(self, def_id: Self::CoroutineId) -> bool {
1868        matches!(def_id.0.loc(self.db).kind, HirClosureKind::OldCoroutine(_))
1869    }
1870
1871    fn coroutine_is_async(self, def_id: Self::CoroutineId) -> bool {
1872        matches!(
1873            def_id.0.loc(self.db).kind,
1874            HirClosureKind::Coroutine { kind: HirCoroutineKind::Async, .. }
1875        )
1876    }
1877
1878    fn coroutine_is_gen(self, def_id: Self::CoroutineId) -> bool {
1879        matches!(
1880            def_id.0.loc(self.db).kind,
1881            HirClosureKind::Coroutine { kind: HirCoroutineKind::Gen, .. }
1882        )
1883    }
1884
1885    fn coroutine_is_async_gen(self, def_id: Self::CoroutineId) -> bool {
1886        matches!(
1887            def_id.0.loc(self.db).kind,
1888            HirClosureKind::Coroutine { kind: HirCoroutineKind::AsyncGen, .. }
1889        )
1890    }
1891
1892    fn unsizing_params_for_adt(self, id: Self::AdtId) -> Self::UnsizingParams {
1893        let def = AdtDef::new(id.0, self);
1894        let num_params = self.generics_of(id.into()).count();
1895
1896        let maybe_unsizing_param_idx = |arg: GenericArg<'db>| match arg.kind() {
1897            GenericArgKind::Type(ty) => match ty.kind() {
1898                rustc_type_ir::TyKind::Param(p) => Some(p.index),
1899                _ => None,
1900            },
1901            GenericArgKind::Lifetime(_) => None,
1902            GenericArgKind::Const(ct) => match ct.kind() {
1903                rustc_type_ir::ConstKind::Param(p) => Some(p.index),
1904                _ => None,
1905            },
1906        };
1907
1908        // The last field of the structure has to exist and contain type/const parameters.
1909        let variant = match def.def_id() {
1910            AdtId::StructId(id) => VariantId::from(id),
1911            AdtId::UnionId(id) => id.into(),
1912            AdtId::EnumId(_) => panic!("expected a struct or a union"),
1913        };
1914        let fields = variant.fields(self.db());
1915        let mut prefix_fields = fields.fields().iter();
1916        let Some(tail_field) = prefix_fields.next_back() else {
1917            return UnsizingParams(DenseBitSet::new_empty(num_params));
1918        };
1919
1920        let field_types = self.db().field_types(variant);
1921        let mut unsizing_params = DenseBitSet::new_empty(num_params);
1922        let ty = field_types[tail_field.0].ty();
1923        for arg in ty.instantiate_identity().skip_norm_wip().walk() {
1924            if let Some(i) = maybe_unsizing_param_idx(arg) {
1925                unsizing_params.insert(i);
1926            }
1927        }
1928
1929        // Ensure none of the other fields mention the parameters used
1930        // in unsizing.
1931        for field in prefix_fields {
1932            for arg in field_types[field.0].ty().instantiate_identity().skip_norm_wip().walk() {
1933                if let Some(i) = maybe_unsizing_param_idx(arg) {
1934                    unsizing_params.remove(i);
1935                }
1936            }
1937        }
1938
1939        UnsizingParams(unsizing_params)
1940    }
1941
1942    fn anonymize_bound_vars<T: rustc_type_ir::TypeFoldable<Self>>(
1943        self,
1944        value: rustc_type_ir::Binder<Self, T>,
1945    ) -> rustc_type_ir::Binder<Self, T> {
1946        struct Anonymize<'a, 'db> {
1947            interner: DbInterner<'db>,
1948            map: &'a mut FxIndexMap<BoundVar, BoundVariableKind<'db>>,
1949        }
1950        impl<'db> BoundVarReplacerDelegate<'db> for Anonymize<'_, 'db> {
1951            fn replace_region(&mut self, br: BoundRegion<'db>) -> Region<'db> {
1952                let entry = self.map.entry(br.var);
1953                let index = entry.index();
1954                let var = BoundVar::from_usize(index);
1955                let kind = (*entry
1956                    .or_insert_with(|| BoundVariableKind::Region(BoundRegionKind::Anon)))
1957                .expect_region();
1958                let br = BoundRegion { var, kind };
1959                Region::new_bound(self.interner, DebruijnIndex::ZERO, br)
1960            }
1961            fn replace_ty(&mut self, bt: BoundTy<'db>) -> Ty<'db> {
1962                let entry = self.map.entry(bt.var);
1963                let index = entry.index();
1964                let var = BoundVar::from_usize(index);
1965                let kind = (*entry.or_insert_with(|| BoundVariableKind::Ty(BoundTyKind::Anon)))
1966                    .expect_ty();
1967                Ty::new_bound(self.interner, DebruijnIndex::ZERO, BoundTy { var, kind })
1968            }
1969            fn replace_const(&mut self, bv: BoundConst<'db>) -> Const<'db> {
1970                let entry = self.map.entry(bv.var);
1971                let index = entry.index();
1972                let var = BoundVar::from_usize(index);
1973                let () = (*entry.or_insert_with(|| BoundVariableKind::Const)).expect_const();
1974                Const::new_bound(self.interner, DebruijnIndex::ZERO, BoundConst::new(var))
1975            }
1976        }
1977
1978        let mut map = Default::default();
1979        let delegate = Anonymize { interner: self, map: &mut map };
1980        let inner = self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate);
1981        let bound_vars = BoundVarKinds::new_from_iter(self, map.into_values());
1982        Binder::bind_with_vars(inner, bound_vars)
1983    }
1984
1985    fn opaque_types_defined_by(self, def_id: Self::LocalDefId) -> Self::LocalDefIds {
1986        let Ok(def_id) = InferBodyId::try_from(def_id) else {
1987            return SolverDefIds::default();
1988        };
1989        let mut result = Vec::new();
1990        crate::opaques::opaque_types_defined_by(self.db, def_id, &mut result);
1991        SolverDefIds::new_from_slice(&result)
1992    }
1993
1994    fn opaque_types_and_coroutines_defined_by(self, def_id: Self::LocalDefId) -> Self::LocalDefIds {
1995        let db = self.db;
1996
1997        let Ok(def_id) = InferBodyId::try_from(def_id) else {
1998            return SolverDefIds::default();
1999        };
2000        let mut result = Vec::new();
2001
2002        crate::opaques::opaque_types_defined_by(db, def_id, &mut result);
2003
2004        // Collect coroutines.
2005        let (store, root_expr) = def_id.store_and_root_expr(db);
2006        // We can't just visit all exprs, since this may end up in unrelated anon consts.
2007        CoroutinesVisitor { db: self.db, owner: def_id, store, coroutines: &mut result }
2008            .on_expr(root_expr);
2009
2010        return SolverDefIds::new_from_slice(&result);
2011
2012        struct CoroutinesVisitor<'a, 'db> {
2013            db: &'db dyn HirDatabase,
2014            owner: InferBodyId<'db>,
2015            store: &'db ExpressionStore,
2016            coroutines: &'a mut Vec<SolverDefId<'db>>,
2017        }
2018
2019        impl<'db> StoreVisitor for CoroutinesVisitor<'_, 'db> {
2020            fn on_expr(&mut self, expr: ExprId) {
2021                if let hir_def::hir::Expr::Closure {
2022                    closure_kind:
2023                        kind @ (hir_def::hir::ClosureKind::Coroutine { .. }
2024                        | hir_def::hir::ClosureKind::OldCoroutine(_)),
2025                    ..
2026                } = self.store[expr]
2027                {
2028                    let coroutine = InternedCoroutineId::new(
2029                        self.db,
2030                        InternedClosure { owner: self.owner, expr, kind },
2031                    );
2032                    self.coroutines.push(coroutine.into());
2033                }
2034
2035                self.store.visit_expr_children(expr, self);
2036            }
2037            fn on_pat(&mut self, pat: PatId) {
2038                self.store.visit_pat_children(pat, self);
2039            }
2040            // Do not visit anon consts, they're separate bodies.
2041            fn on_anon_const_expr(&mut self, _expr: ExprId) {}
2042        }
2043    }
2044
2045    fn alias_has_const_conditions(self, _def_id: Self::DefId) -> bool {
2046        // FIXME(next-solver)
2047        false
2048    }
2049
2050    fn explicit_implied_const_bounds(
2051        self,
2052        _def_id: Self::DefId,
2053    ) -> EarlyBinder<
2054        Self,
2055        impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>,
2056    > {
2057        // FIXME(next-solver)
2058        EarlyBinder::bind([])
2059    }
2060
2061    fn fn_is_const(self, id: Self::FunctionId) -> bool {
2062        let id = match id.0 {
2063            CallableDefId::FunctionId(id) => id,
2064            _ => return false,
2065        };
2066        FunctionSignature::of(self.db(), id).flags.contains(FnFlags::CONST)
2067    }
2068
2069    fn impl_is_const(self, _def_id: Self::ImplId) -> bool {
2070        false
2071    }
2072
2073    fn opt_alias_variances(
2074        self,
2075        _kind: impl Into<AliasTermKind<'db>>,
2076    ) -> Option<Self::VariancesOf> {
2077        None
2078    }
2079
2080    fn type_of_opaque_hir_typeck(
2081        self,
2082        opaque: Self::LocalOpaqueTyId,
2083    ) -> EarlyBinder<Self, Self::Ty> {
2084        let impl_trait_id = opaque.0.loc(self.db);
2085        // The entry is missing when this call cycles back into the still-running inference
2086        // of the defining body, as the cycle fallback is an empty result.
2087        let hidden_type = match impl_trait_id {
2088            crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => {
2089                crate::opaques::rpit_hidden_types(self.db, func).get(idx)
2090            }
2091            crate::ImplTraitId::TypeAliasImplTrait(type_alias, idx) => {
2092                crate::opaques::tait_hidden_types(self.db, type_alias).get(idx)
2093            }
2094        };
2095        match hidden_type {
2096            Some(hidden_type) => hidden_type.get(),
2097            None => EarlyBinder::bind(Ty::new_error(self, ErrorGuaranteed)),
2098        }
2099    }
2100
2101    fn coroutine_hidden_types(
2102        self,
2103        _def_id: Self::CoroutineId,
2104    ) -> EarlyBinder<Self, Binder<'db, CoroutineWitnessTypes<Self>>> {
2105        // FIXME: Actually implement this.
2106        EarlyBinder::bind(Binder::dummy(CoroutineWitnessTypes {
2107            types: Tys::default(),
2108            assumptions: RegionAssumptions::default(),
2109        }))
2110    }
2111
2112    fn is_default_trait(self, def_id: Self::TraitId) -> bool {
2113        self.as_trait_lang_item(def_id).map_or(false, |l| matches!(l, SolverTraitLangItem::Sized))
2114    }
2115
2116    fn trait_is_coinductive(self, trait_: Self::TraitId) -> bool {
2117        TraitSignature::of(self.db(), trait_.0).flags.contains(TraitFlags::COINDUCTIVE)
2118    }
2119
2120    fn trait_is_unsafe(self, trait_: Self::TraitId) -> bool {
2121        TraitSignature::of(self.db(), trait_.0).flags.contains(TraitFlags::UNSAFE)
2122    }
2123
2124    fn impl_self_is_guaranteed_unsized(self, _def_id: Self::ImplId) -> bool {
2125        false
2126    }
2127
2128    fn impl_specializes(
2129        self,
2130        specializing_impl_def_id: Self::ImplId,
2131        parent_impl_def_id: Self::ImplId,
2132    ) -> bool {
2133        let (AnyImplId::ImplId(specializing_impl_def_id), AnyImplId::ImplId(parent_impl_def_id)) =
2134            (specializing_impl_def_id, parent_impl_def_id)
2135        else {
2136            // No builtin derive allow specialization currently.
2137            return false;
2138        };
2139        crate::specialization::specializes(self.db, specializing_impl_def_id, parent_impl_def_id)
2140    }
2141
2142    fn next_trait_solver_globally(self) -> bool {
2143        true
2144    }
2145
2146    type Probe = rustc_type_ir::solve::inspect::Probe<DbInterner<'db>>;
2147    fn mk_probe(self, probe: rustc_type_ir::solve::inspect::Probe<Self>) -> Self::Probe {
2148        probe
2149    }
2150    fn evaluate_root_goal_for_proof_tree_raw(
2151        self,
2152        canonical_goal: rustc_type_ir::solve::CanonicalInput<Self>,
2153    ) -> (rustc_type_ir::solve::QueryResult<Self>, Self::Probe) {
2154        rustc_next_trait_solver::solve::evaluate_root_goal_for_proof_tree_raw_provider::<
2155            SolverContext<'db>,
2156            Self,
2157        >(self, canonical_goal)
2158    }
2159
2160    fn is_sizedness_trait(self, def_id: Self::TraitId) -> bool {
2161        matches!(
2162            self.as_trait_lang_item(def_id),
2163            Some(SolverTraitLangItem::Sized | SolverTraitLangItem::MetaSized)
2164        )
2165    }
2166
2167    fn const_of_item(self, def_id: Self::DefId) -> rustc_type_ir::EarlyBinder<Self, Self::Const> {
2168        let id = match def_id {
2169            SolverDefId::StaticId(id) => id.into(),
2170            SolverDefId::ConstId(id) => id.into(),
2171            _ => unreachable!(),
2172        };
2173        EarlyBinder::bind(Const::new_unevaluated(
2174            self,
2175            UnevaluatedConst { def: GeneralConstIdWrapper(id), args: GenericArgs::empty(self) },
2176        ))
2177    }
2178
2179    fn anon_const_kind(self, _def_id: Self::DefId) -> rustc_type_ir::AnonConstKind {
2180        // FIXME
2181        rustc_type_ir::AnonConstKind::GCE
2182    }
2183
2184    fn alias_ty_kind_from_def_id(self, def_id: Self::DefId) -> AliasTyKind<'db> {
2185        match def_id {
2186            SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container {
2187                ItemContainerId::ExternBlockId(_) | ItemContainerId::ModuleId(_) => {
2188                    AliasTyKind::Free { def_id: type_alias.into() }
2189                }
2190                ItemContainerId::ImplId(_) => AliasTyKind::Inherent { def_id: type_alias.into() },
2191                ItemContainerId::TraitId(_) => {
2192                    AliasTyKind::Projection { def_id: type_alias.into() }
2193                }
2194            },
2195            SolverDefId::InternedOpaqueTyId(def_id) => {
2196                AliasTyKind::Opaque { def_id: def_id.into() }
2197            }
2198            _ => unreachable!(),
2199        }
2200    }
2201
2202    fn closure_is_const(self, _def_id: Self::ClosureId) -> bool {
2203        // FIXME
2204        false
2205    }
2206
2207    fn item_name(self, _item_index: Self::DefId) -> Self::Symbol {
2208        Symbol
2209    }
2210}
2211
2212fn is_ty_self(ty: Ty<'_>) -> bool {
2213    match ty.kind() {
2214        TyKind::Param(param) => param.index == 0,
2215        _ => false,
2216    }
2217}
2218fn is_clause_at_ty(p: &Clause<'_>, filter: impl FnOnce(Ty<'_>) -> bool) -> bool {
2219    match p.kind().skip_binder() {
2220        // rustc has the following assertion:
2221        // https://github.com/rust-lang/rust/blob/52618eb338609df44978b0ca4451ab7941fd1c7a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs#L525-L608
2222        ClauseKind::Trait(it) => filter(it.self_ty()),
2223        ClauseKind::TypeOutlives(it) => filter(it.0),
2224        ClauseKind::Projection(it) => filter(it.self_ty()),
2225        ClauseKind::HostEffect(it) => filter(it.self_ty()),
2226        _ => false,
2227    }
2228}
2229
2230impl<'db> DbInterner<'db> {
2231    pub fn shift_bound_var_indices<T>(self, bound_vars: usize, value: T) -> T
2232    where
2233        T: rustc_type_ir::TypeFoldable<Self>,
2234    {
2235        let shift_bv = |bv: BoundVar| BoundVar::from_usize(bv.as_usize() + bound_vars);
2236        self.replace_escaping_bound_vars_uncached(
2237            value,
2238            FnMutDelegate {
2239                regions: &mut |r: BoundRegion<'db>| {
2240                    Region::new_bound(
2241                        self,
2242                        DebruijnIndex::ZERO,
2243                        BoundRegion { var: shift_bv(r.var), kind: r.kind },
2244                    )
2245                },
2246                types: &mut |t: BoundTy<'db>| {
2247                    Ty::new_bound(
2248                        self,
2249                        DebruijnIndex::ZERO,
2250                        BoundTy { var: shift_bv(t.var), kind: t.kind },
2251                    )
2252                },
2253                consts: &mut |c| {
2254                    Const::new_bound(self, DebruijnIndex::ZERO, BoundConst::new(shift_bv(c.var)))
2255                },
2256            },
2257        )
2258    }
2259
2260    pub fn replace_escaping_bound_vars_uncached<T: rustc_type_ir::TypeFoldable<DbInterner<'db>>>(
2261        self,
2262        value: T,
2263        delegate: impl BoundVarReplacerDelegate<'db>,
2264    ) -> T {
2265        if !value.has_escaping_bound_vars() {
2266            value
2267        } else {
2268            let mut replacer = BoundVarReplacer::new(self, delegate);
2269            value.fold_with(&mut replacer)
2270        }
2271    }
2272
2273    pub fn replace_bound_vars_uncached<T: rustc_type_ir::TypeFoldable<DbInterner<'db>>>(
2274        self,
2275        value: Binder<'db, T>,
2276        delegate: impl BoundVarReplacerDelegate<'db>,
2277    ) -> T {
2278        self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate)
2279    }
2280
2281    // FIXME: add splat support when the experiment is complete
2282    pub fn mk_fn_sig<I>(
2283        self,
2284        inputs: I,
2285        output: Ty<'db>,
2286        c_variadic: bool,
2287        safety: Safety,
2288        abi: ExternAbi,
2289    ) -> FnSig<'db>
2290    where
2291        I: IntoIterator<Item = Ty<'db>>,
2292    {
2293        FnSig {
2294            inputs_and_output: Tys::new_from_iter(
2295                self,
2296                inputs.into_iter().chain(std::iter::once(output)),
2297            ),
2298            fn_sig_kind: FnSigKind::new(abi, safety, c_variadic),
2299        }
2300    }
2301
2302    /// `mk_fn_sig`, but with a safe Rust ABI, and no C-variadic argument.
2303    pub fn mk_fn_sig_safe_rust_abi<I>(self, inputs: I, output: Ty<'db>) -> FnSig<'db>
2304    where
2305        I: IntoIterator<Item = Ty<'db>>,
2306    {
2307        self.mk_fn_sig(inputs, output, false, Safety::Safe, ExternAbi::Rust)
2308    }
2309}
2310
2311fn predicates_of<'db>(
2312    db: &'db dyn HirDatabase,
2313    def_id: SolverDefId<'db>,
2314) -> &'db GenericPredicates {
2315    match def_id {
2316        SolverDefId::BuiltinDeriveImplId(impl_) => crate::builtin_derive::predicates(db, impl_),
2317        SolverDefId::AnonConstId(anon_const) => {
2318            let loc = anon_const.loc(db);
2319            if loc.allow_using_generic_params {
2320                GenericPredicates::query(db, loc.owner.generic_def(db))
2321            } else {
2322                GenericPredicates::empty()
2323            }
2324        }
2325        _ => GenericPredicates::query(db, def_id.try_into().unwrap()),
2326    }
2327}
2328
2329macro_rules! TrivialTypeTraversalImpls {
2330    ($($ty:ty,)+) => {
2331        $(
2332            impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for $ty {
2333                fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
2334                    self,
2335                    _: &mut F,
2336                ) -> ::std::result::Result<Self, F::Error> {
2337                    Ok(self)
2338                }
2339
2340                #[inline]
2341                fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(
2342                    self,
2343                    _: &mut F,
2344                ) -> Self {
2345                    self
2346                }
2347            }
2348
2349            impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for $ty {
2350                #[inline]
2351                fn visit_with<F: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
2352                    &self,
2353                    _: &mut F)
2354                    -> F::Result
2355                {
2356                    <F::Result as rustc_ast_ir::visit::VisitorResult>::output()
2357                }
2358            }
2359
2360            impl<V> rustc_type_ir::GenericTypeVisitable<V> for $ty {
2361                #[inline]
2362                fn generic_visit_with(&self, _visitor: &mut V) {}
2363            }
2364        )+
2365    };
2366}
2367
2368TrivialTypeTraversalImpls! {
2369    SolverDefId<'_>,
2370    TraitIdWrapper,
2371    TypeAliasIdWrapper,
2372    CallableIdWrapper,
2373    ClosureIdWrapper<'_>,
2374    CoroutineIdWrapper<'_>,
2375    CoroutineClosureIdWrapper<'_>,
2376    AdtIdWrapper,
2377    TraitAssocTyId,
2378    TraitAssocConstId,
2379    TraitAssocTermId,
2380    ImplOrTraitAssocTyId,
2381    ImplOrTraitAssocConstId,
2382    ImplOrTraitAssocTermId,
2383    FreeTyAliasId,
2384    FreeConstAliasId,
2385    FreeTermAliasId,
2386    InherentAssocTyId,
2387    InherentAssocConstId,
2388    InherentAssocTermId,
2389    OpaqueTyIdWrapper<'_>,
2390    AnyImplId,
2391    GeneralConstIdWrapper<'_>,
2392    Safety,
2393    Span,
2394    ParamConst,
2395    ParamTy,
2396    EarlyParamRegion,
2397    AdtDef,
2398    ScalarInt,
2399}
2400
2401mod tls_db {
2402    use std::{cell::Cell, ptr::NonNull};
2403
2404    use crate::db::HirDatabase;
2405
2406    struct Attached {
2407        database: Cell<Option<NonNull<dyn HirDatabase>>>,
2408    }
2409
2410    impl Attached {
2411        #[inline]
2412        fn attach<R>(&self, db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2413            struct DbGuard<'s> {
2414                state: Option<&'s Attached>,
2415            }
2416
2417            impl<'s> DbGuard<'s> {
2418                #[inline]
2419                fn new(attached: &'s Attached, db: &dyn HirDatabase) -> Self {
2420                    match attached.database.get() {
2421                        Some(current_db) => {
2422                            let new_db = NonNull::from(db);
2423                            if !std::ptr::addr_eq(current_db.as_ptr(), new_db.as_ptr()) {
2424                                panic!(
2425                                    "Cannot change attached database. This is likely a bug.\n\
2426                                    If this is not a bug, you can use `attach_db_allow_change()`."
2427                                );
2428                            }
2429                            Self { state: None }
2430                        }
2431                        None => {
2432                            // Otherwise, set the database.
2433                            attached.database.set(Some(NonNull::from(db)));
2434                            Self { state: Some(attached) }
2435                        }
2436                    }
2437                }
2438            }
2439
2440            impl Drop for DbGuard<'_> {
2441                #[inline]
2442                fn drop(&mut self) {
2443                    // Reset database to null if we did anything in `DbGuard::new`.
2444                    if let Some(attached) = self.state {
2445                        attached.database.set(None);
2446                    }
2447                }
2448            }
2449
2450            let _guard = DbGuard::new(self, db);
2451            super::tls_cache::reinit_cache(db);
2452            op()
2453        }
2454
2455        #[inline]
2456        fn attach_allow_change<R>(&self, db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2457            struct DbGuard<'s> {
2458                state: &'s Attached,
2459                prev: Option<NonNull<dyn HirDatabase>>,
2460            }
2461
2462            impl<'s> DbGuard<'s> {
2463                #[inline]
2464                fn new(attached: &'s Attached, db: &dyn HirDatabase) -> Self {
2465                    let prev = attached.database.replace(Some(NonNull::from(db)));
2466                    Self { state: attached, prev }
2467                }
2468            }
2469
2470            impl Drop for DbGuard<'_> {
2471                #[inline]
2472                fn drop(&mut self) {
2473                    self.state.database.set(self.prev);
2474                    if let Some(prev) = self.prev {
2475                        super::tls_cache::reinit_cache(unsafe { prev.as_ref() });
2476                    }
2477                }
2478            }
2479
2480            let _guard = DbGuard::new(self, db);
2481            super::tls_cache::reinit_cache(db);
2482            op()
2483        }
2484
2485        #[inline]
2486        fn with<R>(&self, op: impl FnOnce(&dyn HirDatabase) -> R) -> R {
2487            let db = self.database.get().expect("Try to use attached db, but not db is attached");
2488
2489            // SAFETY: The db is attached, so it must be valid.
2490            op(unsafe { db.as_ref() })
2491        }
2492    }
2493
2494    thread_local! {
2495        static GLOBAL_DB: Attached = const { Attached { database: Cell::new(None) } };
2496    }
2497
2498    #[inline]
2499    pub fn attach_db<R>(db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2500        GLOBAL_DB.with(|global_db| global_db.attach(db, op))
2501    }
2502
2503    #[inline]
2504    pub fn attach_db_allow_change<R>(db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2505        GLOBAL_DB.with(|global_db| global_db.attach_allow_change(db, op))
2506    }
2507
2508    #[inline]
2509    pub fn with_attached_db<R>(op: impl FnOnce(&dyn HirDatabase) -> R) -> R {
2510        GLOBAL_DB.with(
2511            #[inline]
2512            |a| a.with(op),
2513        )
2514    }
2515}
2516
2517mod tls_cache {
2518    use crate::db::HirDatabase;
2519
2520    use super::DbInterner;
2521    use base_db::Nonce;
2522    use rustc_type_ir::search_graph::GlobalCache;
2523    use salsa::Revision;
2524    use std::cell::RefCell;
2525
2526    struct Cache {
2527        cache: GlobalCache<DbInterner<'static>>,
2528        revision: Revision,
2529        db_nonce: Nonce,
2530    }
2531
2532    impl Cache {
2533        const fn default() -> Cache {
2534            Cache {
2535                cache: GlobalCache::new(),
2536                revision: Revision::max(),
2537                db_nonce: Nonce::invalid(),
2538            }
2539        }
2540    }
2541
2542    thread_local! {
2543        static GLOBAL_CACHE: RefCell<Cache> = const { RefCell::new(Cache::default()) };
2544    }
2545
2546    pub(super) fn reinit_cache(db: &dyn HirDatabase) {
2547        GLOBAL_CACHE.with_borrow_mut(|handle| {
2548            let (db_nonce, revision) = db.nonce_and_revision();
2549            if handle.revision != revision || db_nonce != handle.db_nonce {
2550                *handle = Cache { cache: GlobalCache::default(), revision, db_nonce };
2551            }
2552        })
2553    }
2554
2555    #[inline]
2556    pub(super) fn borrow_assume_valid<'db, T>(
2557        db: &'db dyn HirDatabase,
2558        f: impl FnOnce(&mut GlobalCache<DbInterner<'db>>) -> T,
2559    ) -> T {
2560        if cfg!(debug_assertions) {
2561            let get_state =
2562                || GLOBAL_CACHE.with_borrow(|handle| (handle.db_nonce, handle.revision));
2563            let old_state = get_state();
2564            reinit_cache(db);
2565            let new_state = get_state();
2566            assert_eq!(old_state, new_state, "you assumed the cache is valid!");
2567        }
2568
2569        GLOBAL_CACHE.with_borrow_mut(|handle| {
2570            // SAFETY: No idea
2571            f(unsafe {
2572                std::mem::transmute::<
2573                    &mut GlobalCache<DbInterner<'static>>,
2574                    &mut GlobalCache<DbInterner<'db>>,
2575                >(&mut handle.cache)
2576            })
2577        })
2578    }
2579
2580    /// Clears the thread-local trait solver cache.
2581    ///
2582    /// Should be called before getting memory usage estimations, as the solver cache
2583    /// is per-revision and usually should be excluded from estimations.
2584    pub fn clear_tls_solver_cache() {
2585        GLOBAL_CACHE.with_borrow_mut(|handle| *handle = Cache::default());
2586    }
2587}
2588
2589impl WorldExposer for intern::GarbageCollector {
2590    fn on_interned<T: intern::Internable>(
2591        &mut self,
2592        interned: InternedRef<'_, T>,
2593    ) -> ControlFlow<()> {
2594        self.mark_interned_alive(interned)
2595    }
2596
2597    fn on_interned_slice<T: intern::SliceInternable>(
2598        &mut self,
2599        interned: InternedSliceRef<'_, T>,
2600    ) -> ControlFlow<()> {
2601        self.mark_interned_slice_alive(interned)
2602    }
2603}
2604
2605/// # Safety
2606///
2607/// This cannot be called if there are some not-yet-recorded type values. Generally, if you have a mutable
2608/// reference to the database, and there are no other database - then you can call this safely, but you
2609/// also need to make sure to maintain the mutable reference while this is running.
2610pub unsafe fn collect_ty_garbage() {
2611    let mut gc = intern::GarbageCollector::default();
2612
2613    gc.add_storage::<super::consts::ConstInterned>();
2614    gc.add_storage::<super::consts::ValTreeInterned>();
2615    gc.add_storage::<super::allocation::AllocationInterned>();
2616    gc.add_storage::<PatternInterned>();
2617    gc.add_storage::<super::opaques::ExternalConstraintsInterned>();
2618    gc.add_storage::<super::predicate::PredicateInterned>();
2619    gc.add_storage::<super::region::RegionInterned>();
2620    gc.add_storage::<super::ty::TyInterned>();
2621
2622    gc.add_slice_storage::<super::consts::ConstsStorage>();
2623    gc.add_slice_storage::<super::predicate::ClausesStorage>();
2624    gc.add_slice_storage::<super::generic_arg::GenericArgsStorage>();
2625    gc.add_slice_storage::<BoundVarKindsStorage>();
2626    gc.add_slice_storage::<VariancesOfStorage>();
2627    gc.add_slice_storage::<CanonicalVarsStorage>();
2628    gc.add_slice_storage::<PatListStorage>();
2629    gc.add_slice_storage::<super::opaques::PredefinedOpaquesStorage>();
2630    gc.add_slice_storage::<super::opaques::SolverDefIdsStorage>();
2631    gc.add_slice_storage::<super::predicate::BoundExistentialPredicatesStorage>();
2632    gc.add_slice_storage::<super::region::RegionAssumptionsStorage>();
2633    gc.add_slice_storage::<super::ty::TysStorage>();
2634    gc.add_slice_storage::<crate::mir::ProjectionStorage>();
2635
2636    // SAFETY:
2637    //  - By our precondition, there are no unrecorded types.
2638    //  - We implement `GcInternedVisit` and `GcInternedSliceVisit` correctly for all types.
2639    //  - We added all storages (FIXME: it's too easy to forget to add a new storage here).
2640    unsafe { gc.collect() };
2641}
2642
2643macro_rules! impl_gc_visit {
2644    ( $($ty:ty),* $(,)? ) => {
2645        $(
2646            impl ::intern::GcInternedVisit for $ty {
2647                #[inline]
2648                fn visit_with(&self, gc: &mut ::intern::GarbageCollector) {
2649                    self.generic_visit_with(gc);
2650                }
2651            }
2652        )*
2653    };
2654}
2655
2656impl_gc_visit!(
2657    super::consts::ConstInterned,
2658    super::consts::ValTreeInterned,
2659    super::allocation::AllocationInterned,
2660    PatternInterned,
2661    super::opaques::ExternalConstraintsInterned,
2662    super::predicate::PredicateInterned,
2663    super::region::RegionInterned,
2664    super::ty::TyInterned,
2665    super::predicate::ClausesCachedTypeInfo,
2666);
2667
2668macro_rules! impl_gc_visit_slice {
2669    ( $($ty:ty),* $(,)? ) => {
2670        $(
2671            impl ::intern::GcInternedSliceVisit for $ty {
2672                #[inline]
2673                fn visit_header(header: &<Self as ::intern::SliceInternable>::Header, gc: &mut ::intern::GarbageCollector) {
2674                    header.generic_visit_with(gc);
2675                }
2676
2677                #[inline]
2678                fn visit_slice(slice: &[<Self as ::intern::SliceInternable>::SliceType], gc: &mut ::intern::GarbageCollector) {
2679                    slice.generic_visit_with(gc);
2680                }
2681            }
2682        )*
2683    };
2684}
2685
2686impl_gc_visit_slice!(
2687    super::predicate::ClausesStorage,
2688    super::generic_arg::GenericArgsStorage,
2689    BoundVarKindsStorage,
2690    VariancesOfStorage,
2691    CanonicalVarsStorage,
2692    PatListStorage,
2693    super::opaques::PredefinedOpaquesStorage,
2694    super::opaques::SolverDefIdsStorage,
2695    super::predicate::BoundExistentialPredicatesStorage,
2696    super::region::RegionAssumptionsStorage,
2697    super::ty::TysStorage,
2698    super::consts::ConstsStorage,
2699    crate::mir::ProjectionStorage,
2700);