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