hir_ty/next_solver/
interner.rs

1//! Things related to the Interner in the next-trait-solver.
2#![allow(unused)]
3
4use base_db::Crate;
5use chalk_ir::{ProgramClauseImplication, SeparatorTraitRef, Variances};
6use hir_def::lang_item::LangItem;
7use hir_def::signatures::{FieldData, FnFlags, ImplFlags, StructFlags, TraitFlags};
8use hir_def::{AdtId, BlockId, TypeAliasId, VariantId};
9use hir_def::{AttrDefId, Lookup};
10use hir_def::{CallableDefId, EnumVariantId, ItemContainerId, StructId, UnionId};
11use intern::sym::non_exhaustive;
12use intern::{Interned, impl_internable, sym};
13use la_arena::Idx;
14use rustc_abi::{Align, ReprFlags, ReprOptions};
15use rustc_hash::FxHashSet;
16use rustc_index::bit_set::DenseBitSet;
17use rustc_type_ir::elaborate::elaborate;
18use rustc_type_ir::error::TypeError;
19use rustc_type_ir::inherent::{
20    AdtDef as _, GenericArgs as _, GenericsOf, IntoKind, SliceLike as _, Span as _,
21};
22use rustc_type_ir::lang_items::TraitSolverLangItem;
23use rustc_type_ir::solve::SizedTraitKind;
24use rustc_type_ir::{
25    AliasTerm, AliasTermKind, AliasTy, AliasTyKind, EarlyBinder, FlagComputation, Flags,
26    ImplPolarity, InferTy, ProjectionPredicate, TraitPredicate, TraitRef, Upcast,
27};
28use salsa::plumbing::AsId;
29use smallvec::{SmallVec, smallvec};
30use std::fmt;
31use std::ops::ControlFlow;
32use syntax::ast::SelfParamKind;
33use triomphe::Arc;
34
35use rustc_ast_ir::visit::VisitorResult;
36use rustc_index::IndexVec;
37use rustc_type_ir::TypeVisitableExt;
38use rustc_type_ir::{
39    BoundVar, CollectAndApply, DebruijnIndex, GenericArgKind, RegionKind, TermKind, UniverseIndex,
40    Variance, WithCachedTypeInfo, elaborate,
41    inherent::{self, Const as _, Region as _, Ty as _},
42    ir_print, relate,
43};
44
45use crate::lower_nextsolver::{self, TyLoweringContext};
46use crate::method_resolution::{ALL_FLOAT_FPS, ALL_INT_FPS, TyFingerprint};
47use crate::next_solver::util::{ContainsTypeErrors, explicit_item_bounds, for_trait_impls};
48use crate::next_solver::{
49    CanonicalVarKind, FxIndexMap, InternedWrapperNoDebug, RegionAssumptions, SolverDefIds,
50};
51use crate::{ConstScalar, FnAbi, Interner, db::HirDatabase};
52
53use super::generics::generics;
54use super::util::sizedness_constraint_for_ty;
55use super::{
56    Binder, BoundExistentialPredicate, BoundExistentialPredicates, BoundTy, BoundTyKind, Clause,
57    Clauses, Const, ConstKind, ErrorGuaranteed, ExprConst, ExternalConstraints,
58    ExternalConstraintsData, GenericArg, GenericArgs, InternedClausesWrapper, ParamConst, ParamEnv,
59    ParamTy, PlaceholderConst, PlaceholderTy, PredefinedOpaques, PredefinedOpaquesData, Predicate,
60    PredicateKind, Term, Ty, TyKind, Tys, ValueConst,
61    abi::Safety,
62    fold::{BoundVarReplacer, BoundVarReplacerDelegate, FnMutDelegate},
63    generics::Generics,
64    mapping::ChalkToNextSolver,
65    region::{
66        BoundRegion, BoundRegionKind, EarlyParamRegion, LateParamRegion, PlaceholderRegion, Region,
67    },
68};
69use super::{ClauseKind, SolverDefId, Valtree};
70
71#[macro_export]
72#[doc(hidden)]
73macro_rules! _interned_vec_nolifetime_salsa {
74    ($name:ident, $ty:ty) => {
75        interned_vec_nolifetime_salsa!($name, $ty, nofold);
76
77        impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for $name {
78            fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
79                self,
80                folder: &mut F,
81            ) -> Result<Self, F::Error> {
82                use rustc_type_ir::inherent::SliceLike as _;
83                let inner: smallvec::SmallVec<[_; 2]> =
84                    self.iter().map(|v| v.try_fold_with(folder)).collect::<Result<_, _>>()?;
85                Ok($name::new_(folder.cx().db(), inner))
86            }
87            fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(
88                self,
89                folder: &mut F,
90            ) -> Self {
91                use rustc_type_ir::inherent::SliceLike as _;
92                let inner: smallvec::SmallVec<[_; 2]> =
93                    self.iter().map(|v| v.fold_with(folder)).collect();
94                $name::new_(folder.cx().db(), inner)
95            }
96        }
97
98        impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for $name {
99            fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
100                &self,
101                visitor: &mut V,
102            ) -> V::Result {
103                use rustc_ast_ir::visit::VisitorResult;
104                use rustc_type_ir::inherent::SliceLike as _;
105                rustc_ast_ir::walk_visitable_list!(visitor, self.as_slice().iter());
106                V::Result::output()
107            }
108        }
109    };
110    ($name:ident, $ty:ty, nofold) => {
111        #[salsa::interned(no_lifetime, constructor = new_, debug)]
112        pub struct $name {
113            #[returns(ref)]
114            inner_: smallvec::SmallVec<[$ty; 2]>,
115        }
116
117        impl $name {
118            pub fn new_from_iter<'db>(
119                interner: DbInterner<'db>,
120                data: impl IntoIterator<Item = $ty>,
121            ) -> Self {
122                $name::new_(interner.db(), data.into_iter().collect::<smallvec::SmallVec<[_; 2]>>())
123            }
124
125            pub fn inner(&self) -> &smallvec::SmallVec<[$ty; 2]> {
126                // SAFETY: ¯\_(ツ)_/¯
127                salsa::with_attached_database(|db| {
128                    let inner = self.inner_(db);
129                    unsafe { std::mem::transmute(inner) }
130                })
131                .unwrap()
132            }
133        }
134
135        impl rustc_type_ir::inherent::SliceLike for $name {
136            type Item = $ty;
137
138            type IntoIter = <smallvec::SmallVec<[$ty; 2]> as IntoIterator>::IntoIter;
139
140            fn iter(self) -> Self::IntoIter {
141                self.inner().clone().into_iter()
142            }
143
144            fn as_slice(&self) -> &[Self::Item] {
145                self.inner().as_slice()
146            }
147        }
148
149        impl IntoIterator for $name {
150            type Item = $ty;
151            type IntoIter = <Self as rustc_type_ir::inherent::SliceLike>::IntoIter;
152
153            fn into_iter(self) -> Self::IntoIter {
154                rustc_type_ir::inherent::SliceLike::iter(self)
155            }
156        }
157
158        impl Default for $name {
159            fn default() -> Self {
160                $name::new_from_iter(DbInterner::conjure(), [])
161            }
162        }
163    };
164}
165
166pub use crate::_interned_vec_nolifetime_salsa as interned_vec_nolifetime_salsa;
167
168#[macro_export]
169#[doc(hidden)]
170macro_rules! _interned_vec_db {
171    ($name:ident, $ty:ident) => {
172        interned_vec_db!($name, $ty, nofold);
173
174        impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for $name<'db> {
175            fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
176                self,
177                folder: &mut F,
178            ) -> Result<Self, F::Error> {
179                use rustc_type_ir::inherent::SliceLike as _;
180                let inner: smallvec::SmallVec<[_; 2]> =
181                    self.iter().map(|v| v.try_fold_with(folder)).collect::<Result<_, _>>()?;
182                Ok($name::new_(folder.cx().db(), inner))
183            }
184            fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(
185                self,
186                folder: &mut F,
187            ) -> Self {
188                use rustc_type_ir::inherent::SliceLike as _;
189                let inner: smallvec::SmallVec<[_; 2]> =
190                    self.iter().map(|v| v.fold_with(folder)).collect();
191                $name::new_(folder.cx().db(), inner)
192            }
193        }
194
195        impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for $name<'db> {
196            fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
197                &self,
198                visitor: &mut V,
199            ) -> V::Result {
200                use rustc_ast_ir::visit::VisitorResult;
201                use rustc_type_ir::inherent::SliceLike as _;
202                rustc_ast_ir::walk_visitable_list!(visitor, self.as_slice().iter());
203                V::Result::output()
204            }
205        }
206    };
207    ($name:ident, $ty:ident, nofold) => {
208        #[salsa::interned(constructor = new_)]
209        pub struct $name<'db> {
210            #[returns(ref)]
211            inner_: smallvec::SmallVec<[$ty<'db>; 2]>,
212        }
213
214        impl<'db> std::fmt::Debug for $name<'db> {
215            fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
216                self.as_slice().fmt(fmt)
217            }
218        }
219
220        impl<'db> $name<'db> {
221            pub fn new_from_iter(
222                interner: DbInterner<'db>,
223                data: impl IntoIterator<Item = $ty<'db>>,
224            ) -> Self {
225                $name::new_(interner.db(), data.into_iter().collect::<smallvec::SmallVec<[_; 2]>>())
226            }
227
228            pub fn inner(&self) -> &smallvec::SmallVec<[$ty<'db>; 2]> {
229                // SAFETY: ¯\_(ツ)_/¯
230                salsa::with_attached_database(|db| {
231                    let inner = self.inner_(db);
232                    unsafe { std::mem::transmute(inner) }
233                })
234                .unwrap()
235            }
236        }
237
238        impl<'db> rustc_type_ir::inherent::SliceLike for $name<'db> {
239            type Item = $ty<'db>;
240
241            type IntoIter = <smallvec::SmallVec<[$ty<'db>; 2]> as IntoIterator>::IntoIter;
242
243            fn iter(self) -> Self::IntoIter {
244                self.inner().clone().into_iter()
245            }
246
247            fn as_slice(&self) -> &[Self::Item] {
248                self.inner().as_slice()
249            }
250        }
251
252        impl<'db> IntoIterator for $name<'db> {
253            type Item = $ty<'db>;
254            type IntoIter = <Self as rustc_type_ir::inherent::SliceLike>::IntoIter;
255
256            fn into_iter(self) -> Self::IntoIter {
257                rustc_type_ir::inherent::SliceLike::iter(self)
258            }
259        }
260
261        impl<'db> Default for $name<'db> {
262            fn default() -> Self {
263                $name::new_from_iter(DbInterner::conjure(), [])
264            }
265        }
266    };
267}
268
269pub use crate::_interned_vec_db as interned_vec_db;
270
271#[derive(Debug, Copy, Clone)]
272pub struct DbInterner<'db> {
273    pub(crate) db: &'db dyn HirDatabase,
274    pub(crate) krate: Option<Crate>,
275    pub(crate) block: Option<BlockId>,
276}
277
278// FIXME: very wrong, see https://github.com/rust-lang/rust/pull/144808
279unsafe impl Send for DbInterner<'_> {}
280unsafe impl Sync for DbInterner<'_> {}
281
282impl<'db> DbInterner<'db> {
283    // FIXME(next-solver): remove this method
284    pub fn conjure() -> DbInterner<'db> {
285        salsa::with_attached_database(|db| DbInterner {
286            db: unsafe {
287                std::mem::transmute::<&dyn HirDatabase, &'db dyn HirDatabase>(db.as_view())
288            },
289            krate: None,
290            block: None,
291        })
292        .expect("db is expected to be attached")
293    }
294
295    pub fn new_with(
296        db: &'db dyn HirDatabase,
297        krate: Option<Crate>,
298        block: Option<BlockId>,
299    ) -> DbInterner<'db> {
300        DbInterner { db, krate, block }
301    }
302
303    pub fn db(&self) -> &'db dyn HirDatabase {
304        self.db
305    }
306}
307
308// This is intentionally left as `()`
309#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
310pub struct Span(());
311
312impl<'db> inherent::Span<DbInterner<'db>> for Span {
313    fn dummy() -> Self {
314        Span(())
315    }
316}
317
318interned_vec_nolifetime_salsa!(BoundVarKinds, BoundVarKind, nofold);
319
320#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
321pub enum BoundVarKind {
322    Ty(BoundTyKind),
323    Region(BoundRegionKind),
324    Const,
325}
326
327impl BoundVarKind {
328    pub fn expect_region(self) -> BoundRegionKind {
329        match self {
330            BoundVarKind::Region(lt) => lt,
331            _ => panic!("expected a region, but found another kind"),
332        }
333    }
334
335    pub fn expect_ty(self) -> BoundTyKind {
336        match self {
337            BoundVarKind::Ty(ty) => ty,
338            _ => panic!("expected a type, but found another kind"),
339        }
340    }
341
342    pub fn expect_const(self) {
343        match self {
344            BoundVarKind::Const => (),
345            _ => panic!("expected a const, but found another kind"),
346        }
347    }
348}
349
350interned_vec_db!(CanonicalVars, CanonicalVarKind, nofold);
351
352pub struct DepNodeIndex;
353
354#[derive(Debug)]
355pub struct Tracked<T: fmt::Debug + Clone>(T);
356
357#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
358pub struct Placeholder<T> {
359    pub universe: UniverseIndex,
360    pub bound: T,
361}
362
363impl<T: std::fmt::Debug> std::fmt::Debug for Placeholder<T> {
364    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
365        if self.universe == UniverseIndex::ROOT {
366            write!(f, "!{:?}", self.bound)
367        } else {
368            write!(f, "!{}_{:?}", self.universe.index(), self.bound)
369        }
370    }
371}
372
373#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
374pub struct AllocId;
375
376interned_vec_nolifetime_salsa!(VariancesOf, Variance, nofold);
377
378#[derive(Debug, Clone, Eq, PartialEq, Hash)]
379pub struct VariantIdx(usize);
380
381// FIXME: could/should store actual data?
382#[derive(Debug, Clone, Eq, PartialEq, Hash)]
383pub enum VariantDef {
384    Struct(StructId),
385    Union(UnionId),
386    Enum(EnumVariantId),
387}
388
389impl VariantDef {
390    pub fn id(&self) -> VariantId {
391        match self {
392            VariantDef::Struct(struct_id) => VariantId::StructId(*struct_id),
393            VariantDef::Union(union_id) => VariantId::UnionId(*union_id),
394            VariantDef::Enum(enum_variant_id) => VariantId::EnumVariantId(*enum_variant_id),
395        }
396    }
397
398    pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Idx<FieldData>, FieldData)> {
399        let id: VariantId = match self {
400            VariantDef::Struct(it) => (*it).into(),
401            VariantDef::Union(it) => (*it).into(),
402            VariantDef::Enum(it) => (*it).into(),
403        };
404        id.fields(db).fields().iter().map(|(id, data)| (id, data.clone())).collect()
405    }
406}
407
408/*
409/// Definition of a variant -- a struct's fields or an enum variant.
410#[derive(Debug, HashStable, TyEncodable, TyDecodable)]
411pub struct VariantDef {
412    /// `DefId` that identifies the variant itself.
413    /// If this variant belongs to a struct or union, then this is a copy of its `DefId`.
414    pub def_id: DefId,
415    /// `DefId` that identifies the variant's constructor.
416    /// If this variant is a struct variant, then this is `None`.
417    pub ctor: Option<(CtorKind, DefId)>,
418    /// Variant or struct name, maybe empty for anonymous adt (struct or union).
419    pub name: Symbol,
420    /// Discriminant of this variant.
421    pub discr: VariantDiscr,
422    /// Fields of this variant.
423    pub fields: IndexVec<FieldIdx, FieldDef>,
424    /// The error guarantees from parser, if any.
425    tainted: Option<ErrorGuaranteed>,
426    /// Flags of the variant (e.g. is field list non-exhaustive)?
427    flags: VariantFlags,
428}
429*/
430
431#[derive(Debug, Clone, Eq, PartialEq, Hash)]
432pub struct AdtFlags {
433    is_enum: bool,
434    is_union: bool,
435    is_struct: bool,
436    is_phantom_data: bool,
437    is_fundamental: bool,
438    is_box: bool,
439    is_manually_drop: bool,
440}
441
442#[derive(Debug, Clone, PartialEq, Eq)]
443pub struct AdtDefInner {
444    pub id: AdtId,
445    variants: Vec<(VariantIdx, VariantDef)>,
446    flags: AdtFlags,
447    repr: ReprOptions,
448}
449
450// We're gonna cheat a little bit and implement `Hash` on only the `DefId` and
451// accept there might be collisions for def ids from different crates (or across
452// different tests, oh my).
453impl std::hash::Hash for AdtDefInner {
454    #[inline]
455    fn hash<H: std::hash::Hasher>(&self, s: &mut H) {
456        self.id.hash(s)
457    }
458}
459
460#[salsa::interned(no_lifetime, constructor = new_)]
461pub struct AdtDef {
462    #[returns(ref)]
463    data_: AdtDefInner,
464}
465
466impl AdtDef {
467    pub fn new<'db>(def_id: AdtId, interner: DbInterner<'db>) -> Self {
468        let db = interner.db();
469        let (flags, variants, repr) = match def_id {
470            AdtId::StructId(struct_id) => {
471                let data = db.struct_signature(struct_id);
472
473                let flags = AdtFlags {
474                    is_enum: false,
475                    is_union: false,
476                    is_struct: true,
477                    is_phantom_data: data.flags.contains(StructFlags::IS_PHANTOM_DATA),
478                    is_fundamental: data.flags.contains(StructFlags::FUNDAMENTAL),
479                    is_box: data.flags.contains(StructFlags::IS_BOX),
480                    is_manually_drop: data.flags.contains(StructFlags::IS_MANUALLY_DROP),
481                };
482
483                let variants = vec![(VariantIdx(0), VariantDef::Struct(struct_id))];
484
485                let mut repr = ReprOptions::default();
486                repr.align = data.repr.and_then(|r| r.align);
487                repr.pack = data.repr.and_then(|r| r.pack);
488                repr.int = data.repr.and_then(|r| r.int);
489
490                let mut repr_flags = ReprFlags::empty();
491                if flags.is_box {
492                    repr_flags.insert(ReprFlags::IS_LINEAR);
493                }
494                if data.repr.is_some_and(|r| r.c()) {
495                    repr_flags.insert(ReprFlags::IS_C);
496                }
497                if data.repr.is_some_and(|r| r.simd()) {
498                    repr_flags.insert(ReprFlags::IS_SIMD);
499                }
500                repr.flags = repr_flags;
501
502                (flags, variants, repr)
503            }
504            AdtId::UnionId(union_id) => {
505                let data = db.union_signature(union_id);
506
507                let flags = AdtFlags {
508                    is_enum: false,
509                    is_union: true,
510                    is_struct: false,
511                    is_phantom_data: false,
512                    is_fundamental: false,
513                    is_box: false,
514                    is_manually_drop: false,
515                };
516
517                let variants = vec![(VariantIdx(0), VariantDef::Union(union_id))];
518
519                let mut repr = ReprOptions::default();
520                repr.align = data.repr.and_then(|r| r.align);
521                repr.pack = data.repr.and_then(|r| r.pack);
522                repr.int = data.repr.and_then(|r| r.int);
523
524                let mut repr_flags = ReprFlags::empty();
525                if flags.is_box {
526                    repr_flags.insert(ReprFlags::IS_LINEAR);
527                }
528                if data.repr.is_some_and(|r| r.c()) {
529                    repr_flags.insert(ReprFlags::IS_C);
530                }
531                if data.repr.is_some_and(|r| r.simd()) {
532                    repr_flags.insert(ReprFlags::IS_SIMD);
533                }
534                repr.flags = repr_flags;
535
536                (flags, variants, repr)
537            }
538            AdtId::EnumId(enum_id) => {
539                let flags = AdtFlags {
540                    is_enum: true,
541                    is_union: false,
542                    is_struct: false,
543                    is_phantom_data: false,
544                    is_fundamental: false,
545                    is_box: false,
546                    is_manually_drop: false,
547                };
548
549                let variants = enum_id
550                    .enum_variants(db)
551                    .variants
552                    .iter()
553                    .enumerate()
554                    .map(|(idx, v)| (VariantIdx(idx), v))
555                    .map(|(idx, v)| (idx, VariantDef::Enum(v.0)))
556                    .collect();
557
558                let data = db.enum_signature(enum_id);
559
560                let mut repr = ReprOptions::default();
561                repr.align = data.repr.and_then(|r| r.align);
562                repr.pack = data.repr.and_then(|r| r.pack);
563                repr.int = data.repr.and_then(|r| r.int);
564
565                let mut repr_flags = ReprFlags::empty();
566                if flags.is_box {
567                    repr_flags.insert(ReprFlags::IS_LINEAR);
568                }
569                if data.repr.is_some_and(|r| r.c()) {
570                    repr_flags.insert(ReprFlags::IS_C);
571                }
572                if data.repr.is_some_and(|r| r.simd()) {
573                    repr_flags.insert(ReprFlags::IS_SIMD);
574                }
575                repr.flags = repr_flags;
576
577                (flags, variants, repr)
578            }
579        };
580
581        AdtDef::new_(db, AdtDefInner { id: def_id, variants, flags, repr })
582    }
583
584    pub fn inner(&self) -> &AdtDefInner {
585        salsa::with_attached_database(|db| {
586            let inner = self.data_(db);
587            // SAFETY: ¯\_(ツ)_/¯
588            unsafe { std::mem::transmute(inner) }
589        })
590        .unwrap()
591    }
592
593    pub fn is_enum(&self) -> bool {
594        self.inner().flags.is_enum
595    }
596
597    #[inline]
598    pub fn repr(self) -> ReprOptions {
599        self.inner().repr
600    }
601
602    /// Asserts this is a struct or union and returns its unique variant.
603    pub fn non_enum_variant(self) -> VariantDef {
604        assert!(self.inner().flags.is_struct || self.inner().flags.is_union);
605        self.inner().variants[0].1.clone()
606    }
607}
608
609impl<'db> inherent::AdtDef<DbInterner<'db>> for AdtDef {
610    fn def_id(self) -> <DbInterner<'db> as rustc_type_ir::Interner>::DefId {
611        SolverDefId::AdtId(self.inner().id)
612    }
613
614    fn is_struct(self) -> bool {
615        self.inner().flags.is_struct
616    }
617
618    fn is_phantom_data(self) -> bool {
619        self.inner().flags.is_phantom_data
620    }
621
622    fn is_fundamental(self) -> bool {
623        self.inner().flags.is_fundamental
624    }
625
626    fn struct_tail_ty(
627        self,
628        interner: DbInterner<'db>,
629    ) -> Option<EarlyBinder<DbInterner<'db>, Ty<'db>>> {
630        let db = interner.db();
631        let hir_def::AdtId::StructId(struct_id) = self.inner().id else {
632            return None;
633        };
634        let id: VariantId = struct_id.into();
635        let field_types = interner.db().field_types_ns(id);
636
637        field_types.iter().last().map(|f| *f.1)
638    }
639
640    fn all_field_tys(
641        self,
642        interner: DbInterner<'db>,
643    ) -> EarlyBinder<DbInterner<'db>, impl IntoIterator<Item = Ty<'db>>> {
644        let db = interner.db();
645        // FIXME: this is disabled just to match the behavior with chalk right now
646        let field_tys = |id: VariantId| {
647            let variant_data = id.fields(db);
648            let fields = if variant_data.fields().is_empty() {
649                vec![]
650            } else {
651                let field_types = db.field_types_ns(id);
652                variant_data
653                    .fields()
654                    .iter()
655                    .map(|(idx, _)| {
656                        let ty = field_types[idx];
657                        ty.skip_binder()
658                    })
659                    .collect()
660            };
661        };
662        let field_tys = |id: VariantId| vec![];
663        let tys: Vec<_> = match self.inner().id {
664            hir_def::AdtId::StructId(id) => field_tys(id.into()),
665            hir_def::AdtId::UnionId(id) => field_tys(id.into()),
666            hir_def::AdtId::EnumId(id) => id
667                .enum_variants(db)
668                .variants
669                .iter()
670                .flat_map(|&(variant_id, _, _)| field_tys(variant_id.into()))
671                .collect(),
672        };
673
674        EarlyBinder::bind(tys)
675    }
676
677    fn sizedness_constraint(
678        self,
679        interner: DbInterner<'db>,
680        sizedness: SizedTraitKind,
681    ) -> Option<EarlyBinder<DbInterner<'db>, Ty<'db>>> {
682        if self.is_struct() {
683            let tail_ty = self.all_field_tys(interner).skip_binder().into_iter().last()?;
684
685            let constraint_ty = sizedness_constraint_for_ty(interner, sizedness, tail_ty)?;
686
687            Some(EarlyBinder::bind(constraint_ty))
688        } else {
689            None
690        }
691    }
692
693    fn destructor(
694        self,
695        interner: DbInterner<'db>,
696    ) -> Option<rustc_type_ir::solve::AdtDestructorKind> {
697        // FIXME(next-solver)
698        None
699    }
700
701    fn is_manually_drop(self) -> bool {
702        self.inner().flags.is_manually_drop
703    }
704}
705
706impl fmt::Debug for AdtDef {
707    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
708        salsa::with_attached_database(|db| match self.inner().id {
709            AdtId::StructId(struct_id) => {
710                let data = db.as_view::<dyn HirDatabase>().struct_signature(struct_id);
711                f.write_str(data.name.as_str())
712            }
713            AdtId::UnionId(union_id) => {
714                let data = db.as_view::<dyn HirDatabase>().union_signature(union_id);
715                f.write_str(data.name.as_str())
716            }
717            AdtId::EnumId(enum_id) => {
718                let data = db.as_view::<dyn HirDatabase>().enum_signature(enum_id);
719                f.write_str(data.name.as_str())
720            }
721        })
722        .unwrap_or_else(|| f.write_str(&format!("AdtDef({:?})", self.inner().id)))
723    }
724}
725
726#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
727pub struct Features;
728
729impl<'db> inherent::Features<DbInterner<'db>> for Features {
730    fn generic_const_exprs(self) -> bool {
731        false
732    }
733
734    fn coroutine_clone(self) -> bool {
735        false
736    }
737
738    fn associated_const_equality(self) -> bool {
739        false
740    }
741
742    fn feature_bound_holds_in_crate(self, symbol: ()) -> bool {
743        false
744    }
745}
746
747#[derive(Debug, Clone, Eq, PartialEq, Hash)]
748pub struct UnsizingParams(pub(crate) DenseBitSet<u32>);
749
750impl std::ops::Deref for UnsizingParams {
751    type Target = DenseBitSet<u32>;
752
753    fn deref(&self) -> &Self::Target {
754        &self.0
755    }
756}
757
758pub type PatternKind<'db> = rustc_type_ir::PatternKind<DbInterner<'db>>;
759
760#[salsa::interned(constructor = new_, debug)]
761pub struct Pattern<'db> {
762    #[returns(ref)]
763    kind_: InternedWrapperNoDebug<PatternKind<'db>>,
764}
765
766impl<'db> std::fmt::Debug for InternedWrapperNoDebug<PatternKind<'db>> {
767    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
768        self.0.fmt(f)
769    }
770}
771
772impl<'db> Pattern<'db> {
773    pub fn new(interner: DbInterner<'db>, kind: PatternKind<'db>) -> Self {
774        Pattern::new_(interner.db(), InternedWrapperNoDebug(kind))
775    }
776
777    pub fn inner(&self) -> &PatternKind<'db> {
778        salsa::with_attached_database(|db| {
779            let inner = &self.kind_(db).0;
780            // SAFETY: The caller already has access to a `Ty<'db>`, so borrowchecking will
781            // make sure that our returned value is valid for the lifetime `'db`.
782            unsafe { std::mem::transmute(inner) }
783        })
784        .unwrap()
785    }
786}
787
788impl<'db> Flags for Pattern<'db> {
789    fn flags(&self) -> rustc_type_ir::TypeFlags {
790        match self.inner() {
791            PatternKind::Range { start, end } => {
792                FlagComputation::for_const_kind(&start.kind()).flags
793                    | FlagComputation::for_const_kind(&end.kind()).flags
794            }
795            PatternKind::Or(pats) => {
796                let mut flags = pats.as_slice()[0].flags();
797                for pat in pats.as_slice()[1..].iter() {
798                    flags |= pat.flags();
799                }
800                flags
801            }
802        }
803    }
804
805    fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex {
806        match self.inner() {
807            PatternKind::Range { start, end } => {
808                start.outer_exclusive_binder().max(end.outer_exclusive_binder())
809            }
810            PatternKind::Or(pats) => {
811                let mut idx = pats.as_slice()[0].outer_exclusive_binder();
812                for pat in pats.as_slice()[1..].iter() {
813                    idx = idx.max(pat.outer_exclusive_binder());
814                }
815                idx
816            }
817        }
818    }
819}
820
821impl<'db> rustc_type_ir::inherent::IntoKind for Pattern<'db> {
822    type Kind = rustc_type_ir::PatternKind<DbInterner<'db>>;
823    fn kind(self) -> Self::Kind {
824        *self.inner()
825    }
826}
827
828impl<'db> rustc_type_ir::relate::Relate<DbInterner<'db>> for Pattern<'db> {
829    fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>(
830        relation: &mut R,
831        a: Self,
832        b: Self,
833    ) -> rustc_type_ir::relate::RelateResult<DbInterner<'db>, Self> {
834        let tcx = relation.cx();
835        match (a.kind(), b.kind()) {
836            (
837                PatternKind::Range { start: start_a, end: end_a },
838                PatternKind::Range { start: start_b, end: end_b },
839            ) => {
840                let start = relation.relate(start_a, start_b)?;
841                let end = relation.relate(end_a, end_b)?;
842                Ok(Pattern::new(tcx, PatternKind::Range { start, end }))
843            }
844            (PatternKind::Or(a), PatternKind::Or(b)) => {
845                if a.len() != b.len() {
846                    return Err(TypeError::Mismatch);
847                }
848                let pats = CollectAndApply::collect_and_apply(
849                    std::iter::zip(a.iter(), b.iter()).map(|(a, b)| relation.relate(a, b)),
850                    |g| PatList::new_from_iter(tcx, g.iter().cloned()),
851                )?;
852                Ok(Pattern::new(tcx, PatternKind::Or(pats)))
853            }
854            (PatternKind::Range { .. } | PatternKind::Or(_), _) => Err(TypeError::Mismatch),
855        }
856    }
857}
858
859interned_vec_db!(PatList, Pattern);
860
861impl<'db> rustc_type_ir::Interner for DbInterner<'db> {
862    type DefId = SolverDefId;
863    type LocalDefId = SolverDefId;
864    type LocalDefIds = SolverDefIds;
865    type Span = Span;
866
867    type GenericArgs = GenericArgs<'db>;
868    type GenericArgsSlice = GenericArgs<'db>;
869    type GenericArg = GenericArg<'db>;
870
871    type Term = Term<'db>;
872
873    type BoundVarKinds = BoundVarKinds;
874    type BoundVarKind = BoundVarKind;
875
876    type PredefinedOpaques = PredefinedOpaques<'db>;
877
878    fn mk_predefined_opaques_in_body(
879        self,
880        data: rustc_type_ir::solve::PredefinedOpaquesData<Self>,
881    ) -> Self::PredefinedOpaques {
882        PredefinedOpaques::new(self, data)
883    }
884
885    type CanonicalVarKinds = CanonicalVars<'db>;
886
887    fn mk_canonical_var_kinds(
888        self,
889        kinds: &[rustc_type_ir::CanonicalVarKind<Self>],
890    ) -> Self::CanonicalVarKinds {
891        CanonicalVars::new_from_iter(self, kinds.iter().cloned())
892    }
893
894    type ExternalConstraints = ExternalConstraints<'db>;
895
896    fn mk_external_constraints(
897        self,
898        data: rustc_type_ir::solve::ExternalConstraintsData<Self>,
899    ) -> Self::ExternalConstraints {
900        ExternalConstraints::new(self, data)
901    }
902
903    type DepNodeIndex = DepNodeIndex;
904
905    type Tracked<T: fmt::Debug + Clone> = Tracked<T>;
906
907    type Ty = Ty<'db>;
908    type Tys = Tys<'db>;
909    type FnInputTys = Tys<'db>;
910    type ParamTy = ParamTy;
911    type BoundTy = BoundTy;
912    type PlaceholderTy = PlaceholderTy;
913    type Symbol = ();
914
915    type ErrorGuaranteed = ErrorGuaranteed;
916    type BoundExistentialPredicates = BoundExistentialPredicates<'db>;
917    type AllocId = AllocId;
918    type Pat = Pattern<'db>;
919    type PatList = PatList<'db>;
920    type Safety = Safety;
921    type Abi = FnAbi;
922
923    type Const = Const<'db>;
924    type PlaceholderConst = PlaceholderConst;
925    type ParamConst = ParamConst;
926    type BoundConst = rustc_type_ir::BoundVar;
927    type ValueConst = ValueConst<'db>;
928    type ValTree = Valtree<'db>;
929    type ExprConst = ExprConst;
930
931    type Region = Region<'db>;
932    type EarlyParamRegion = EarlyParamRegion;
933    type LateParamRegion = LateParamRegion;
934    type BoundRegion = BoundRegion;
935    type PlaceholderRegion = PlaceholderRegion;
936
937    type RegionAssumptions = RegionAssumptions<'db>;
938
939    type ParamEnv = ParamEnv<'db>;
940    type Predicate = Predicate<'db>;
941    type Clause = Clause<'db>;
942    type Clauses = Clauses<'db>;
943
944    type GenericsOf = Generics;
945
946    type VariancesOf = VariancesOf;
947
948    type AdtDef = AdtDef;
949
950    type Features = Features;
951
952    fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs {
953        GenericArgs::new_from_iter(self, args.iter().cloned())
954    }
955
956    fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
957    where
958        I: Iterator<Item = T>,
959        T: rustc_type_ir::CollectAndApply<Self::GenericArg, Self::GenericArgs>,
960    {
961        CollectAndApply::collect_and_apply(args, |g| {
962            GenericArgs::new_from_iter(self, g.iter().cloned())
963        })
964    }
965
966    type UnsizingParams = UnsizingParams;
967
968    fn mk_tracked<T: fmt::Debug + Clone>(
969        self,
970        data: T,
971        dep_node: Self::DepNodeIndex,
972    ) -> Self::Tracked<T> {
973        Tracked(data)
974    }
975
976    fn get_tracked<T: fmt::Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T {
977        tracked.0.clone()
978    }
979
980    fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, Self::DepNodeIndex) {
981        (task(), DepNodeIndex)
982    }
983
984    fn with_global_cache<R>(
985        self,
986        f: impl FnOnce(&mut rustc_type_ir::search_graph::GlobalCache<Self>) -> R,
987    ) -> R {
988        salsa::with_attached_database(|db| {
989            tls_cache::with_cache(
990                unsafe {
991                    std::mem::transmute::<&dyn HirDatabase, &'db dyn HirDatabase>(
992                        db.as_view::<dyn HirDatabase>(),
993                    )
994                },
995                f,
996            )
997        })
998        .unwrap()
999    }
1000
1001    fn canonical_param_env_cache_get_or_insert<R>(
1002        self,
1003        param_env: Self::ParamEnv,
1004        f: impl FnOnce() -> rustc_type_ir::CanonicalParamEnvCacheEntry<Self>,
1005        from_entry: impl FnOnce(&rustc_type_ir::CanonicalParamEnvCacheEntry<Self>) -> R,
1006    ) -> R {
1007        from_entry(&f())
1008    }
1009
1010    fn evaluation_is_concurrent(&self) -> bool {
1011        false
1012    }
1013
1014    fn expand_abstract_consts<T: rustc_type_ir::TypeFoldable<Self>>(self, _: T) -> T {
1015        unreachable!("only used by the old trait solver in rustc");
1016    }
1017
1018    fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf {
1019        generics(self.db(), def_id)
1020    }
1021
1022    fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf {
1023        match def_id {
1024            SolverDefId::FunctionId(def_id) => VariancesOf::new_from_iter(
1025                self,
1026                self.db()
1027                    .variances_of(hir_def::GenericDefId::FunctionId(def_id))
1028                    .as_deref()
1029                    .unwrap_or_default()
1030                    .iter()
1031                    .map(|v| v.to_nextsolver(self)),
1032            ),
1033            SolverDefId::AdtId(def_id) => VariancesOf::new_from_iter(
1034                self,
1035                self.db()
1036                    .variances_of(hir_def::GenericDefId::AdtId(def_id))
1037                    .as_deref()
1038                    .unwrap_or_default()
1039                    .iter()
1040                    .map(|v| v.to_nextsolver(self)),
1041            ),
1042            SolverDefId::InternedOpaqueTyId(_def_id) => {
1043                // FIXME(next-solver): track variances
1044                //
1045                // We compute them based on the only `Ty` level info in rustc,
1046                // move `variances_of_opaque` into `rustc_next_trait_solver` for reuse.
1047                VariancesOf::new_from_iter(
1048                    self,
1049                    (0..self.generics_of(def_id).count()).map(|_| Variance::Invariant),
1050                )
1051            }
1052            _ => VariancesOf::new_from_iter(self, []),
1053        }
1054    }
1055
1056    fn type_of(self, def_id: Self::DefId) -> EarlyBinder<Self, Self::Ty> {
1057        let def_id = match def_id {
1058            SolverDefId::TypeAliasId(id) => {
1059                use hir_def::Lookup;
1060                match id.lookup(self.db()).container {
1061                    ItemContainerId::ImplId(it) => it,
1062                    _ => panic!("assoc ty value should be in impl"),
1063                };
1064                crate::TyDefId::TypeAliasId(id)
1065            }
1066            SolverDefId::AdtId(id) => crate::TyDefId::AdtId(id),
1067            // FIXME(next-solver): This uses the types of `query mir_borrowck` in rustc.
1068            //
1069            // We currently always use the type from HIR typeck which ignores regions. This
1070            // should be fine.
1071            SolverDefId::InternedOpaqueTyId(_) => {
1072                return self.type_of_opaque_hir_typeck(def_id);
1073            }
1074            _ => panic!("Unexpected def_id `{def_id:?}` provided for `type_of`"),
1075        };
1076        self.db().ty_ns(def_id)
1077    }
1078
1079    fn adt_def(self, adt_def_id: Self::DefId) -> Self::AdtDef {
1080        let def_id = match adt_def_id {
1081            SolverDefId::AdtId(adt_id) => adt_id,
1082            _ => panic!("Invalid DefId passed to adt_def"),
1083        };
1084        AdtDef::new(def_id, self)
1085    }
1086
1087    fn alias_ty_kind(self, alias: rustc_type_ir::AliasTy<Self>) -> AliasTyKind {
1088        match alias.def_id {
1089            SolverDefId::InternedOpaqueTyId(_) => AliasTyKind::Opaque,
1090            SolverDefId::TypeAliasId(_) => AliasTyKind::Projection,
1091            _ => unimplemented!("Unexpected alias: {:?}", alias.def_id),
1092        }
1093    }
1094
1095    fn alias_term_kind(
1096        self,
1097        alias: rustc_type_ir::AliasTerm<Self>,
1098    ) -> rustc_type_ir::AliasTermKind {
1099        match alias.def_id {
1100            SolverDefId::InternedOpaqueTyId(_) => AliasTermKind::OpaqueTy,
1101            SolverDefId::TypeAliasId(_) => AliasTermKind::ProjectionTy,
1102            SolverDefId::ConstId(_) => AliasTermKind::UnevaluatedConst,
1103            _ => unimplemented!("Unexpected alias: {:?}", alias.def_id),
1104        }
1105    }
1106
1107    fn trait_ref_and_own_args_for_alias(
1108        self,
1109        def_id: Self::DefId,
1110        args: Self::GenericArgs,
1111    ) -> (rustc_type_ir::TraitRef<Self>, Self::GenericArgsSlice) {
1112        let trait_def_id = self.parent(def_id);
1113        let trait_generics = self.generics_of(trait_def_id);
1114        let trait_args = GenericArgs::new_from_iter(
1115            self,
1116            args.as_slice()[0..trait_generics.own_params.len()].iter().cloned(),
1117        );
1118        let alias_args =
1119            GenericArgs::new_from_iter(self, args.iter().skip(trait_generics.own_params.len()));
1120        (TraitRef::new_from_args(self, trait_def_id, trait_args), alias_args)
1121    }
1122
1123    fn check_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs) -> bool {
1124        // FIXME
1125        true
1126    }
1127
1128    fn debug_assert_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs) {}
1129
1130    fn debug_assert_existential_args_compatible(
1131        self,
1132        def_id: Self::DefId,
1133        args: Self::GenericArgs,
1134    ) {
1135    }
1136
1137    fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
1138    where
1139        I: Iterator<Item = T>,
1140        T: rustc_type_ir::CollectAndApply<Self::Ty, Self::Tys>,
1141    {
1142        CollectAndApply::collect_and_apply(args, |g| Tys::new_from_iter(self, g.iter().cloned()))
1143    }
1144
1145    fn parent(self, def_id: Self::DefId) -> Self::DefId {
1146        use hir_def::Lookup;
1147
1148        let container = match def_id {
1149            SolverDefId::FunctionId(it) => it.lookup(self.db()).container,
1150            SolverDefId::TypeAliasId(it) => it.lookup(self.db()).container,
1151            SolverDefId::ConstId(it) => it.lookup(self.db()).container,
1152            SolverDefId::InternedClosureId(it) => {
1153                return self
1154                    .db()
1155                    .lookup_intern_closure(it)
1156                    .0
1157                    .as_generic_def_id(self.db())
1158                    .unwrap()
1159                    .into();
1160            }
1161            SolverDefId::InternedCoroutineId(it) => {
1162                return self
1163                    .db()
1164                    .lookup_intern_coroutine(it)
1165                    .0
1166                    .as_generic_def_id(self.db())
1167                    .unwrap()
1168                    .into();
1169            }
1170            SolverDefId::StaticId(_)
1171            | SolverDefId::AdtId(_)
1172            | SolverDefId::TraitId(_)
1173            | SolverDefId::ImplId(_)
1174            | SolverDefId::Ctor(..)
1175            | SolverDefId::InternedOpaqueTyId(..) => panic!(),
1176        };
1177
1178        match container {
1179            ItemContainerId::ImplId(it) => it.into(),
1180            ItemContainerId::TraitId(it) => it.into(),
1181            ItemContainerId::ModuleId(_) | ItemContainerId::ExternBlockId(_) => panic!(),
1182        }
1183    }
1184
1185    fn recursion_limit(self) -> usize {
1186        50
1187    }
1188
1189    fn features(self) -> Self::Features {
1190        Features
1191    }
1192
1193    fn fn_sig(
1194        self,
1195        def_id: Self::DefId,
1196    ) -> EarlyBinder<Self, rustc_type_ir::Binder<Self, rustc_type_ir::FnSig<Self>>> {
1197        let id = match def_id {
1198            SolverDefId::FunctionId(id) => CallableDefId::FunctionId(id),
1199            SolverDefId::Ctor(ctor) => match ctor {
1200                super::Ctor::Struct(struct_id) => CallableDefId::StructId(struct_id),
1201                super::Ctor::Enum(enum_variant_id) => CallableDefId::EnumVariantId(enum_variant_id),
1202            },
1203            def => unreachable!("{:?}", def),
1204        };
1205        self.db().callable_item_signature_ns(id)
1206    }
1207
1208    fn coroutine_movability(self, def_id: Self::DefId) -> rustc_ast_ir::Movability {
1209        unimplemented!()
1210    }
1211
1212    fn coroutine_for_closure(self, def_id: Self::DefId) -> Self::DefId {
1213        unimplemented!()
1214    }
1215
1216    fn generics_require_sized_self(self, def_id: Self::DefId) -> bool {
1217        let sized_trait =
1218            LangItem::Sized.resolve_trait(self.db(), self.krate.expect("Must have self.krate"));
1219        let Some(sized_id) = sized_trait else {
1220            return false; /* No Sized trait, can't require it! */
1221        };
1222        let sized_def_id = sized_id.into();
1223
1224        // Search for a predicate like `Self : Sized` amongst the trait bounds.
1225        let predicates = self.predicates_of(def_id);
1226        elaborate(self, predicates.iter_identity()).any(|pred| match pred.kind().skip_binder() {
1227            ClauseKind::Trait(ref trait_pred) => {
1228                trait_pred.def_id() == sized_def_id
1229                    && matches!(
1230                        trait_pred.self_ty().kind(),
1231                        TyKind::Param(ParamTy { index: 0, .. })
1232                    )
1233            }
1234            ClauseKind::RegionOutlives(_)
1235            | ClauseKind::TypeOutlives(_)
1236            | ClauseKind::Projection(_)
1237            | ClauseKind::ConstArgHasType(_, _)
1238            | ClauseKind::WellFormed(_)
1239            | ClauseKind::ConstEvaluatable(_)
1240            | ClauseKind::HostEffect(..)
1241            | ClauseKind::UnstableFeature(_) => false,
1242        })
1243    }
1244
1245    #[tracing::instrument(skip(self), ret)]
1246    fn item_bounds(
1247        self,
1248        def_id: Self::DefId,
1249    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1250        explicit_item_bounds(self, def_id).map_bound(|bounds| {
1251            Clauses::new_from_iter(self, elaborate(self, bounds).collect::<Vec<_>>())
1252        })
1253    }
1254
1255    #[tracing::instrument(skip(self), ret)]
1256    fn item_self_bounds(
1257        self,
1258        def_id: Self::DefId,
1259    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1260        explicit_item_bounds(self, def_id).map_bound(|bounds| {
1261            Clauses::new_from_iter(
1262                self,
1263                elaborate(self, bounds).filter_only_self().collect::<Vec<_>>(),
1264            )
1265        })
1266    }
1267
1268    fn item_non_self_bounds(
1269        self,
1270        def_id: Self::DefId,
1271    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1272        let all_bounds: FxHashSet<_> = self.item_bounds(def_id).skip_binder().into_iter().collect();
1273        let own_bounds: FxHashSet<_> =
1274            self.item_self_bounds(def_id).skip_binder().into_iter().collect();
1275        if all_bounds.len() == own_bounds.len() {
1276            EarlyBinder::bind(Clauses::new_from_iter(self, []))
1277        } else {
1278            EarlyBinder::bind(Clauses::new_from_iter(
1279                self,
1280                all_bounds.difference(&own_bounds).cloned(),
1281            ))
1282        }
1283    }
1284
1285    #[tracing::instrument(level = "debug", skip(self), ret)]
1286    fn predicates_of(
1287        self,
1288        def_id: Self::DefId,
1289    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1290        let predicates = self.db().generic_predicates_ns(def_id.try_into().unwrap());
1291        let predicates: Vec<_> = predicates.iter().cloned().collect();
1292        EarlyBinder::bind(predicates.into_iter())
1293    }
1294
1295    #[tracing::instrument(level = "debug", skip(self), ret)]
1296    fn own_predicates_of(
1297        self,
1298        def_id: Self::DefId,
1299    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1300        let predicates = self.db().generic_predicates_without_parent_ns(def_id.try_into().unwrap());
1301        let predicates: Vec<_> = predicates.iter().cloned().collect();
1302        EarlyBinder::bind(predicates.into_iter())
1303    }
1304
1305    #[tracing::instrument(skip(self), ret)]
1306    fn explicit_super_predicates_of(
1307        self,
1308        def_id: Self::DefId,
1309    ) -> EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> {
1310        let predicates: Vec<(Clause<'db>, Span)> = self
1311            .db()
1312            .generic_predicates_ns(def_id.try_into().unwrap())
1313            .iter()
1314            .cloned()
1315            .map(|p| (p, Span::dummy()))
1316            .collect();
1317        EarlyBinder::bind(predicates)
1318    }
1319
1320    #[tracing::instrument(skip(self), ret)]
1321    fn explicit_implied_predicates_of(
1322        self,
1323        def_id: Self::DefId,
1324    ) -> EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> {
1325        let predicates: Vec<(Clause<'db>, Span)> = self
1326            .db()
1327            .generic_predicates_ns(def_id.try_into().unwrap())
1328            .iter()
1329            .cloned()
1330            .map(|p| (p, Span::dummy()))
1331            .collect();
1332        EarlyBinder::bind(predicates)
1333    }
1334
1335    fn impl_super_outlives(
1336        self,
1337        impl_def_id: Self::DefId,
1338    ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1339        let impl_id = match impl_def_id {
1340            SolverDefId::ImplId(id) => id,
1341            _ => unreachable!(),
1342        };
1343        let trait_ref = self.db().impl_trait_ns(impl_id).expect("expected an impl of trait");
1344        trait_ref.map_bound(|trait_ref| {
1345            let clause: Clause<'_> = trait_ref.upcast(self);
1346            Clauses::new_from_iter(
1347                self,
1348                rustc_type_ir::elaborate::elaborate(self, [clause]).filter(|clause| {
1349                    matches!(
1350                        clause.kind().skip_binder(),
1351                        ClauseKind::TypeOutlives(_) | ClauseKind::RegionOutlives(_)
1352                    )
1353                }),
1354            )
1355        })
1356    }
1357
1358    fn const_conditions(
1359        self,
1360        def_id: Self::DefId,
1361    ) -> EarlyBinder<
1362        Self,
1363        impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>,
1364    > {
1365        EarlyBinder::bind([unimplemented!()])
1366    }
1367
1368    fn has_target_features(self, def_id: Self::DefId) -> bool {
1369        false
1370    }
1371
1372    fn require_lang_item(
1373        self,
1374        lang_item: rustc_type_ir::lang_items::TraitSolverLangItem,
1375    ) -> Self::DefId {
1376        let lang_item = match lang_item {
1377            rustc_type_ir::lang_items::TraitSolverLangItem::AsyncFn => LangItem::AsyncFn,
1378            rustc_type_ir::lang_items::TraitSolverLangItem::AsyncFnKindHelper => unimplemented!(),
1379            rustc_type_ir::lang_items::TraitSolverLangItem::AsyncFnKindUpvars => unimplemented!(),
1380            rustc_type_ir::lang_items::TraitSolverLangItem::AsyncFnMut => LangItem::AsyncFnMut,
1381            rustc_type_ir::lang_items::TraitSolverLangItem::AsyncFnOnce => LangItem::AsyncFnOnce,
1382            rustc_type_ir::lang_items::TraitSolverLangItem::AsyncFnOnceOutput => {
1383                LangItem::AsyncFnOnceOutput
1384            }
1385            rustc_type_ir::lang_items::TraitSolverLangItem::AsyncIterator => unimplemented!(),
1386            rustc_type_ir::lang_items::TraitSolverLangItem::CallOnceFuture => {
1387                LangItem::CallOnceFuture
1388            }
1389            rustc_type_ir::lang_items::TraitSolverLangItem::CallRefFuture => {
1390                LangItem::CallRefFuture
1391            }
1392            rustc_type_ir::lang_items::TraitSolverLangItem::Clone => LangItem::Clone,
1393            rustc_type_ir::lang_items::TraitSolverLangItem::Copy => LangItem::Copy,
1394            rustc_type_ir::lang_items::TraitSolverLangItem::Coroutine => LangItem::Coroutine,
1395            rustc_type_ir::lang_items::TraitSolverLangItem::CoroutineReturn => {
1396                LangItem::CoroutineReturn
1397            }
1398            rustc_type_ir::lang_items::TraitSolverLangItem::CoroutineYield => {
1399                LangItem::CoroutineYield
1400            }
1401            rustc_type_ir::lang_items::TraitSolverLangItem::Destruct => LangItem::Destruct,
1402            rustc_type_ir::lang_items::TraitSolverLangItem::DiscriminantKind => {
1403                LangItem::DiscriminantKind
1404            }
1405            rustc_type_ir::lang_items::TraitSolverLangItem::Drop => LangItem::Drop,
1406            rustc_type_ir::lang_items::TraitSolverLangItem::DynMetadata => LangItem::DynMetadata,
1407            rustc_type_ir::lang_items::TraitSolverLangItem::Fn => LangItem::Fn,
1408            rustc_type_ir::lang_items::TraitSolverLangItem::FnMut => LangItem::FnMut,
1409            rustc_type_ir::lang_items::TraitSolverLangItem::FnOnce => LangItem::FnOnce,
1410            rustc_type_ir::lang_items::TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait,
1411            rustc_type_ir::lang_items::TraitSolverLangItem::FusedIterator => unimplemented!(),
1412            rustc_type_ir::lang_items::TraitSolverLangItem::Future => LangItem::Future,
1413            rustc_type_ir::lang_items::TraitSolverLangItem::FutureOutput => LangItem::FutureOutput,
1414            rustc_type_ir::lang_items::TraitSolverLangItem::Iterator => LangItem::Iterator,
1415            rustc_type_ir::lang_items::TraitSolverLangItem::Metadata => LangItem::Metadata,
1416            rustc_type_ir::lang_items::TraitSolverLangItem::Option => LangItem::Option,
1417            rustc_type_ir::lang_items::TraitSolverLangItem::PointeeTrait => LangItem::PointeeTrait,
1418            rustc_type_ir::lang_items::TraitSolverLangItem::Poll => LangItem::Poll,
1419            rustc_type_ir::lang_items::TraitSolverLangItem::Sized => LangItem::Sized,
1420            rustc_type_ir::lang_items::TraitSolverLangItem::MetaSized => LangItem::MetaSized,
1421            rustc_type_ir::lang_items::TraitSolverLangItem::PointeeSized => LangItem::PointeeSized,
1422            rustc_type_ir::lang_items::TraitSolverLangItem::TransmuteTrait => {
1423                LangItem::TransmuteTrait
1424            }
1425            rustc_type_ir::lang_items::TraitSolverLangItem::Tuple => LangItem::Tuple,
1426            rustc_type_ir::lang_items::TraitSolverLangItem::Unpin => LangItem::Unpin,
1427            rustc_type_ir::lang_items::TraitSolverLangItem::Unsize => LangItem::Unsize,
1428            rustc_type_ir::lang_items::TraitSolverLangItem::BikeshedGuaranteedNoDrop => {
1429                unimplemented!()
1430            }
1431        };
1432        let target = hir_def::lang_item::lang_item(
1433            self.db(),
1434            self.krate.expect("Must have self.krate"),
1435            lang_item,
1436        )
1437        .unwrap_or_else(|| panic!("Lang item {lang_item:?} required but not found."));
1438        match target {
1439            hir_def::lang_item::LangItemTarget::EnumId(enum_id) => enum_id.into(),
1440            hir_def::lang_item::LangItemTarget::Function(function_id) => function_id.into(),
1441            hir_def::lang_item::LangItemTarget::ImplDef(impl_id) => impl_id.into(),
1442            hir_def::lang_item::LangItemTarget::Static(static_id) => static_id.into(),
1443            hir_def::lang_item::LangItemTarget::Struct(struct_id) => struct_id.into(),
1444            hir_def::lang_item::LangItemTarget::Union(union_id) => union_id.into(),
1445            hir_def::lang_item::LangItemTarget::TypeAlias(type_alias_id) => type_alias_id.into(),
1446            hir_def::lang_item::LangItemTarget::Trait(trait_id) => trait_id.into(),
1447            hir_def::lang_item::LangItemTarget::EnumVariant(enum_variant_id) => unimplemented!(),
1448        }
1449    }
1450
1451    #[allow(clippy::match_like_matches_macro)]
1452    fn is_lang_item(
1453        self,
1454        def_id: Self::DefId,
1455        lang_item: rustc_type_ir::lang_items::TraitSolverLangItem,
1456    ) -> bool {
1457        use rustc_type_ir::lang_items::TraitSolverLangItem::*;
1458
1459        // FIXME: derive PartialEq on TraitSolverLangItem
1460        self.as_lang_item(def_id).map_or(false, |l| match (l, lang_item) {
1461            (AsyncFn, AsyncFn) => true,
1462            (AsyncFnKindHelper, AsyncFnKindHelper) => true,
1463            (AsyncFnKindUpvars, AsyncFnKindUpvars) => true,
1464            (AsyncFnMut, AsyncFnMut) => true,
1465            (AsyncFnOnce, AsyncFnOnce) => true,
1466            (AsyncFnOnceOutput, AsyncFnOnceOutput) => true,
1467            (AsyncIterator, AsyncIterator) => true,
1468            (CallOnceFuture, CallOnceFuture) => true,
1469            (CallRefFuture, CallRefFuture) => true,
1470            (Clone, Clone) => true,
1471            (Copy, Copy) => true,
1472            (Coroutine, Coroutine) => true,
1473            (CoroutineReturn, CoroutineReturn) => true,
1474            (CoroutineYield, CoroutineYield) => true,
1475            (Destruct, Destruct) => true,
1476            (DiscriminantKind, DiscriminantKind) => true,
1477            (Drop, Drop) => true,
1478            (DynMetadata, DynMetadata) => true,
1479            (Fn, Fn) => true,
1480            (FnMut, FnMut) => true,
1481            (FnOnce, FnOnce) => true,
1482            (FnPtrTrait, FnPtrTrait) => true,
1483            (FusedIterator, FusedIterator) => true,
1484            (Future, Future) => true,
1485            (FutureOutput, FutureOutput) => true,
1486            (Iterator, Iterator) => true,
1487            (Metadata, Metadata) => true,
1488            (Option, Option) => true,
1489            (PointeeTrait, PointeeTrait) => true,
1490            (Poll, Poll) => true,
1491            (Sized, Sized) => true,
1492            (TransmuteTrait, TransmuteTrait) => true,
1493            (Tuple, Tuple) => true,
1494            (Unpin, Unpin) => true,
1495            (Unsize, Unsize) => true,
1496            _ => false,
1497        })
1498    }
1499
1500    fn as_lang_item(
1501        self,
1502        def_id: Self::DefId,
1503    ) -> Option<rustc_type_ir::lang_items::TraitSolverLangItem> {
1504        use rustc_type_ir::lang_items::TraitSolverLangItem;
1505
1506        let def_id: AttrDefId = match def_id {
1507            SolverDefId::TraitId(id) => id.into(),
1508            SolverDefId::TypeAliasId(id) => id.into(),
1509            _ => panic!("Unexpected SolverDefId in as_lang_item"),
1510        };
1511        let lang_item = self.db().lang_attr(def_id)?;
1512        Some(match lang_item {
1513            LangItem::Sized => TraitSolverLangItem::Sized,
1514            LangItem::MetaSized => TraitSolverLangItem::MetaSized,
1515            LangItem::PointeeSized => TraitSolverLangItem::PointeeSized,
1516            LangItem::Unsize => TraitSolverLangItem::Unsize,
1517            LangItem::StructuralPeq => return None,
1518            LangItem::StructuralTeq => return None,
1519            LangItem::Copy => TraitSolverLangItem::Copy,
1520            LangItem::Clone => TraitSolverLangItem::Clone,
1521            LangItem::Sync => return None,
1522            LangItem::DiscriminantKind => TraitSolverLangItem::DiscriminantKind,
1523            LangItem::Discriminant => return None,
1524            LangItem::PointeeTrait => TraitSolverLangItem::PointeeTrait,
1525            LangItem::Metadata => TraitSolverLangItem::Metadata,
1526            LangItem::DynMetadata => TraitSolverLangItem::DynMetadata,
1527            LangItem::Freeze => return None,
1528            LangItem::FnPtrTrait => TraitSolverLangItem::FnPtrTrait,
1529            LangItem::FnPtrAddr => return None,
1530            LangItem::Drop => TraitSolverLangItem::Drop,
1531            LangItem::Destruct => TraitSolverLangItem::Destruct,
1532            LangItem::CoerceUnsized => return None,
1533            LangItem::DispatchFromDyn => return None,
1534            LangItem::TransmuteOpts => return None,
1535            LangItem::TransmuteTrait => TraitSolverLangItem::TransmuteTrait,
1536            LangItem::Add => return None,
1537            LangItem::Sub => return None,
1538            LangItem::Mul => return None,
1539            LangItem::Div => return None,
1540            LangItem::Rem => return None,
1541            LangItem::Neg => return None,
1542            LangItem::Not => return None,
1543            LangItem::BitXor => return None,
1544            LangItem::BitAnd => return None,
1545            LangItem::BitOr => return None,
1546            LangItem::Shl => return None,
1547            LangItem::Shr => return None,
1548            LangItem::AddAssign => return None,
1549            LangItem::SubAssign => return None,
1550            LangItem::MulAssign => return None,
1551            LangItem::DivAssign => return None,
1552            LangItem::RemAssign => return None,
1553            LangItem::BitXorAssign => return None,
1554            LangItem::BitAndAssign => return None,
1555            LangItem::BitOrAssign => return None,
1556            LangItem::ShlAssign => return None,
1557            LangItem::ShrAssign => return None,
1558            LangItem::Index => return None,
1559            LangItem::IndexMut => return None,
1560            LangItem::UnsafeCell => return None,
1561            LangItem::VaList => return None,
1562            LangItem::Deref => return None,
1563            LangItem::DerefMut => return None,
1564            LangItem::DerefTarget => return None,
1565            LangItem::Receiver => return None,
1566            LangItem::Fn => TraitSolverLangItem::Fn,
1567            LangItem::FnMut => TraitSolverLangItem::FnMut,
1568            LangItem::FnOnce => TraitSolverLangItem::FnOnce,
1569            LangItem::FnOnceOutput => return None,
1570            LangItem::Future => TraitSolverLangItem::Future,
1571            LangItem::CoroutineState => return None,
1572            LangItem::Coroutine => TraitSolverLangItem::Coroutine,
1573            LangItem::CoroutineReturn => TraitSolverLangItem::CoroutineReturn,
1574            LangItem::CoroutineYield => TraitSolverLangItem::CoroutineYield,
1575            LangItem::Unpin => TraitSolverLangItem::Unpin,
1576            LangItem::Pin => return None,
1577            LangItem::PartialEq => return None,
1578            LangItem::PartialOrd => return None,
1579            LangItem::CVoid => return None,
1580            LangItem::Panic => return None,
1581            LangItem::PanicNounwind => return None,
1582            LangItem::PanicFmt => return None,
1583            LangItem::PanicDisplay => return None,
1584            LangItem::ConstPanicFmt => return None,
1585            LangItem::PanicBoundsCheck => return None,
1586            LangItem::PanicMisalignedPointerDereference => return None,
1587            LangItem::PanicInfo => return None,
1588            LangItem::PanicLocation => return None,
1589            LangItem::PanicImpl => return None,
1590            LangItem::PanicCannotUnwind => return None,
1591            LangItem::BeginPanic => return None,
1592            LangItem::FormatAlignment => return None,
1593            LangItem::FormatArgument => return None,
1594            LangItem::FormatArguments => return None,
1595            LangItem::FormatCount => return None,
1596            LangItem::FormatPlaceholder => return None,
1597            LangItem::FormatUnsafeArg => return None,
1598            LangItem::ExchangeMalloc => return None,
1599            LangItem::BoxFree => return None,
1600            LangItem::DropInPlace => return None,
1601            LangItem::AllocLayout => return None,
1602            LangItem::Start => return None,
1603            LangItem::EhPersonality => return None,
1604            LangItem::EhCatchTypeinfo => return None,
1605            LangItem::OwnedBox => return None,
1606            LangItem::PhantomData => return None,
1607            LangItem::ManuallyDrop => return None,
1608            LangItem::MaybeUninit => return None,
1609            LangItem::AlignOffset => return None,
1610            LangItem::Termination => return None,
1611            LangItem::Try => return None,
1612            LangItem::Tuple => TraitSolverLangItem::Tuple,
1613            LangItem::SliceLen => return None,
1614            LangItem::TryTraitFromResidual => return None,
1615            LangItem::TryTraitFromOutput => return None,
1616            LangItem::TryTraitBranch => return None,
1617            LangItem::TryTraitFromYeet => return None,
1618            LangItem::PointerLike => return None,
1619            LangItem::ConstParamTy => return None,
1620            LangItem::Poll => TraitSolverLangItem::Poll,
1621            LangItem::PollReady => return None,
1622            LangItem::PollPending => return None,
1623            LangItem::ResumeTy => return None,
1624            LangItem::GetContext => return None,
1625            LangItem::Context => return None,
1626            LangItem::FuturePoll => return None,
1627            LangItem::FutureOutput => TraitSolverLangItem::FutureOutput,
1628            LangItem::Option => TraitSolverLangItem::Option,
1629            LangItem::OptionSome => return None,
1630            LangItem::OptionNone => return None,
1631            LangItem::ResultOk => return None,
1632            LangItem::ResultErr => return None,
1633            LangItem::ControlFlowContinue => return None,
1634            LangItem::ControlFlowBreak => return None,
1635            LangItem::IntoFutureIntoFuture => return None,
1636            LangItem::IntoIterIntoIter => return None,
1637            LangItem::IteratorNext => return None,
1638            LangItem::Iterator => TraitSolverLangItem::Iterator,
1639            LangItem::PinNewUnchecked => return None,
1640            LangItem::RangeFrom => return None,
1641            LangItem::RangeFull => return None,
1642            LangItem::RangeInclusiveStruct => return None,
1643            LangItem::RangeInclusiveNew => return None,
1644            LangItem::Range => return None,
1645            LangItem::RangeToInclusive => return None,
1646            LangItem::RangeTo => return None,
1647            LangItem::String => return None,
1648            LangItem::CStr => return None,
1649            LangItem::AsyncFn => TraitSolverLangItem::AsyncFn,
1650            LangItem::AsyncFnMut => TraitSolverLangItem::AsyncFnMut,
1651            LangItem::AsyncFnOnce => TraitSolverLangItem::AsyncFnOnce,
1652            LangItem::AsyncFnOnceOutput => TraitSolverLangItem::AsyncFnOnceOutput,
1653            LangItem::CallRefFuture => TraitSolverLangItem::CallRefFuture,
1654            LangItem::CallOnceFuture => TraitSolverLangItem::CallOnceFuture,
1655            LangItem::Ordering => return None,
1656            LangItem::PanicNullPointerDereference => return None,
1657            LangItem::ReceiverTarget => return None,
1658            LangItem::UnsafePinned => return None,
1659            LangItem::AsyncFnOnceOutput => TraitSolverLangItem::AsyncFnOnceOutput,
1660        })
1661    }
1662
1663    fn associated_type_def_ids(self, def_id: Self::DefId) -> impl IntoIterator<Item = Self::DefId> {
1664        let trait_ = match def_id {
1665            SolverDefId::TraitId(id) => id,
1666            _ => unreachable!(),
1667        };
1668        trait_.trait_items(self.db()).associated_types().map(|id| id.into())
1669    }
1670
1671    fn for_each_relevant_impl(
1672        self,
1673        trait_def_id: Self::DefId,
1674        self_ty: Self::Ty,
1675        mut f: impl FnMut(Self::DefId),
1676    ) {
1677        let trait_ = match trait_def_id {
1678            SolverDefId::TraitId(id) => id,
1679            _ => panic!("for_each_relevant_impl called for non-trait"),
1680        };
1681
1682        let self_ty_fp = TyFingerprint::for_trait_impl_ns(&self_ty);
1683        let fps: &[TyFingerprint] = match self_ty.kind() {
1684            TyKind::Infer(InferTy::IntVar(..)) => &ALL_INT_FPS,
1685            TyKind::Infer(InferTy::FloatVar(..)) => &ALL_FLOAT_FPS,
1686            _ => self_ty_fp.as_slice(),
1687        };
1688
1689        if fps.is_empty() {
1690            for_trait_impls(
1691                self.db(),
1692                self.krate.expect("Must have self.krate"),
1693                self.block,
1694                trait_,
1695                self_ty_fp,
1696                |impls| {
1697                    for i in impls.for_trait(trait_) {
1698                        use rustc_type_ir::TypeVisitable;
1699                        let contains_errors = self.db().impl_trait_ns(i).map_or(false, |b| {
1700                            b.skip_binder().visit_with(&mut ContainsTypeErrors).is_break()
1701                        });
1702                        if contains_errors {
1703                            continue;
1704                        }
1705
1706                        f(SolverDefId::ImplId(i));
1707                    }
1708                    ControlFlow::Continue(())
1709                },
1710            );
1711        } else {
1712            for_trait_impls(
1713                self.db(),
1714                self.krate.expect("Must have self.krate"),
1715                self.block,
1716                trait_,
1717                self_ty_fp,
1718                |impls| {
1719                    for fp in fps {
1720                        for i in impls.for_trait_and_self_ty(trait_, *fp) {
1721                            use rustc_type_ir::TypeVisitable;
1722                            let contains_errors = self.db().impl_trait_ns(i).map_or(false, |b| {
1723                                b.skip_binder().visit_with(&mut ContainsTypeErrors).is_break()
1724                            });
1725                            if contains_errors {
1726                                continue;
1727                            }
1728
1729                            f(SolverDefId::ImplId(i));
1730                        }
1731                    }
1732                    ControlFlow::Continue(())
1733                },
1734            );
1735        }
1736    }
1737
1738    fn has_item_definition(self, def_id: Self::DefId) -> bool {
1739        // FIXME(next-solver): should check if the associated item has a value.
1740        true
1741    }
1742
1743    fn impl_is_default(self, impl_def_id: Self::DefId) -> bool {
1744        // FIXME
1745        false
1746    }
1747
1748    #[tracing::instrument(skip(self), ret)]
1749    fn impl_trait_ref(
1750        self,
1751        impl_def_id: Self::DefId,
1752    ) -> EarlyBinder<Self, rustc_type_ir::TraitRef<Self>> {
1753        let impl_id = match impl_def_id {
1754            SolverDefId::ImplId(id) => id,
1755            _ => panic!("Unexpected SolverDefId in impl_trait_ref"),
1756        };
1757
1758        let db = self.db();
1759
1760        db.impl_trait_ns(impl_id)
1761            // ImplIds for impls where the trait ref can't be resolved should never reach trait solving
1762            .expect("invalid impl passed to trait solver")
1763    }
1764
1765    fn impl_polarity(self, impl_def_id: Self::DefId) -> rustc_type_ir::ImplPolarity {
1766        let impl_id = match impl_def_id {
1767            SolverDefId::ImplId(id) => id,
1768            _ => unreachable!(),
1769        };
1770        let impl_data = self.db().impl_signature(impl_id);
1771        if impl_data.flags.contains(ImplFlags::NEGATIVE) {
1772            ImplPolarity::Negative
1773        } else {
1774            ImplPolarity::Positive
1775        }
1776    }
1777
1778    fn trait_is_auto(self, trait_def_id: Self::DefId) -> bool {
1779        let trait_ = match trait_def_id {
1780            SolverDefId::TraitId(id) => id,
1781            _ => panic!("Unexpected SolverDefId in trait_is_auto"),
1782        };
1783        let trait_data = self.db().trait_signature(trait_);
1784        trait_data.flags.contains(TraitFlags::AUTO)
1785    }
1786
1787    fn trait_is_alias(self, trait_def_id: Self::DefId) -> bool {
1788        let trait_ = match trait_def_id {
1789            SolverDefId::TraitId(id) => id,
1790            _ => panic!("Unexpected SolverDefId in trait_is_alias"),
1791        };
1792        let trait_data = self.db().trait_signature(trait_);
1793        trait_data.flags.contains(TraitFlags::ALIAS)
1794    }
1795
1796    fn trait_is_dyn_compatible(self, trait_def_id: Self::DefId) -> bool {
1797        let trait_ = match trait_def_id {
1798            SolverDefId::TraitId(id) => id,
1799            _ => unreachable!(),
1800        };
1801        crate::dyn_compatibility::dyn_compatibility(self.db(), trait_).is_none()
1802    }
1803
1804    fn trait_is_fundamental(self, def_id: Self::DefId) -> bool {
1805        let trait_ = match def_id {
1806            SolverDefId::TraitId(id) => id,
1807            _ => panic!("Unexpected SolverDefId in trait_is_fundamental"),
1808        };
1809        let trait_data = self.db().trait_signature(trait_);
1810        trait_data.flags.contains(TraitFlags::FUNDAMENTAL)
1811    }
1812
1813    fn trait_may_be_implemented_via_object(self, trait_def_id: Self::DefId) -> bool {
1814        // FIXME(next-solver): should check the `TraitFlags` for
1815        // the `#[rustc_do_not_implement_via_object]` flag
1816        true
1817    }
1818
1819    fn is_impl_trait_in_trait(self, def_id: Self::DefId) -> bool {
1820        // FIXME(next-solver)
1821        false
1822    }
1823
1824    fn delay_bug(self, msg: impl ToString) -> Self::ErrorGuaranteed {
1825        panic!("Bug encountered in next-trait-solver.")
1826    }
1827
1828    fn is_general_coroutine(self, coroutine_def_id: Self::DefId) -> bool {
1829        // FIXME(next-solver)
1830        true
1831    }
1832
1833    fn coroutine_is_async(self, coroutine_def_id: Self::DefId) -> bool {
1834        // FIXME(next-solver)
1835        true
1836    }
1837
1838    fn coroutine_is_gen(self, coroutine_def_id: Self::DefId) -> bool {
1839        // FIXME(next-solver)
1840        false
1841    }
1842
1843    fn coroutine_is_async_gen(self, coroutine_def_id: Self::DefId) -> bool {
1844        // FIXME(next-solver)
1845        false
1846    }
1847
1848    fn unsizing_params_for_adt(self, adt_def_id: Self::DefId) -> Self::UnsizingParams {
1849        let id = match adt_def_id {
1850            SolverDefId::AdtId(id) => id,
1851            _ => unreachable!(),
1852        };
1853        let def = AdtDef::new(id, self);
1854        let num_params = self.generics_of(adt_def_id).count();
1855
1856        let maybe_unsizing_param_idx = |arg: GenericArg<'db>| match arg.kind() {
1857            GenericArgKind::Type(ty) => match ty.kind() {
1858                rustc_type_ir::TyKind::Param(p) => Some(p.index),
1859                _ => None,
1860            },
1861            GenericArgKind::Lifetime(_) => None,
1862            GenericArgKind::Const(ct) => match ct.kind() {
1863                rustc_type_ir::ConstKind::Param(p) => Some(p.index),
1864                _ => None,
1865            },
1866        };
1867
1868        // The last field of the structure has to exist and contain type/const parameters.
1869        let variant = def.non_enum_variant();
1870        let fields = variant.fields(self.db());
1871        let Some((tail_field, prefix_fields)) = fields.split_last() else {
1872            return UnsizingParams(DenseBitSet::new_empty(num_params));
1873        };
1874
1875        let field_types = self.db().field_types_ns(variant.id());
1876        let mut unsizing_params = DenseBitSet::new_empty(num_params);
1877        let ty = field_types[tail_field.0];
1878        for arg in ty.instantiate_identity().walk() {
1879            if let Some(i) = maybe_unsizing_param_idx(arg) {
1880                unsizing_params.insert(i);
1881            }
1882        }
1883
1884        // Ensure none of the other fields mention the parameters used
1885        // in unsizing.
1886        for field in prefix_fields {
1887            for arg in field_types[field.0].instantiate_identity().walk() {
1888                if let Some(i) = maybe_unsizing_param_idx(arg) {
1889                    unsizing_params.remove(i);
1890                }
1891            }
1892        }
1893
1894        UnsizingParams(unsizing_params)
1895    }
1896
1897    fn anonymize_bound_vars<T: rustc_type_ir::TypeFoldable<Self>>(
1898        self,
1899        value: rustc_type_ir::Binder<Self, T>,
1900    ) -> rustc_type_ir::Binder<Self, T> {
1901        struct Anonymize<'a, 'db> {
1902            interner: DbInterner<'db>,
1903            map: &'a mut FxIndexMap<BoundVar, BoundVarKind>,
1904        }
1905        impl<'db> BoundVarReplacerDelegate<'db> for Anonymize<'_, 'db> {
1906            fn replace_region(&mut self, br: BoundRegion) -> Region<'db> {
1907                let entry = self.map.entry(br.var);
1908                let index = entry.index();
1909                let var = BoundVar::from_usize(index);
1910                let kind = (*entry.or_insert_with(|| BoundVarKind::Region(BoundRegionKind::Anon)))
1911                    .expect_region();
1912                let br = BoundRegion { var, kind };
1913                Region::new_bound(self.interner, DebruijnIndex::ZERO, br)
1914            }
1915            fn replace_ty(&mut self, bt: BoundTy) -> Ty<'db> {
1916                let entry = self.map.entry(bt.var);
1917                let index = entry.index();
1918                let var = BoundVar::from_usize(index);
1919                let kind =
1920                    (*entry.or_insert_with(|| BoundVarKind::Ty(BoundTyKind::Anon))).expect_ty();
1921                Ty::new_bound(self.interner, DebruijnIndex::ZERO, BoundTy { var, kind })
1922            }
1923            fn replace_const(&mut self, bv: BoundVar) -> Const<'db> {
1924                let entry = self.map.entry(bv);
1925                let index = entry.index();
1926                let var = BoundVar::from_usize(index);
1927                let () = (*entry.or_insert_with(|| BoundVarKind::Const)).expect_const();
1928                Const::new_bound(self.interner, DebruijnIndex::ZERO, var)
1929            }
1930        }
1931
1932        let mut map = Default::default();
1933        let delegate = Anonymize { interner: self, map: &mut map };
1934        let inner = self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate);
1935        let bound_vars = CollectAndApply::collect_and_apply(map.into_values(), |xs| {
1936            BoundVarKinds::new_from_iter(self, xs.iter().cloned())
1937        });
1938        Binder::bind_with_vars(inner, bound_vars)
1939    }
1940
1941    fn opaque_types_defined_by(self, defining_anchor: Self::LocalDefId) -> Self::LocalDefIds {
1942        // FIXME(next-solver)
1943        SolverDefIds::new_from_iter(self, [])
1944    }
1945
1946    fn alias_has_const_conditions(self, def_id: Self::DefId) -> bool {
1947        // FIXME(next-solver)
1948        false
1949    }
1950
1951    fn explicit_implied_const_bounds(
1952        self,
1953        def_id: Self::DefId,
1954    ) -> EarlyBinder<
1955        Self,
1956        impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>,
1957    > {
1958        // FIXME(next-solver)
1959        EarlyBinder::bind([])
1960    }
1961
1962    fn fn_is_const(self, def_id: Self::DefId) -> bool {
1963        let id = match def_id {
1964            SolverDefId::FunctionId(id) => id,
1965            _ => unreachable!(),
1966        };
1967        self.db().function_signature(id).flags.contains(FnFlags::CONST)
1968    }
1969
1970    fn impl_is_const(self, def_id: Self::DefId) -> bool {
1971        false
1972    }
1973
1974    fn opt_alias_variances(
1975        self,
1976        kind: impl Into<rustc_type_ir::AliasTermKind>,
1977        def_id: Self::DefId,
1978    ) -> Option<Self::VariancesOf> {
1979        None
1980    }
1981
1982    fn type_of_opaque_hir_typeck(self, def_id: Self::LocalDefId) -> EarlyBinder<Self, Self::Ty> {
1983        match def_id {
1984            SolverDefId::InternedOpaqueTyId(opaque) => {
1985                let impl_trait_id = self.db().lookup_intern_impl_trait_id(opaque);
1986                match impl_trait_id {
1987                    crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => {
1988                        let infer = self.db().infer(func.into());
1989                        EarlyBinder::bind(infer.type_of_rpit[idx].to_nextsolver(self))
1990                    }
1991                    crate::ImplTraitId::TypeAliasImplTrait(..)
1992                    | crate::ImplTraitId::AsyncBlockTypeImplTrait(_, _) => {
1993                        // FIXME(next-solver)
1994                        EarlyBinder::bind(Ty::new_error(self, ErrorGuaranteed))
1995                    }
1996                }
1997            }
1998            _ => panic!("Unexpected SolverDefId in type_of_opaque_hir_typeck"),
1999        }
2000    }
2001
2002    fn coroutine_hidden_types(
2003        self,
2004        def_id: Self::DefId,
2005    ) -> EarlyBinder<Self, rustc_type_ir::Binder<Self, rustc_type_ir::CoroutineWitnessTypes<Self>>>
2006    {
2007        // FIXME(next-solver)
2008        unimplemented!()
2009    }
2010
2011    fn is_default_trait(self, def_id: Self::DefId) -> bool {
2012        self.as_lang_item(def_id).map_or(false, |l| matches!(l, TraitSolverLangItem::Sized))
2013    }
2014
2015    fn trait_is_coinductive(self, trait_def_id: Self::DefId) -> bool {
2016        let id = match trait_def_id {
2017            SolverDefId::TraitId(id) => id,
2018            _ => unreachable!(),
2019        };
2020        self.db().trait_signature(id).flags.contains(TraitFlags::COINDUCTIVE)
2021    }
2022
2023    fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
2024        let id = match trait_def_id {
2025            SolverDefId::TraitId(id) => id,
2026            _ => unreachable!(),
2027        };
2028        self.db().trait_signature(id).flags.contains(TraitFlags::UNSAFE)
2029    }
2030
2031    fn impl_self_is_guaranteed_unsized(self, def_id: Self::DefId) -> bool {
2032        false
2033    }
2034
2035    fn impl_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool {
2036        false
2037    }
2038
2039    fn next_trait_solver_globally(self) -> bool {
2040        true
2041    }
2042
2043    fn opaque_types_and_coroutines_defined_by(
2044        self,
2045        defining_anchor: Self::LocalDefId,
2046    ) -> Self::LocalDefIds {
2047        // FIXME(next-solver)
2048        unimplemented!()
2049    }
2050}
2051
2052impl<'db> DbInterner<'db> {
2053    pub fn shift_bound_var_indices<T>(self, bound_vars: usize, value: T) -> T
2054    where
2055        T: rustc_type_ir::TypeFoldable<Self>,
2056    {
2057        let shift_bv = |bv: BoundVar| BoundVar::from_usize(bv.as_usize() + bound_vars);
2058        self.replace_escaping_bound_vars_uncached(
2059            value,
2060            FnMutDelegate {
2061                regions: &mut |r: BoundRegion| {
2062                    Region::new_bound(
2063                        self,
2064                        DebruijnIndex::ZERO,
2065                        BoundRegion { var: shift_bv(r.var), kind: r.kind },
2066                    )
2067                },
2068                types: &mut |t: BoundTy| {
2069                    Ty::new_bound(
2070                        self,
2071                        DebruijnIndex::ZERO,
2072                        BoundTy { var: shift_bv(t.var), kind: t.kind },
2073                    )
2074                },
2075                consts: &mut |c| Const::new_bound(self, DebruijnIndex::ZERO, shift_bv(c)),
2076            },
2077        )
2078    }
2079
2080    pub fn replace_escaping_bound_vars_uncached<T: rustc_type_ir::TypeFoldable<DbInterner<'db>>>(
2081        self,
2082        value: T,
2083        delegate: impl BoundVarReplacerDelegate<'db>,
2084    ) -> T {
2085        if !value.has_escaping_bound_vars() {
2086            value
2087        } else {
2088            let mut replacer = BoundVarReplacer::new(self, delegate);
2089            value.fold_with(&mut replacer)
2090        }
2091    }
2092
2093    pub fn replace_bound_vars_uncached<T: rustc_type_ir::TypeFoldable<DbInterner<'db>>>(
2094        self,
2095        value: Binder<'db, T>,
2096        delegate: impl BoundVarReplacerDelegate<'db>,
2097    ) -> T {
2098        self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate)
2099    }
2100}
2101
2102macro_rules! TrivialTypeTraversalImpls {
2103    ($($ty:ty,)+) => {
2104        $(
2105            impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for $ty {
2106                fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
2107                    self,
2108                    _: &mut F,
2109                ) -> ::std::result::Result<Self, F::Error> {
2110                    Ok(self)
2111                }
2112
2113                #[inline]
2114                fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(
2115                    self,
2116                    _: &mut F,
2117                ) -> Self {
2118                    self
2119                }
2120            }
2121
2122            impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for $ty {
2123                #[inline]
2124                fn visit_with<F: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
2125                    &self,
2126                    _: &mut F)
2127                    -> F::Result
2128                {
2129                    <F::Result as rustc_ast_ir::visit::VisitorResult>::output()
2130                }
2131            }
2132        )+
2133    };
2134}
2135
2136TrivialTypeTraversalImpls! {
2137    SolverDefId,
2138    Pattern<'db>,
2139    Safety,
2140    FnAbi,
2141    Span,
2142    ParamConst,
2143    ParamTy,
2144    BoundRegion,
2145    BoundVar,
2146    Placeholder<BoundRegion>,
2147    Placeholder<BoundTy>,
2148    Placeholder<BoundVar>,
2149}
2150
2151mod tls_cache {
2152    use crate::db::HirDatabase;
2153
2154    use super::DbInterner;
2155    use base_db::Nonce;
2156    use rustc_type_ir::search_graph::GlobalCache;
2157    use salsa::Revision;
2158    use std::cell::RefCell;
2159
2160    struct Cache {
2161        cache: GlobalCache<DbInterner<'static>>,
2162        revision: Revision,
2163        db_nonce: Nonce,
2164    }
2165
2166    thread_local! {
2167        static GLOBAL_CACHE: RefCell<Option<Cache>> = const { RefCell::new(None) };
2168    }
2169
2170    pub(super) fn with_cache<'db, T>(
2171        db: &'db dyn HirDatabase,
2172        f: impl FnOnce(&mut GlobalCache<DbInterner<'db>>) -> T,
2173    ) -> T {
2174        GLOBAL_CACHE.with_borrow_mut(|handle| {
2175            let (db_nonce, revision) = db.nonce_and_revision();
2176            let handle = match handle {
2177                Some(handle) => {
2178                    if handle.revision != revision || db_nonce != handle.db_nonce {
2179                        *handle = Cache { cache: GlobalCache::default(), revision, db_nonce };
2180                    }
2181                    handle
2182                }
2183                None => handle.insert(Cache { cache: GlobalCache::default(), revision, db_nonce }),
2184            };
2185
2186            // SAFETY: No idea
2187            f(unsafe {
2188                std::mem::transmute::<
2189                    &mut GlobalCache<DbInterner<'static>>,
2190                    &mut GlobalCache<DbInterner<'db>>,
2191                >(&mut handle.cache)
2192            })
2193        })
2194    }
2195}