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