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, 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
875impl<'db> Interner for DbInterner<'db> {
876 type DefId = SolverDefId<'db>;
877 type LocalDefId = SolverDefId<'db>;
878 type LocalDefIds = SolverDefIds<'db>;
879 type TraitId = TraitIdWrapper;
880 type ForeignId = TypeAliasIdWrapper;
881 type FunctionId = CallableIdWrapper;
882 type ClosureId = ClosureIdWrapper<'db>;
883 type CoroutineClosureId = CoroutineClosureIdWrapper<'db>;
884 type CoroutineId = CoroutineIdWrapper<'db>;
885 type AdtId = AdtIdWrapper;
886 type ImplId = AnyImplId;
887 type UnevaluatedConstId = GeneralConstIdWrapper<'db>;
888 type TraitAssocTyId = TraitAssocTyId;
889 type TraitAssocConstId = TraitAssocConstId;
890 type TraitAssocTermId = TraitAssocTermId;
891 type OpaqueTyId = OpaqueTyIdWrapper<'db>;
892 type LocalOpaqueTyId = OpaqueTyIdWrapper<'db>;
893 type FreeTyAliasId = FreeTyAliasId;
894 type FreeConstAliasId = FreeConstAliasId;
895 type FreeTermAliasId = FreeTermAliasId;
896 type ImplOrTraitAssocTyId = ImplOrTraitAssocTyId;
897 type ImplOrTraitAssocConstId = ImplOrTraitAssocConstId;
898 type ImplOrTraitAssocTermId = ImplOrTraitAssocTermId;
899 type InherentAssocTyId = InherentAssocTyId;
900 type InherentAssocConstId = InherentAssocConstId;
901 type InherentAssocTermId = InherentAssocTermId;
902 type Span = Span;
903
904 type GenericArgs = GenericArgs<'db>;
905 type GenericArgsSlice = &'db [GenericArg<'db>];
906 type GenericArg = GenericArg<'db>;
907
908 type Term = Term<'db>;
909
910 type BoundVarKinds = BoundVarKinds<'db>;
911
912 type PredefinedOpaques = PredefinedOpaques<'db>;
913
914 fn mk_predefined_opaques_in_body(
915 self,
916 data: &[(OpaqueTypeKey<'db>, Self::Ty)],
917 ) -> Self::PredefinedOpaques {
918 PredefinedOpaques::new_from_slice(data)
919 }
920
921 type CanonicalVarKinds = CanonicalVarKinds<'db>;
922
923 fn mk_canonical_var_kinds(
924 self,
925 kinds: &[rustc_type_ir::CanonicalVarKind<Self>],
926 ) -> Self::CanonicalVarKinds {
927 CanonicalVarKinds::new_from_slice(kinds)
928 }
929
930 type ExternalConstraints = ExternalConstraints<'db>;
931
932 fn mk_external_constraints(
933 self,
934 data: rustc_type_ir::solve::ExternalConstraintsData<Self>,
935 ) -> Self::ExternalConstraints {
936 ExternalConstraints::new(self, data)
937 }
938
939 type DepNodeIndex = DepNodeIndex;
940
941 type Tracked<T: fmt::Debug + Clone> = Tracked<T>;
942
943 type Ty = Ty<'db>;
944 type Tys = Tys<'db>;
945 type FnInputTys = &'db [Ty<'db>];
946 type ParamTy = ParamTy;
947 type Symbol = Symbol;
948
949 type ErrorGuaranteed = ErrorGuaranteed;
950 type BoundExistentialPredicates = BoundExistentialPredicates<'db>;
951 type AllocId = AllocId;
952 type Pat = Pattern<'db>;
953 type PatList = PatList<'db>;
954 type Safety = Safety;
955
956 type Const = Const<'db>;
957 type ParamConst = ParamConst;
958 type ValueConst = ValueConst<'db>;
959 type ValTree = ValTree<'db>;
960 type Consts = Consts<'db>;
961 type ScalarInt = ScalarInt;
962 type ExprConst = ExprConst;
963
964 type Region = Region<'db>;
965 type EarlyParamRegion = EarlyParamRegion;
966 type LateParamRegion = LateParamRegion<'db>;
967
968 type RegionAssumptions = RegionAssumptions<'db>;
969
970 type ParamEnv = ParamEnv<'db>;
971 type Predicate = Predicate<'db>;
972 type Clause = Clause<'db>;
973 type Clauses = Clauses<'db>;
974
975 type GenericsOf = Generics<'db>;
976
977 type VariancesOf = VariancesOf<'db>;
978
979 type AdtDef = AdtDef;
980
981 type Features = Features;
982
983 fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs {
984 GenericArgs::new_from_slice(args)
985 }
986
987 fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
988 where
989 I: Iterator<Item = T>,
990 T: rustc_type_ir::CollectAndApply<Self::GenericArg, Self::GenericArgs>,
991 {
992 GenericArgs::new_from_iter(args)
993 }
994
995 type UnsizingParams = UnsizingParams;
996
997 fn mk_tracked<T: fmt::Debug + Clone>(
998 self,
999 data: T,
1000 _dep_node: Self::DepNodeIndex,
1001 ) -> Self::Tracked<T> {
1002 Tracked(data)
1003 }
1004
1005 fn get_tracked<T: fmt::Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T {
1006 tracked.0.clone()
1007 }
1008
1009 fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, Self::DepNodeIndex) {
1010 (task(), DepNodeIndex)
1011 }
1012
1013 fn with_global_cache<R>(
1014 self,
1015 f: impl FnOnce(&mut rustc_type_ir::search_graph::GlobalCache<Self>) -> R,
1016 ) -> R {
1017 tls_cache::borrow_assume_valid(self.db, f)
1019 }
1020
1021 fn canonical_param_env_cache_get_or_insert<R>(
1022 self,
1023 _param_env: Self::ParamEnv,
1024 f: impl FnOnce() -> rustc_type_ir::CanonicalParamEnvCacheEntry<Self>,
1025 from_entry: impl FnOnce(&rustc_type_ir::CanonicalParamEnvCacheEntry<Self>) -> R,
1026 ) -> R {
1027 from_entry(&f())
1028 }
1029
1030 fn assert_evaluation_is_concurrent(&self) {
1031 }
1034
1035 fn expand_abstract_consts<T: rustc_type_ir::TypeFoldable<Self>>(self, _: T) -> T {
1036 unreachable!("only used by the old trait solver in rustc");
1037 }
1038
1039 fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf {
1040 generics(self, def_id)
1041 }
1042
1043 fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf {
1044 let generic_def = match def_id {
1045 SolverDefId::Ctor(Ctor::Enum(def_id)) | SolverDefId::EnumVariantId(def_id) => {
1046 def_id.loc(self.db).parent.into()
1047 }
1048 SolverDefId::InternedOpaqueTyId(_def_id) => {
1049 return VariancesOf::new_from_iter(
1054 (0..self.generics_of(def_id).count()).map(|_| Variance::Invariant),
1055 );
1056 }
1057 SolverDefId::Ctor(Ctor::Struct(def_id)) => def_id.into(),
1058 SolverDefId::AdtId(def_id) => def_id.into(),
1059 SolverDefId::FunctionId(def_id) => def_id.into(),
1060 SolverDefId::ConstId(_)
1061 | SolverDefId::StaticId(_)
1062 | SolverDefId::TraitId(_)
1063 | SolverDefId::TypeAliasId(_)
1064 | SolverDefId::ImplId(_)
1065 | SolverDefId::BuiltinDeriveImplId(_)
1066 | SolverDefId::InternedClosureId(_)
1067 | SolverDefId::InternedCoroutineId(_)
1068 | SolverDefId::InternedCoroutineClosureId(_)
1069 | SolverDefId::AnonConstId(_) => {
1070 return VariancesOf::empty();
1071 }
1072 };
1073 self.db.variances_of(generic_def)
1074 }
1075
1076 fn type_of(self, def_id: Self::DefId) -> EarlyBinder<Self, Self::Ty> {
1077 match def_id {
1078 SolverDefId::TypeAliasId(id) => self.db().ty(id.into()),
1079 SolverDefId::AdtId(id) => self.db().ty(id.into()),
1080 SolverDefId::InternedOpaqueTyId(def_id) => {
1085 self.type_of_opaque_hir_typeck(def_id.into())
1086 }
1087 SolverDefId::FunctionId(id) => self.db.value_ty(id.into()).unwrap(),
1088 SolverDefId::Ctor(id) => {
1089 let id = match id {
1090 Ctor::Struct(id) => id.into(),
1091 Ctor::Enum(id) => id.into(),
1092 };
1093 self.db.value_ty(id).expect("`SolverDefId::Ctor` should have a function-like ctor")
1094 }
1095 _ => panic!("Unexpected def_id `{def_id:?}` provided for `type_of`"),
1096 }
1097 }
1098
1099 fn adt_def(self, def_id: Self::AdtId) -> Self::AdtDef {
1100 AdtDef::new(def_id.0, self)
1101 }
1102
1103 fn alias_term_kind_from_def_id(self, def_id: SolverDefId<'db>) -> AliasTermKind<'db> {
1104 match def_id {
1105 SolverDefId::InternedOpaqueTyId(def_id) => {
1106 AliasTermKind::OpaqueTy { def_id: def_id.into() }
1107 }
1108 SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container {
1109 ItemContainerId::ImplId(impl_)
1110 if ImplSignature::of(self.db, impl_).target_trait.is_none() =>
1111 {
1112 AliasTermKind::InherentTy { def_id: type_alias.into() }
1113 }
1114 ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) => {
1115 AliasTermKind::ProjectionTy { def_id: type_alias.into() }
1116 }
1117 _ => AliasTermKind::FreeTy { def_id: type_alias.into() },
1118 },
1119 SolverDefId::ConstId(def_id) => {
1122 AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) }
1123 }
1124 SolverDefId::StaticId(def_id) => {
1125 AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) }
1126 }
1127 SolverDefId::AnonConstId(def_id) => {
1128 AliasTermKind::UnevaluatedConst { def_id: GeneralConstIdWrapper(def_id.into()) }
1129 }
1130 _ => unimplemented!("Unexpected alias: {:?}", def_id),
1131 }
1132 }
1133
1134 fn trait_ref_and_own_args_for_alias(
1135 self,
1136 def_id: Self::TraitAssocTermId,
1137 args: Self::GenericArgs,
1138 ) -> (rustc_type_ir::TraitRef<Self>, Self::GenericArgsSlice) {
1139 let trait_def_id = self.projection_parent(def_id);
1140 let trait_ref = TraitRef::from_assoc(self, trait_def_id, args);
1141 (trait_ref, &args.as_slice()[trait_ref.args.len()..])
1142 }
1143
1144 fn check_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs) -> bool {
1145 let generics = self.generics_of(def_id);
1146 generics.count() == args.len()
1147 && std::iter::zip(generics.iter(), args).all(|((param, _), arg)| {
1148 matches!(
1149 (param, arg.kind()),
1150 (GenericParamId::LifetimeParamId(_), GenericArgKind::Lifetime(_))
1151 | (GenericParamId::TypeParamId(_), GenericArgKind::Type(_))
1152 | (GenericParamId::ConstParamId(_), GenericArgKind::Const(_))
1153 )
1154 })
1155 }
1156
1157 fn debug_assert_args_compatible(self, _def_id: Self::DefId, _args: Self::GenericArgs) {}
1158
1159 fn debug_assert_existential_args_compatible(
1160 self,
1161 _def_id: Self::DefId,
1162 _args: Self::GenericArgs,
1163 ) {
1164 }
1165
1166 fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
1167 where
1168 I: Iterator<Item = T>,
1169 T: rustc_type_ir::CollectAndApply<Self::Ty, Self::Tys>,
1170 {
1171 Tys::new_from_iter(args)
1172 }
1173
1174 fn projection_parent(self, def_id: Self::TraitAssocTermId) -> Self::TraitId {
1175 let container = match def_id.0 {
1176 TermId::TypeAliasId(def_id) => def_id.loc(self.db).container,
1177 TermId::ConstId(def_id) => def_id.loc(self.db).container,
1178 };
1179 let ItemContainerId::TraitId(trait_) = container else {
1180 panic!("a TraitAssocTermId can only come from a trait")
1181 };
1182 trait_.into()
1183 }
1184
1185 fn impl_or_trait_assoc_term_parent(self, def_id: Self::ImplOrTraitAssocTermId) -> Self::DefId {
1186 let container = match def_id.0 {
1187 TermId::TypeAliasId(def_id) => def_id.loc(self.db).container,
1188 TermId::ConstId(def_id) => def_id.loc(self.db).container,
1189 };
1190 match container {
1191 ItemContainerId::ImplId(impl_) => impl_.into(),
1192 ItemContainerId::TraitId(trait_) => trait_.into(),
1193 ItemContainerId::ExternBlockId(_) | ItemContainerId::ModuleId(_) => {
1194 panic!("only impl or trait can be the parent of ImplOrTraitAssocTermId")
1195 }
1196 }
1197 }
1198
1199 fn inherent_alias_term_parent(self, def_id: Self::InherentAssocTermId) -> Self::ImplId {
1200 let container = match def_id.0 {
1201 TermId::TypeAliasId(def_id) => def_id.loc(self.db).container,
1202 TermId::ConstId(def_id) => def_id.loc(self.db).container,
1203 };
1204 match container {
1205 ItemContainerId::ImplId(impl_) => impl_.into(),
1206 ItemContainerId::ExternBlockId(_)
1207 | ItemContainerId::ModuleId(_)
1208 | ItemContainerId::TraitId(_) => {
1209 panic!("only impl can be the parent of InherentAliasTermId")
1210 }
1211 }
1212 }
1213
1214 fn recursion_limit(self) -> usize {
1215 50
1216 }
1217
1218 fn is_type_const(self, _def_id: Self::DefId) -> bool {
1219 false
1220 }
1221
1222 fn features(self) -> Features {
1223 Features
1224 }
1225
1226 fn fn_sig(
1227 self,
1228 def_id: Self::FunctionId,
1229 ) -> EarlyBinder<Self, rustc_type_ir::Binder<Self, rustc_type_ir::FnSig<Self>>> {
1230 self.db().callable_item_signature(def_id.0)
1231 }
1232
1233 fn coroutine_movability(self, def_id: Self::CoroutineId) -> rustc_ast_ir::Movability {
1234 match def_id.0.loc(self.db).kind {
1235 hir_def::hir::ClosureKind::OldCoroutine(movability) => match movability {
1236 hir_def::hir::Movability::Static => rustc_ast_ir::Movability::Static,
1237 hir_def::hir::Movability::Movable => rustc_ast_ir::Movability::Movable,
1238 },
1239 hir_def::hir::ClosureKind::Coroutine { .. } => rustc_ast_ir::Movability::Static,
1240 kind => panic!("unexpected kind for a coroutine: {kind:?}"),
1241 }
1242 }
1243
1244 fn coroutine_for_closure(self, def_id: Self::CoroutineClosureId) -> Self::CoroutineId {
1245 let InternedClosure { owner, expr: coroutine_closure_expr, kind: coroutine_closure_kind } =
1246 def_id.0.loc(self.db);
1247 let coroutine_closure_kind = match coroutine_closure_kind {
1248 HirClosureKind::CoroutineClosure(it) => it,
1249 _ => {
1250 panic!("invalid kind closure kind {coroutine_closure_kind:?} for coroutine closure")
1251 }
1252 };
1253 let coroutine_expr = ExpressionStore::coroutine_for_closure(coroutine_closure_expr);
1254 let coroutine_kind = hir_def::hir::ClosureKind::Coroutine {
1255 kind: coroutine_closure_kind,
1256 source: hir_def::hir::CoroutineSource::Closure,
1257 };
1258 InternedCoroutineId::new(
1259 self.db,
1260 InternedClosure { owner, expr: coroutine_expr, kind: coroutine_kind },
1261 )
1262 .into()
1263 }
1264
1265 fn generics_require_sized_self(self, def_id: Self::DefId) -> bool {
1266 match GenericDefId::try_from(def_id) {
1267 Ok(def_id) => crate::dyn_compatibility::generics_require_sized_self(self.db, def_id),
1268 Err(_) => false,
1269 }
1270 }
1271
1272 #[tracing::instrument(skip(self))]
1273 fn item_bounds(
1274 self,
1275 def_id: Self::DefId,
1276 ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1277 ItemBounds::of_solver_def(self.db, def_id).all_bounds()
1278 }
1279
1280 #[tracing::instrument(skip(self))]
1281 fn item_self_bounds(
1282 self,
1283 def_id: Self::DefId,
1284 ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1285 ItemBounds::of_solver_def(self.db, def_id).self_bounds()
1286 }
1287
1288 fn item_non_self_bounds(
1289 self,
1290 def_id: Self::DefId,
1291 ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1292 ItemBounds::of_solver_def(self.db, def_id).non_self_bounds()
1293 }
1294
1295 fn predicates_of(
1296 self,
1297 def_id: Self::DefId,
1298 ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1299 predicates_of(self.db, def_id).all_predicates()
1300 }
1301
1302 fn own_predicates_of(
1303 self,
1304 def_id: Self::DefId,
1305 ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1306 predicates_of(self.db, def_id).own_explicit_predicates()
1307 }
1308
1309 fn explicit_super_predicates_of(
1310 self,
1311 def_id: Self::TraitId,
1312 ) -> EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> {
1313 GenericPredicates::query(self.db, def_id.0.into())
1314 .explicit_non_assoc_types_predicates()
1315 .map_bound(move |predicates| {
1316 predicates.filter(|p| is_clause_at_ty(p, is_ty_self)).map(|p| (p, Span::dummy()))
1317 })
1318 }
1319
1320 fn explicit_implied_predicates_of(
1321 self,
1322 def_id: Self::DefId,
1323 ) -> EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>> {
1324 fn is_ty_assoc_of_self(ty: Ty<'_>) -> bool {
1325 if let TyKind::Alias(alias @ AliasTy { kind: AliasTyKind::Projection { .. }, .. }) =
1328 ty.kind()
1329 {
1330 is_ty_assoc_of_self(alias.self_ty())
1331 } else {
1332 is_ty_self(ty)
1333 }
1334 }
1335
1336 let predicates = predicates_of(self.db, def_id);
1337 let non_assoc_types = predicates
1338 .explicit_non_assoc_types_predicates()
1339 .skip_binder()
1340 .filter(|p| is_clause_at_ty(p, is_ty_self));
1341 let assoc_types = predicates
1342 .explicit_assoc_types_predicates()
1343 .skip_binder()
1344 .filter(|p| is_clause_at_ty(p, is_ty_assoc_of_self));
1345 EarlyBinder::bind(non_assoc_types.chain(assoc_types).map(|it| (it, Span::dummy())))
1346 }
1347
1348 fn impl_super_outlives(
1349 self,
1350 impl_id: Self::ImplId,
1351 ) -> EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>> {
1352 let bounds = match impl_id {
1353 AnyImplId::ImplId(id) => {
1354 impl_super_outlives(self.db, id).get().map_bound(|it| it.as_slice())
1355 }
1356 AnyImplId::BuiltinDeriveImplId(id) => {
1357 crate::builtin_derive::impl_super_outlives(self, id)
1358 }
1359 };
1360 bounds.map_bound(|it| it.iter().copied())
1361 }
1362
1363 #[expect(unreachable_code)]
1364 fn const_conditions(
1365 self,
1366 _def_id: Self::DefId,
1367 ) -> EarlyBinder<
1368 Self,
1369 impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>,
1370 > {
1371 EarlyBinder::bind([unimplemented!()])
1372 }
1373
1374 fn has_target_features(self, _def_id: Self::FunctionId) -> bool {
1375 false
1376 }
1377
1378 fn require_projection_lang_item(
1379 self,
1380 lang_item: SolverProjectionLangItem,
1381 ) -> Self::TraitAssocTyId {
1382 self.lang_items()
1383 .get_solver_projection(lang_item)
1384 .expect("Lang item required but not found.")
1385 .into()
1386 }
1387
1388 fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> TraitIdWrapper {
1389 self.lang_items()
1390 .get_solver_trait(lang_item)
1391 .expect("Lang item required but not found.")
1392 .into()
1393 }
1394
1395 fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> AdtIdWrapper {
1396 self.lang_items()
1397 .get_solver_adt(lang_item)
1398 .expect("Lang item required but not found.")
1399 .into()
1400 }
1401
1402 fn is_projection_lang_item(
1403 self,
1404 def_id: Self::TraitAssocTyId,
1405 lang_item: SolverProjectionLangItem,
1406 ) -> bool {
1407 self.lang_items().get_solver_projection(lang_item) == Some(def_id.0)
1408 }
1409
1410 fn is_trait_lang_item(self, def_id: Self::TraitId, lang_item: SolverTraitLangItem) -> bool {
1411 self.lang_items().get_solver_trait(lang_item) == Some(def_id.0)
1412 }
1413
1414 fn is_adt_lang_item(self, def_id: Self::AdtId, lang_item: SolverAdtLangItem) -> bool {
1415 self.lang_items().get_solver_adt(lang_item) == Some(def_id.0)
1416 }
1417
1418 fn as_projection_lang_item(
1419 self,
1420 def_id: Self::TraitAssocTyId,
1421 ) -> Option<SolverProjectionLangItem> {
1422 self.lang_items().get_reverse_solver_projection(def_id.0)
1423 }
1424
1425 fn as_trait_lang_item(self, def_id: Self::TraitId) -> Option<SolverTraitLangItem> {
1426 self.lang_items().get_reverse_solver_trait(def_id.0)
1427 }
1428
1429 fn as_adt_lang_item(self, def_id: Self::AdtId) -> Option<SolverAdtLangItem> {
1430 self.lang_items().get_reverse_solver_adt(def_id.0)
1431 }
1432
1433 fn associated_type_def_ids(
1434 self,
1435 def_id: Self::TraitId,
1436 ) -> impl IntoIterator<Item = Self::DefId> {
1437 def_id.0.trait_items(self.db()).associated_types().map(|id| id.into())
1438 }
1439
1440 fn for_each_relevant_impl<R: VisitorResult>(
1441 self,
1442 trait_def_id: Self::TraitId,
1443 self_ty: Self::Ty,
1444 mut f: impl FnMut(Self::ImplId) -> R,
1445 ) -> R {
1446 let krate = self.krate.expect("trait solving requires setting `DbInterner::krate`");
1447 let trait_block = trait_def_id.0.loc(self.db).container.block(self.db);
1448 let mut consider_impls_for_simplified_type = |simp: SimplifiedType<'_>| {
1449 let type_block = simp.def().and_then(|def_id| {
1450 let module = match def_id {
1451 SolverDefId::AdtId(AdtId::StructId(id)) => id.module(self.db),
1452 SolverDefId::AdtId(AdtId::EnumId(id)) => id.module(self.db),
1453 SolverDefId::AdtId(AdtId::UnionId(id)) => id.module(self.db),
1454 SolverDefId::TraitId(id) => id.module(self.db),
1455 SolverDefId::TypeAliasId(id) => id.module(self.db),
1456 SolverDefId::ConstId(_)
1457 | SolverDefId::FunctionId(_)
1458 | SolverDefId::ImplId(_)
1459 | SolverDefId::BuiltinDeriveImplId(_)
1460 | SolverDefId::StaticId(_)
1461 | SolverDefId::InternedClosureId(_)
1462 | SolverDefId::InternedCoroutineId(_)
1463 | SolverDefId::InternedCoroutineClosureId(_)
1464 | SolverDefId::InternedOpaqueTyId(_)
1465 | SolverDefId::EnumVariantId(_)
1466 | SolverDefId::AnonConstId(_)
1467 | SolverDefId::Ctor(_) => return None,
1468 };
1469 module.block(self.db)
1470 });
1471 TraitImpls::for_each_crate_and_block_trait_and_type(
1472 self.db,
1473 krate,
1474 type_block,
1475 trait_block,
1476 &mut |impls| {
1477 let (regular_impls, builtin_derive_impls) =
1478 impls.for_trait_and_self_ty(trait_def_id.0, &simp);
1479 for &impl_ in regular_impls {
1480 try_visit!(f(impl_.into()));
1481 }
1482 for &impl_ in builtin_derive_impls {
1483 try_visit!(f(impl_.into()));
1484 }
1485 R::output()
1486 },
1487 )
1488 };
1489
1490 match self_ty.kind() {
1491 TyKind::Bool
1492 | TyKind::Char
1493 | TyKind::Int(_)
1494 | TyKind::Uint(_)
1495 | TyKind::Float(_)
1496 | TyKind::Adt(_, _)
1497 | TyKind::Foreign(_)
1498 | TyKind::Str
1499 | TyKind::Array(_, _)
1500 | TyKind::Pat(_, _)
1501 | TyKind::Slice(_)
1502 | TyKind::RawPtr(_, _)
1503 | TyKind::Ref(_, _, _)
1504 | TyKind::FnDef(_, _)
1505 | TyKind::FnPtr(..)
1506 | TyKind::Dynamic(_, _)
1507 | TyKind::Closure(..)
1508 | TyKind::CoroutineClosure(..)
1509 | TyKind::Coroutine(_, _)
1510 | TyKind::Never
1511 | TyKind::Tuple(_)
1512 | TyKind::UnsafeBinder(_) => {
1513 let simp =
1514 fast_reject::simplify_type(self, self_ty, fast_reject::TreatParams::AsRigid)
1515 .unwrap();
1516 try_visit!(consider_impls_for_simplified_type(simp));
1517 }
1518
1519 TyKind::Infer(InferTy::IntVar(_)) => {
1522 use IntTy::*;
1523 use UintTy::*;
1524 let (I8 | I16 | I32 | I64 | I128 | Isize): IntTy;
1526 let (U8 | U16 | U32 | U64 | U128 | Usize): UintTy;
1527 let possible_integers = [
1528 SimplifiedType::Int(I8),
1530 SimplifiedType::Int(I16),
1531 SimplifiedType::Int(I32),
1532 SimplifiedType::Int(I64),
1533 SimplifiedType::Int(I128),
1534 SimplifiedType::Int(Isize),
1535 SimplifiedType::Uint(U8),
1537 SimplifiedType::Uint(U16),
1538 SimplifiedType::Uint(U32),
1539 SimplifiedType::Uint(U64),
1540 SimplifiedType::Uint(U128),
1541 SimplifiedType::Uint(Usize),
1542 ];
1543 for simp in possible_integers {
1544 try_visit!(consider_impls_for_simplified_type(simp));
1545 }
1546 }
1547
1548 TyKind::Infer(InferTy::FloatVar(_)) => {
1549 let (FloatTy::F16 | FloatTy::F32 | FloatTy::F64 | FloatTy::F128);
1551 let possible_floats = [
1552 SimplifiedType::Float(FloatTy::F16),
1553 SimplifiedType::Float(FloatTy::F32),
1554 SimplifiedType::Float(FloatTy::F64),
1555 SimplifiedType::Float(FloatTy::F128),
1556 ];
1557
1558 for simp in possible_floats {
1559 try_visit!(consider_impls_for_simplified_type(simp));
1560 }
1561 }
1562
1563 TyKind::Alias(..) | TyKind::Placeholder(..) | TyKind::Error(_) => (),
1568
1569 TyKind::CoroutineWitness(..) => (),
1573
1574 TyKind::Infer(
1576 InferTy::TyVar(_)
1577 | InferTy::FreshTy(_)
1578 | InferTy::FreshIntTy(_)
1579 | InferTy::FreshFloatTy(_),
1580 )
1581 | TyKind::Param(_)
1582 | TyKind::Bound(_, _) => panic!("unexpected self type: {self_ty:?}"),
1583 }
1584
1585 self.for_each_blanket_impl(trait_def_id, f)
1586 }
1587
1588 fn for_each_blanket_impl<R: VisitorResult>(
1589 self,
1590 trait_def_id: Self::TraitId,
1591 mut f: impl FnMut(Self::ImplId) -> R,
1592 ) -> R {
1593 let Some(krate) = self.krate else {
1594 return R::output();
1595 };
1596 let block = trait_def_id.0.loc(self.db).container.block(self.db);
1597
1598 TraitImpls::for_each_crate_and_block(self.db, krate, block, &mut |impls| {
1599 for &impl_ in impls.blanket_impls(trait_def_id.0) {
1600 try_visit!(f(impl_.into()));
1601 }
1602 R::output()
1603 })
1604 }
1605
1606 fn has_item_definition(self, _def_id: Self::ImplOrTraitAssocTermId) -> bool {
1607 true
1609 }
1610
1611 fn impl_is_default(self, impl_def_id: Self::ImplId) -> bool {
1612 match impl_def_id {
1613 AnyImplId::ImplId(impl_id) => ImplSignature::of(self.db, impl_id).is_default(),
1614 AnyImplId::BuiltinDeriveImplId(_) => false,
1615 }
1616 }
1617
1618 #[tracing::instrument(skip(self), ret)]
1619 fn impl_trait_ref(
1620 self,
1621 impl_id: Self::ImplId,
1622 ) -> EarlyBinder<Self, rustc_type_ir::TraitRef<Self>> {
1623 match impl_id {
1624 AnyImplId::ImplId(impl_id) => {
1625 let db = self.db();
1626 db.impl_trait(impl_id)
1627 .expect("invalid impl passed to trait solver")
1629 }
1630 AnyImplId::BuiltinDeriveImplId(impl_id) => {
1631 crate::builtin_derive::impl_trait(self, impl_id)
1632 }
1633 }
1634 }
1635
1636 fn impl_polarity(self, impl_id: Self::ImplId) -> rustc_type_ir::ImplPolarity {
1637 let AnyImplId::ImplId(impl_id) = impl_id else {
1638 return ImplPolarity::Positive;
1639 };
1640 let impl_data = ImplSignature::of(self.db(), impl_id);
1641 if impl_data.flags.contains(ImplFlags::NEGATIVE) {
1642 ImplPolarity::Negative
1643 } else {
1644 ImplPolarity::Positive
1645 }
1646 }
1647
1648 fn trait_is_auto(self, trait_: Self::TraitId) -> bool {
1649 let trait_data = TraitSignature::of(self.db(), trait_.0);
1650 trait_data.flags.contains(TraitFlags::AUTO)
1651 }
1652
1653 fn trait_is_alias(self, trait_: Self::TraitId) -> bool {
1654 let trait_data = TraitSignature::of(self.db(), trait_.0);
1655 trait_data.flags.contains(TraitFlags::ALIAS)
1656 }
1657
1658 fn trait_is_dyn_compatible(self, trait_: Self::TraitId) -> bool {
1659 crate::dyn_compatibility::dyn_compatibility(self.db(), trait_.0).is_none()
1660 }
1661
1662 fn trait_is_fundamental(self, trait_: Self::TraitId) -> bool {
1663 let trait_data = TraitSignature::of(self.db(), trait_.0);
1664 trait_data.flags.contains(TraitFlags::FUNDAMENTAL)
1665 }
1666
1667 fn is_impl_trait_in_trait(self, _def_id: Self::DefId) -> bool {
1668 false
1670 }
1671
1672 fn delay_bug(self, _msg: impl ToString) -> Self::ErrorGuaranteed {
1673 ErrorGuaranteed
1674 }
1675
1676 fn is_general_coroutine(self, def_id: Self::CoroutineId) -> bool {
1677 matches!(def_id.0.loc(self.db).kind, HirClosureKind::OldCoroutine(_))
1678 }
1679
1680 fn coroutine_is_async(self, def_id: Self::CoroutineId) -> bool {
1681 matches!(
1682 def_id.0.loc(self.db).kind,
1683 HirClosureKind::Coroutine { kind: HirCoroutineKind::Async, .. }
1684 )
1685 }
1686
1687 fn coroutine_is_gen(self, def_id: Self::CoroutineId) -> bool {
1688 matches!(
1689 def_id.0.loc(self.db).kind,
1690 HirClosureKind::Coroutine { kind: HirCoroutineKind::Gen, .. }
1691 )
1692 }
1693
1694 fn coroutine_is_async_gen(self, def_id: Self::CoroutineId) -> bool {
1695 matches!(
1696 def_id.0.loc(self.db).kind,
1697 HirClosureKind::Coroutine { kind: HirCoroutineKind::AsyncGen, .. }
1698 )
1699 }
1700
1701 fn unsizing_params_for_adt(self, id: Self::AdtId) -> Self::UnsizingParams {
1702 let def = AdtDef::new(id.0, self);
1703 let num_params = self.generics_of(id.into()).count();
1704
1705 let maybe_unsizing_param_idx = |arg: GenericArg<'db>| match arg.kind() {
1706 GenericArgKind::Type(ty) => match ty.kind() {
1707 rustc_type_ir::TyKind::Param(p) => Some(p.index),
1708 _ => None,
1709 },
1710 GenericArgKind::Lifetime(_) => None,
1711 GenericArgKind::Const(ct) => match ct.kind() {
1712 rustc_type_ir::ConstKind::Param(p) => Some(p.index),
1713 _ => None,
1714 },
1715 };
1716
1717 let variant = match def.def_id() {
1719 AdtId::StructId(id) => VariantId::from(id),
1720 AdtId::UnionId(id) => id.into(),
1721 AdtId::EnumId(_) => panic!("expected a struct or a union"),
1722 };
1723 let fields = variant.fields(self.db());
1724 let mut prefix_fields = fields.fields().iter();
1725 let Some(tail_field) = prefix_fields.next_back() else {
1726 return UnsizingParams(DenseBitSet::new_empty(num_params));
1727 };
1728
1729 let field_types = self.db().field_types(variant);
1730 let mut unsizing_params = DenseBitSet::new_empty(num_params);
1731 let ty = field_types[tail_field.0].ty();
1732 for arg in ty.instantiate_identity().skip_norm_wip().walk() {
1733 if let Some(i) = maybe_unsizing_param_idx(arg) {
1734 unsizing_params.insert(i);
1735 }
1736 }
1737
1738 for field in prefix_fields {
1741 for arg in field_types[field.0].ty().instantiate_identity().skip_norm_wip().walk() {
1742 if let Some(i) = maybe_unsizing_param_idx(arg) {
1743 unsizing_params.remove(i);
1744 }
1745 }
1746 }
1747
1748 UnsizingParams(unsizing_params)
1749 }
1750
1751 fn anonymize_bound_vars<T: rustc_type_ir::TypeFoldable<Self>>(
1752 self,
1753 value: rustc_type_ir::Binder<Self, T>,
1754 ) -> rustc_type_ir::Binder<Self, T> {
1755 struct Anonymize<'a, 'db> {
1756 interner: DbInterner<'db>,
1757 map: &'a mut FxIndexMap<BoundVar, BoundVariableKind<'db>>,
1758 }
1759 impl<'db> BoundVarReplacerDelegate<'db> for Anonymize<'_, 'db> {
1760 fn replace_region(&mut self, br: BoundRegion<'db>) -> Region<'db> {
1761 let entry = self.map.entry(br.var);
1762 let index = entry.index();
1763 let var = BoundVar::from_usize(index);
1764 let kind = (*entry
1765 .or_insert_with(|| BoundVariableKind::Region(BoundRegionKind::Anon)))
1766 .expect_region();
1767 let br = BoundRegion { var, kind };
1768 Region::new_bound(self.interner, DebruijnIndex::ZERO, br)
1769 }
1770 fn replace_ty(&mut self, bt: BoundTy<'db>) -> Ty<'db> {
1771 let entry = self.map.entry(bt.var);
1772 let index = entry.index();
1773 let var = BoundVar::from_usize(index);
1774 let kind = (*entry.or_insert_with(|| BoundVariableKind::Ty(BoundTyKind::Anon)))
1775 .expect_ty();
1776 Ty::new_bound(self.interner, DebruijnIndex::ZERO, BoundTy { var, kind })
1777 }
1778 fn replace_const(&mut self, bv: BoundConst<'db>) -> Const<'db> {
1779 let entry = self.map.entry(bv.var);
1780 let index = entry.index();
1781 let var = BoundVar::from_usize(index);
1782 let () = (*entry.or_insert_with(|| BoundVariableKind::Const)).expect_const();
1783 Const::new_bound(self.interner, DebruijnIndex::ZERO, BoundConst::new(var))
1784 }
1785 }
1786
1787 let mut map = Default::default();
1788 let delegate = Anonymize { interner: self, map: &mut map };
1789 let inner = self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate);
1790 let bound_vars = BoundVarKinds::new_from_iter(map.into_values());
1791 Binder::bind_with_vars(inner, bound_vars)
1792 }
1793
1794 fn opaque_types_defined_by(self, def_id: Self::LocalDefId) -> Self::LocalDefIds {
1795 let Ok(def_id) = InferBodyId::try_from(def_id) else {
1796 return SolverDefIds::default();
1797 };
1798 let mut result = Vec::new();
1799 crate::opaques::opaque_types_defined_by(self.db, def_id, &mut result);
1800 SolverDefIds::new_from_slice(&result)
1801 }
1802
1803 fn opaque_types_and_coroutines_defined_by(self, def_id: Self::LocalDefId) -> Self::LocalDefIds {
1804 let db = self.db;
1805
1806 let Ok(def_id) = InferBodyId::try_from(def_id) else {
1807 return SolverDefIds::default();
1808 };
1809 let mut result = Vec::new();
1810
1811 crate::opaques::opaque_types_defined_by(db, def_id, &mut result);
1812
1813 let (store, root_expr) = def_id.store_and_root_expr(db);
1815 CoroutinesVisitor { db: self.db, owner: def_id, store, coroutines: &mut result }
1817 .on_expr(root_expr);
1818
1819 return SolverDefIds::new_from_slice(&result);
1820
1821 struct CoroutinesVisitor<'a, 'db> {
1822 db: &'db dyn HirDatabase,
1823 owner: InferBodyId<'db>,
1824 store: &'db ExpressionStore,
1825 coroutines: &'a mut Vec<SolverDefId<'db>>,
1826 }
1827
1828 impl<'db> StoreVisitor for CoroutinesVisitor<'_, 'db> {
1829 fn on_expr(&mut self, expr: ExprId) {
1830 if let hir_def::hir::Expr::Closure {
1831 closure_kind:
1832 kind @ (hir_def::hir::ClosureKind::Coroutine { .. }
1833 | hir_def::hir::ClosureKind::OldCoroutine(_)),
1834 ..
1835 } = self.store[expr]
1836 {
1837 let coroutine = InternedCoroutineId::new(
1838 self.db,
1839 InternedClosure { owner: self.owner, expr, kind },
1840 );
1841 self.coroutines.push(coroutine.into());
1842 }
1843
1844 self.store.visit_expr_children(expr, self);
1845 }
1846 fn on_pat(&mut self, pat: PatId) {
1847 self.store.visit_pat_children(pat, self);
1848 }
1849 fn on_anon_const_expr(&mut self, _expr: ExprId) {}
1851 }
1852 }
1853
1854 fn alias_has_const_conditions(self, _def_id: Self::DefId) -> bool {
1855 false
1857 }
1858
1859 fn explicit_implied_const_bounds(
1860 self,
1861 _def_id: Self::DefId,
1862 ) -> EarlyBinder<
1863 Self,
1864 impl IntoIterator<Item = rustc_type_ir::Binder<Self, rustc_type_ir::TraitRef<Self>>>,
1865 > {
1866 EarlyBinder::bind([])
1868 }
1869
1870 fn fn_is_const(self, id: Self::FunctionId) -> bool {
1871 let id = match id.0 {
1872 CallableDefId::FunctionId(id) => id,
1873 _ => return false,
1874 };
1875 FunctionSignature::of(self.db(), id).flags.contains(FnFlags::CONST)
1876 }
1877
1878 fn impl_is_const(self, _def_id: Self::ImplId) -> bool {
1879 false
1880 }
1881
1882 fn opt_alias_variances(
1883 self,
1884 _kind: impl Into<AliasTermKind<'db>>,
1885 ) -> Option<Self::VariancesOf> {
1886 None
1887 }
1888
1889 fn type_of_opaque_hir_typeck(
1890 self,
1891 opaque: Self::LocalOpaqueTyId,
1892 ) -> EarlyBinder<Self, Self::Ty> {
1893 let impl_trait_id = opaque.0.loc(self.db);
1894 let hidden_type = match impl_trait_id {
1897 crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => {
1898 crate::opaques::rpit_hidden_types(self.db, func).get(idx)
1899 }
1900 crate::ImplTraitId::TypeAliasImplTrait(type_alias, idx) => {
1901 crate::opaques::tait_hidden_types(self.db, type_alias).get(idx)
1902 }
1903 };
1904 match hidden_type {
1905 Some(hidden_type) => hidden_type.get(),
1906 None => EarlyBinder::bind(Ty::new_error(self, ErrorGuaranteed)),
1907 }
1908 }
1909
1910 fn coroutine_hidden_types(
1911 self,
1912 _def_id: Self::CoroutineId,
1913 ) -> EarlyBinder<Self, Binder<'db, CoroutineWitnessTypes<Self>>> {
1914 EarlyBinder::bind(Binder::dummy(CoroutineWitnessTypes {
1916 types: Tys::default(),
1917 assumptions: RegionAssumptions::default(),
1918 }))
1919 }
1920
1921 fn is_default_trait(self, def_id: Self::TraitId) -> bool {
1922 self.as_trait_lang_item(def_id).map_or(false, |l| matches!(l, SolverTraitLangItem::Sized))
1923 }
1924
1925 fn trait_is_coinductive(self, trait_: Self::TraitId) -> bool {
1926 TraitSignature::of(self.db(), trait_.0).flags.contains(TraitFlags::COINDUCTIVE)
1927 }
1928
1929 fn trait_is_unsafe(self, trait_: Self::TraitId) -> bool {
1930 TraitSignature::of(self.db(), trait_.0).flags.contains(TraitFlags::UNSAFE)
1931 }
1932
1933 fn impl_self_is_guaranteed_unsized(self, _def_id: Self::ImplId) -> bool {
1934 false
1935 }
1936
1937 fn impl_specializes(
1938 self,
1939 specializing_impl_def_id: Self::ImplId,
1940 parent_impl_def_id: Self::ImplId,
1941 ) -> bool {
1942 let (AnyImplId::ImplId(specializing_impl_def_id), AnyImplId::ImplId(parent_impl_def_id)) =
1943 (specializing_impl_def_id, parent_impl_def_id)
1944 else {
1945 return false;
1947 };
1948 crate::specialization::specializes(self.db, specializing_impl_def_id, parent_impl_def_id)
1949 }
1950
1951 fn next_trait_solver_globally(self) -> bool {
1952 true
1953 }
1954
1955 type Probe = rustc_type_ir::solve::inspect::Probe<DbInterner<'db>>;
1956 fn mk_probe(self, probe: rustc_type_ir::solve::inspect::Probe<Self>) -> Self::Probe {
1957 probe
1958 }
1959 fn evaluate_root_goal_for_proof_tree_raw(
1960 self,
1961 canonical_goal: rustc_type_ir::solve::CanonicalInput<Self>,
1962 ) -> (rustc_type_ir::solve::QueryResult<Self>, Self::Probe) {
1963 rustc_next_trait_solver::solve::evaluate_root_goal_for_proof_tree_raw_provider::<
1964 SolverContext<'db>,
1965 Self,
1966 >(self, canonical_goal)
1967 }
1968
1969 fn is_sizedness_trait(self, def_id: Self::TraitId) -> bool {
1970 matches!(
1971 self.as_trait_lang_item(def_id),
1972 Some(SolverTraitLangItem::Sized | SolverTraitLangItem::MetaSized)
1973 )
1974 }
1975
1976 fn const_of_item(self, def_id: Self::DefId) -> rustc_type_ir::EarlyBinder<Self, Self::Const> {
1977 let id = match def_id {
1978 SolverDefId::StaticId(id) => id.into(),
1979 SolverDefId::ConstId(id) => id.into(),
1980 _ => unreachable!(),
1981 };
1982 EarlyBinder::bind(Const::new_unevaluated(
1983 self,
1984 UnevaluatedConst { def: GeneralConstIdWrapper(id), args: GenericArgs::empty() },
1985 ))
1986 }
1987
1988 fn anon_const_kind(self, _def_id: Self::DefId) -> rustc_type_ir::AnonConstKind {
1989 rustc_type_ir::AnonConstKind::GCE
1991 }
1992
1993 fn alias_ty_kind_from_def_id(self, def_id: Self::DefId) -> AliasTyKind<'db> {
1994 match def_id {
1995 SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container {
1996 ItemContainerId::ExternBlockId(_) | ItemContainerId::ModuleId(_) => {
1997 AliasTyKind::Free { def_id: type_alias.into() }
1998 }
1999 ItemContainerId::ImplId(_) => AliasTyKind::Inherent { def_id: type_alias.into() },
2000 ItemContainerId::TraitId(_) => {
2001 AliasTyKind::Projection { def_id: type_alias.into() }
2002 }
2003 },
2004 SolverDefId::InternedOpaqueTyId(def_id) => {
2005 AliasTyKind::Opaque { def_id: def_id.into() }
2006 }
2007 _ => unreachable!(),
2008 }
2009 }
2010
2011 fn closure_is_const(self, _def_id: Self::ClosureId) -> bool {
2012 false
2014 }
2015
2016 fn item_name(self, _item_index: Self::DefId) -> Self::Symbol {
2017 Symbol
2018 }
2019}
2020
2021fn is_ty_self(ty: Ty<'_>) -> bool {
2022 match ty.kind() {
2023 TyKind::Param(param) => param.index == 0,
2024 _ => false,
2025 }
2026}
2027fn is_clause_at_ty(p: &Clause<'_>, filter: impl FnOnce(Ty<'_>) -> bool) -> bool {
2028 match p.kind().skip_binder() {
2029 ClauseKind::Trait(it) => filter(it.self_ty()),
2032 ClauseKind::TypeOutlives(it) => filter(it.0),
2033 ClauseKind::Projection(it) => filter(it.self_ty()),
2034 ClauseKind::HostEffect(it) => filter(it.self_ty()),
2035 _ => false,
2036 }
2037}
2038
2039impl<'db> DbInterner<'db> {
2040 pub fn shift_bound_var_indices<T>(self, bound_vars: usize, value: T) -> T
2041 where
2042 T: rustc_type_ir::TypeFoldable<Self>,
2043 {
2044 let shift_bv = |bv: BoundVar| BoundVar::from_usize(bv.as_usize() + bound_vars);
2045 self.replace_escaping_bound_vars_uncached(
2046 value,
2047 FnMutDelegate {
2048 regions: &mut |r: BoundRegion<'db>| {
2049 Region::new_bound(
2050 self,
2051 DebruijnIndex::ZERO,
2052 BoundRegion { var: shift_bv(r.var), kind: r.kind },
2053 )
2054 },
2055 types: &mut |t: BoundTy<'db>| {
2056 Ty::new_bound(
2057 self,
2058 DebruijnIndex::ZERO,
2059 BoundTy { var: shift_bv(t.var), kind: t.kind },
2060 )
2061 },
2062 consts: &mut |c| {
2063 Const::new_bound(self, DebruijnIndex::ZERO, BoundConst::new(shift_bv(c.var)))
2064 },
2065 },
2066 )
2067 }
2068
2069 pub fn replace_escaping_bound_vars_uncached<T: rustc_type_ir::TypeFoldable<DbInterner<'db>>>(
2070 self,
2071 value: T,
2072 delegate: impl BoundVarReplacerDelegate<'db>,
2073 ) -> T {
2074 if !value.has_escaping_bound_vars() {
2075 value
2076 } else {
2077 let mut replacer = BoundVarReplacer::new(self, delegate);
2078 value.fold_with(&mut replacer)
2079 }
2080 }
2081
2082 pub fn replace_bound_vars_uncached<T: rustc_type_ir::TypeFoldable<DbInterner<'db>>>(
2083 self,
2084 value: Binder<'db, T>,
2085 delegate: impl BoundVarReplacerDelegate<'db>,
2086 ) -> T {
2087 self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate)
2088 }
2089
2090 pub fn mk_fn_sig<I>(
2092 self,
2093 inputs: I,
2094 output: Ty<'db>,
2095 c_variadic: bool,
2096 safety: Safety,
2097 abi: ExternAbi,
2098 ) -> FnSig<'db>
2099 where
2100 I: IntoIterator<Item = Ty<'db>>,
2101 {
2102 FnSig {
2103 inputs_and_output: Tys::new_from_iter(
2104 inputs.into_iter().chain(std::iter::once(output)),
2105 ),
2106 fn_sig_kind: FnSigKind::new(abi, safety, c_variadic),
2107 }
2108 }
2109
2110 pub fn mk_fn_sig_safe_rust_abi<I>(self, inputs: I, output: Ty<'db>) -> FnSig<'db>
2112 where
2113 I: IntoIterator<Item = Ty<'db>>,
2114 {
2115 self.mk_fn_sig(inputs, output, false, Safety::Safe, ExternAbi::Rust)
2116 }
2117}
2118
2119fn predicates_of<'db>(
2120 db: &'db dyn HirDatabase,
2121 def_id: SolverDefId<'db>,
2122) -> &'db GenericPredicates {
2123 match def_id {
2124 SolverDefId::BuiltinDeriveImplId(impl_) => crate::builtin_derive::predicates(db, impl_),
2125 SolverDefId::AnonConstId(anon_const) => {
2126 let loc = anon_const.loc(db);
2127 if loc.allow_using_generic_params {
2128 GenericPredicates::query(db, loc.owner.generic_def(db))
2129 } else {
2130 GenericPredicates::empty()
2131 }
2132 }
2133 _ => GenericPredicates::query(db, def_id.try_into().unwrap()),
2134 }
2135}
2136
2137macro_rules! TrivialTypeTraversalImpls {
2138 ($($ty:ty,)+) => {
2139 $(
2140 impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for $ty {
2141 fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
2142 self,
2143 _: &mut F,
2144 ) -> ::std::result::Result<Self, F::Error> {
2145 Ok(self)
2146 }
2147
2148 #[inline]
2149 fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(
2150 self,
2151 _: &mut F,
2152 ) -> Self {
2153 self
2154 }
2155 }
2156
2157 impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for $ty {
2158 #[inline]
2159 fn visit_with<F: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
2160 &self,
2161 _: &mut F)
2162 -> F::Result
2163 {
2164 <F::Result as rustc_ast_ir::visit::VisitorResult>::output()
2165 }
2166 }
2167
2168 impl<V> rustc_type_ir::GenericTypeVisitable<V> for $ty {
2169 #[inline]
2170 fn generic_visit_with(&self, _visitor: &mut V) {}
2171 }
2172 )+
2173 };
2174}
2175
2176TrivialTypeTraversalImpls! {
2177 SolverDefId<'_>,
2178 TraitIdWrapper,
2179 TypeAliasIdWrapper,
2180 CallableIdWrapper,
2181 ClosureIdWrapper<'_>,
2182 CoroutineIdWrapper<'_>,
2183 CoroutineClosureIdWrapper<'_>,
2184 AdtIdWrapper,
2185 TraitAssocTyId,
2186 TraitAssocConstId,
2187 TraitAssocTermId,
2188 ImplOrTraitAssocTyId,
2189 ImplOrTraitAssocConstId,
2190 ImplOrTraitAssocTermId,
2191 FreeTyAliasId,
2192 FreeConstAliasId,
2193 FreeTermAliasId,
2194 InherentAssocTyId,
2195 InherentAssocConstId,
2196 InherentAssocTermId,
2197 OpaqueTyIdWrapper<'_>,
2198 AnyImplId,
2199 GeneralConstIdWrapper<'_>,
2200 Safety,
2201 Span,
2202 ParamConst,
2203 ParamTy,
2204 EarlyParamRegion,
2205 AdtDef,
2206 ScalarInt,
2207}
2208
2209mod tls_db {
2210 use std::{cell::Cell, ptr::NonNull};
2211
2212 use crate::db::HirDatabase;
2213
2214 struct Attached {
2215 database: Cell<Option<NonNull<dyn HirDatabase>>>,
2216 }
2217
2218 impl Attached {
2219 #[inline]
2220 fn attach<R>(&self, db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2221 struct DbGuard<'s> {
2222 state: Option<&'s Attached>,
2223 }
2224
2225 impl<'s> DbGuard<'s> {
2226 #[inline]
2227 fn new(attached: &'s Attached, db: &dyn HirDatabase) -> Self {
2228 match attached.database.get() {
2229 Some(current_db) => {
2230 let new_db = NonNull::from(db);
2231 if !std::ptr::addr_eq(current_db.as_ptr(), new_db.as_ptr()) {
2232 panic!(
2233 "Cannot change attached database. This is likely a bug.\n\
2234 If this is not a bug, you can use `attach_db_allow_change()`."
2235 );
2236 }
2237 Self { state: None }
2238 }
2239 None => {
2240 attached.database.set(Some(NonNull::from(db)));
2242 Self { state: Some(attached) }
2243 }
2244 }
2245 }
2246 }
2247
2248 impl Drop for DbGuard<'_> {
2249 #[inline]
2250 fn drop(&mut self) {
2251 if let Some(attached) = self.state {
2253 attached.database.set(None);
2254 }
2255 }
2256 }
2257
2258 let _guard = DbGuard::new(self, db);
2259 super::tls_cache::reinit_cache(db);
2260 op()
2261 }
2262
2263 #[inline]
2264 fn attach_allow_change<R>(&self, db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2265 struct DbGuard<'s> {
2266 state: &'s Attached,
2267 prev: Option<NonNull<dyn HirDatabase>>,
2268 }
2269
2270 impl<'s> DbGuard<'s> {
2271 #[inline]
2272 fn new(attached: &'s Attached, db: &dyn HirDatabase) -> Self {
2273 let prev = attached.database.replace(Some(NonNull::from(db)));
2274 Self { state: attached, prev }
2275 }
2276 }
2277
2278 impl Drop for DbGuard<'_> {
2279 #[inline]
2280 fn drop(&mut self) {
2281 self.state.database.set(self.prev);
2282 if let Some(prev) = self.prev {
2283 super::tls_cache::reinit_cache(unsafe { prev.as_ref() });
2284 }
2285 }
2286 }
2287
2288 let _guard = DbGuard::new(self, db);
2289 super::tls_cache::reinit_cache(db);
2290 op()
2291 }
2292
2293 #[inline]
2294 fn with<R>(&self, op: impl FnOnce(&dyn HirDatabase) -> R) -> R {
2295 let db = self.database.get().expect("Tried to use attached db, but no db is attached");
2296
2297 op(unsafe { db.as_ref() })
2299 }
2300 }
2301
2302 thread_local! {
2303 static GLOBAL_DB: Attached = const { Attached { database: Cell::new(None) } };
2304 }
2305
2306 #[inline]
2307 pub fn attach_db<R>(db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2308 GLOBAL_DB.with(|global_db| global_db.attach(db, op))
2309 }
2310
2311 #[inline]
2312 pub fn attach_db_allow_change<R>(db: &dyn HirDatabase, op: impl FnOnce() -> R) -> R {
2313 GLOBAL_DB.with(|global_db| global_db.attach_allow_change(db, op))
2314 }
2315
2316 #[inline]
2317 pub fn with_attached_db<R>(op: impl FnOnce(&dyn HirDatabase) -> R) -> R {
2318 GLOBAL_DB.with(
2319 #[inline]
2320 |a| a.with(op),
2321 )
2322 }
2323}
2324
2325mod tls_cache {
2326 use crate::db::HirDatabase;
2327
2328 use super::DbInterner;
2329 use base_db::Nonce;
2330 use rustc_type_ir::search_graph::GlobalCache;
2331 use salsa::Revision;
2332 use std::cell::RefCell;
2333
2334 struct Cache {
2335 cache: GlobalCache<DbInterner<'static>>,
2336 revision: Revision,
2337 db_nonce: Nonce,
2338 }
2339
2340 impl Cache {
2341 const fn default() -> Cache {
2342 Cache {
2343 cache: GlobalCache::new(),
2344 revision: Revision::max(),
2345 db_nonce: Nonce::invalid(),
2346 }
2347 }
2348 }
2349
2350 thread_local! {
2351 static GLOBAL_CACHE: RefCell<Cache> = const { RefCell::new(Cache::default()) };
2352 }
2353
2354 pub(super) fn reinit_cache(db: &dyn HirDatabase) {
2355 GLOBAL_CACHE.with_borrow_mut(|handle| {
2356 let (db_nonce, revision) = db.nonce_and_revision();
2357 if handle.revision != revision || db_nonce != handle.db_nonce {
2358 *handle = Cache { cache: GlobalCache::default(), revision, db_nonce };
2359 }
2360 })
2361 }
2362
2363 #[inline]
2364 pub(super) fn borrow_assume_valid<'db, T>(
2365 db: &'db dyn HirDatabase,
2366 f: impl FnOnce(&mut GlobalCache<DbInterner<'db>>) -> T,
2367 ) -> T {
2368 if cfg!(debug_assertions) {
2369 let get_state =
2370 || GLOBAL_CACHE.with_borrow(|handle| (handle.db_nonce, handle.revision));
2371 let old_state = get_state();
2372 reinit_cache(db);
2373 let new_state = get_state();
2374 assert_eq!(old_state, new_state, "you assumed the cache is valid!");
2375 }
2376
2377 GLOBAL_CACHE.with_borrow_mut(|handle| {
2378 f(unsafe {
2380 std::mem::transmute::<
2381 &mut GlobalCache<DbInterner<'static>>,
2382 &mut GlobalCache<DbInterner<'db>>,
2383 >(&mut handle.cache)
2384 })
2385 })
2386 }
2387
2388 pub fn clear_tls_solver_cache() {
2393 GLOBAL_CACHE.with_borrow_mut(|handle| *handle = Cache::default());
2394 }
2395}
2396
2397impl WorldExposer for intern::GarbageCollector {
2398 fn on_interned<T: intern::Internable>(
2399 &mut self,
2400 interned: InternedRef<'_, T>,
2401 ) -> ControlFlow<()> {
2402 self.mark_interned_alive(interned)
2403 }
2404
2405 fn on_interned_slice<T: intern::SliceInternable>(
2406 &mut self,
2407 interned: InternedSliceRef<'_, T>,
2408 ) -> ControlFlow<()> {
2409 self.mark_interned_slice_alive(interned)
2410 }
2411}
2412
2413pub unsafe fn collect_ty_garbage() {
2419 let mut gc = intern::GarbageCollector::default();
2420
2421 gc.add_storage::<super::consts::ConstInterned>();
2422 gc.add_storage::<super::consts::ValTreeInterned>();
2423 gc.add_storage::<super::allocation::AllocationInterned>();
2424 gc.add_storage::<PatternInterned>();
2425 gc.add_storage::<super::opaques::ExternalConstraintsInterned>();
2426 gc.add_storage::<super::predicate::PredicateInterned>();
2427 gc.add_storage::<super::region::RegionInterned>();
2428 gc.add_storage::<super::ty::TyInterned>();
2429
2430 gc.add_slice_storage::<super::consts::ConstsStorage>();
2431 gc.add_slice_storage::<super::predicate::ClausesStorage>();
2432 gc.add_slice_storage::<super::generic_arg::GenericArgsStorage>();
2433 gc.add_slice_storage::<BoundVarKindsStorage>();
2434 gc.add_slice_storage::<VariancesOfStorage>();
2435 gc.add_slice_storage::<CanonicalVarsStorage>();
2436 gc.add_slice_storage::<PatListStorage>();
2437 gc.add_slice_storage::<super::opaques::PredefinedOpaquesStorage>();
2438 gc.add_slice_storage::<super::opaques::SolverDefIdsStorage>();
2439 gc.add_slice_storage::<super::predicate::BoundExistentialPredicatesStorage>();
2440 gc.add_slice_storage::<super::region::RegionAssumptionsStorage>();
2441 gc.add_slice_storage::<super::ty::TysStorage>();
2442 gc.add_slice_storage::<crate::mir::ProjectionStorage>();
2443
2444 unsafe { gc.collect() };
2449}
2450
2451macro_rules! impl_gc_visit {
2452 ( $($ty:ty),* $(,)? ) => {
2453 $(
2454 impl ::intern::GcInternedVisit for $ty {
2455 #[inline]
2456 fn visit_with(&self, gc: &mut ::intern::GarbageCollector) {
2457 self.generic_visit_with(gc);
2458 }
2459 }
2460 )*
2461 };
2462}
2463
2464impl_gc_visit!(
2465 super::consts::ConstInterned,
2466 super::consts::ValTreeInterned,
2467 super::allocation::AllocationInterned,
2468 PatternInterned,
2469 super::opaques::ExternalConstraintsInterned,
2470 super::predicate::PredicateInterned,
2471 super::region::RegionInterned,
2472 super::ty::TyInterned,
2473 super::predicate::ClausesCachedTypeInfo,
2474);
2475
2476macro_rules! impl_gc_visit_slice {
2477 ( $($ty:ty),* $(,)? ) => {
2478 $(
2479 impl ::intern::GcInternedSliceVisit for $ty {
2480 #[inline]
2481 fn visit_header(header: &<Self as ::intern::SliceInternable>::Header, gc: &mut ::intern::GarbageCollector) {
2482 header.generic_visit_with(gc);
2483 }
2484
2485 #[inline]
2486 fn visit_slice(slice: &[<Self as ::intern::SliceInternable>::SliceType], gc: &mut ::intern::GarbageCollector) {
2487 slice.generic_visit_with(gc);
2488 }
2489 }
2490 )*
2491 };
2492}
2493
2494impl_gc_visit_slice!(
2495 super::predicate::ClausesStorage,
2496 super::generic_arg::GenericArgsStorage,
2497 BoundVarKindsStorage,
2498 VariancesOfStorage,
2499 CanonicalVarsStorage,
2500 PatListStorage,
2501 super::opaques::PredefinedOpaquesStorage,
2502 super::opaques::SolverDefIdsStorage,
2503 super::predicate::BoundExistentialPredicatesStorage,
2504 super::region::RegionAssumptionsStorage,
2505 super::ty::TysStorage,
2506 super::consts::ConstsStorage,
2507 crate::mir::ProjectionStorage,
2508);