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