1#![deny(rust_2018_idioms)]
4#![warn(missing_docs)]
5
6extern crate self as chalk_ir;
8
9use crate::cast::{Cast, CastTo, Caster};
10use crate::fold::shift::Shift;
11use crate::fold::{FallibleTypeFolder, Subst, TypeFoldable, TypeFolder, TypeSuperFoldable};
12use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor, VisitExt};
13use chalk_derive::{
14 FallibleTypeFolder, HasInterner, TypeFoldable, TypeSuperVisitable, TypeVisitable, Zip,
15};
16use std::marker::PhantomData;
17use std::ops::ControlFlow;
18
19pub use crate::debug::SeparatorTraitRef;
20#[macro_use(bitflags)]
21extern crate bitflags;
22#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
24pub enum Void {}
25
26pub type Fallible<T> = Result<T, NoSolution>;
29
30pub enum FallibleOrFloundered<T> {
32 Ok(T),
34 NoSolution,
36 Floundered,
38}
39
40#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
43pub struct NoSolution;
44
45pub struct Floundered;
48
49macro_rules! impl_debugs {
50 ($($id:ident), *) => {
51 $(
52 impl<I: Interner> std::fmt::Debug for $id<I> {
53 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
54 write!(fmt, "{}({:?})", stringify!($id), self.0)
55 }
56 }
57 )*
58 };
59}
60
61#[macro_use]
62pub mod zip;
63
64#[macro_use]
65pub mod fold;
66
67#[macro_use]
68pub mod visit;
69
70pub mod cast;
71
72pub mod interner;
73use interner::{HasInterner, Interner};
74
75pub mod could_match;
76pub mod debug;
77
78#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
80pub enum Variance {
81 Covariant,
83 Invariant,
85 Contravariant,
87}
88
89impl Variance {
90 pub fn xform(self, other: Variance) -> Variance {
132 match (self, other) {
133 (Variance::Invariant, _) => Variance::Invariant,
134 (_, Variance::Invariant) => Variance::Invariant,
135 (_, Variance::Covariant) => self,
136 (Variance::Covariant, Variance::Contravariant) => Variance::Contravariant,
137 (Variance::Contravariant, Variance::Contravariant) => Variance::Covariant,
138 }
139 }
140
141 pub fn invert(self) -> Variance {
144 match self {
145 Variance::Invariant => Variance::Invariant,
146 Variance::Covariant => Variance::Contravariant,
147 Variance::Contravariant => Variance::Covariant,
148 }
149 }
150}
151
152#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
153pub struct Environment<I: Interner> {
156 pub clauses: ProgramClauses<I>,
158}
159
160impl<I: Interner> Copy for Environment<I> where I::InternedProgramClauses: Copy {}
161
162impl<I: Interner> Environment<I> {
163 pub fn new(interner: I) -> Self {
165 Environment {
166 clauses: ProgramClauses::empty(interner),
167 }
168 }
169
170 pub fn add_clauses<II>(&self, interner: I, clauses: II) -> Self
172 where
173 II: IntoIterator<Item = ProgramClause<I>>,
174 {
175 let mut env = self.clone();
176 env.clauses =
177 ProgramClauses::from_iter(interner, env.clauses.iter(interner).cloned().chain(clauses));
178 env
179 }
180
181 pub fn has_compatible_clause(&self, interner: I) -> bool {
184 self.clauses.as_slice(interner).iter().any(|c| {
185 let ProgramClauseData(implication) = c.data(interner);
186 match implication.skip_binders().consequence {
187 DomainGoal::Compatible => {
188 assert!(implication.skip_binders().conditions.is_empty(interner));
192 assert!(implication.skip_binders().constraints.is_empty(interner));
193 true
194 }
195 _ => false,
196 }
197 })
198 }
199}
200
201#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
203#[allow(missing_docs)]
204pub struct InEnvironment<G: HasInterner> {
205 pub environment: Environment<G::Interner>,
206 pub goal: G,
207}
208
209impl<G: HasInterner<Interner = I> + Copy, I: Interner> Copy for InEnvironment<G> where
210 I::InternedProgramClauses: Copy
211{
212}
213
214impl<G: HasInterner> InEnvironment<G> {
215 pub fn new(environment: &Environment<G::Interner>, goal: G) -> Self {
217 InEnvironment {
218 environment: environment.clone(),
219 goal,
220 }
221 }
222
223 pub fn map<OP, H>(self, op: OP) -> InEnvironment<H>
225 where
226 OP: FnOnce(G) -> H,
227 H: HasInterner<Interner = G::Interner>,
228 {
229 InEnvironment {
230 environment: self.environment,
231 goal: op(self.goal),
232 }
233 }
234}
235
236impl<G: HasInterner> HasInterner for InEnvironment<G> {
237 type Interner = G::Interner;
238}
239
240#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
242#[allow(missing_docs)]
243pub enum IntTy {
244 Isize,
245 I8,
246 I16,
247 I32,
248 I64,
249 I128,
250}
251
252#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
254#[allow(missing_docs)]
255pub enum UintTy {
256 Usize,
257 U8,
258 U16,
259 U32,
260 U64,
261 U128,
262}
263
264#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
266#[allow(missing_docs)]
267pub enum FloatTy {
268 F16,
269 F32,
270 F64,
271 F128,
272}
273
274#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
276#[allow(missing_docs)]
277pub enum Scalar {
278 Bool,
279 Char,
280 Int(IntTy),
281 Uint(UintTy),
282 Float(FloatTy),
283}
284
285#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
287pub enum Safety {
288 Safe,
290 Unsafe,
292}
293
294#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
296pub enum Mutability {
297 Mut,
299 Not,
301}
302
303#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
311pub struct UniverseIndex {
312 pub counter: usize,
314}
315
316impl UniverseIndex {
317 pub const ROOT: UniverseIndex = UniverseIndex { counter: 0 };
319
320 pub fn root() -> UniverseIndex {
322 Self::ROOT
323 }
324
325 pub fn can_see(self, ui: UniverseIndex) -> bool {
327 self.counter >= ui.counter
328 }
329
330 pub fn next(self) -> UniverseIndex {
332 UniverseIndex {
333 counter: self.counter + 1,
334 }
335 }
336}
337
338#[derive(Clone, Debug)]
344pub struct UniverseMap {
345 pub universes: Vec<UniverseIndex>,
349}
350
351impl UniverseMap {
352 pub fn new() -> Self {
354 UniverseMap {
355 universes: vec![UniverseIndex::root()],
356 }
357 }
358
359 pub fn num_canonical_universes(&self) -> usize {
361 self.universes.len()
362 }
363}
364
365#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
367pub struct AdtId<I: Interner>(pub I::InternedAdtId);
368
369#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
374pub struct TraitId<I: Interner>(pub I::DefId);
375
376#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
378pub struct ImplId<I: Interner>(pub I::DefId);
379
380#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
382pub struct ClauseId<I: Interner>(pub I::DefId);
383
384#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
389pub struct AssocTypeId<I: Interner>(pub I::DefId);
390
391#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
393pub struct OpaqueTyId<I: Interner>(pub I::DefId);
394
395#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
397pub struct FnDefId<I: Interner>(pub I::DefId);
398
399#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
401pub struct ClosureId<I: Interner>(pub I::DefId);
402
403#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
405pub struct CoroutineId<I: Interner>(pub I::DefId);
406
407#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
409pub struct ForeignDefId<I: Interner>(pub I::DefId);
410
411impl_debugs!(ImplId, ClauseId);
412
413#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
415pub struct Ty<I: Interner> {
416 interned: I::InternedType,
417}
418
419impl<I: Interner> Ty<I> {
420 pub fn new(interner: I, data: impl CastTo<TyKind<I>>) -> Self {
422 let ty_kind = data.cast(interner);
423 Ty {
424 interned: I::intern_ty(interner, ty_kind),
425 }
426 }
427
428 pub fn interned(&self) -> &I::InternedType {
430 &self.interned
431 }
432
433 pub fn data(&self, interner: I) -> &TyData<I> {
435 I::ty_data(interner, &self.interned)
436 }
437
438 pub fn kind(&self, interner: I) -> &TyKind<I> {
440 &I::ty_data(interner, &self.interned).kind
441 }
442
443 pub fn from_env(&self) -> FromEnv<I> {
445 FromEnv::Ty(self.clone())
446 }
447
448 pub fn well_formed(&self) -> WellFormed<I> {
450 WellFormed::Ty(self.clone())
451 }
452
453 pub fn into_from_env_goal(self, interner: I) -> DomainGoal<I> {
455 self.from_env().cast(interner)
456 }
457
458 pub fn bound_var(&self, interner: I) -> Option<BoundVar> {
460 if let TyKind::BoundVar(bv) = self.kind(interner) {
461 Some(*bv)
462 } else {
463 None
464 }
465 }
466
467 pub fn inference_var(&self, interner: I) -> Option<InferenceVar> {
469 if let TyKind::InferenceVar(depth, _) = self.kind(interner) {
470 Some(*depth)
471 } else {
472 None
473 }
474 }
475
476 pub fn is_general_var(&self, interner: I, binders: &CanonicalVarKinds<I>) -> bool {
478 match self.kind(interner) {
479 TyKind::BoundVar(bv)
480 if bv.debruijn == DebruijnIndex::INNERMOST
481 && binders.at(interner, bv.index).kind
482 == VariableKind::Ty(TyVariableKind::General) =>
483 {
484 true
485 }
486 TyKind::InferenceVar(_, TyVariableKind::General) => true,
487 _ => false,
488 }
489 }
490
491 pub fn is_alias(&self, interner: I) -> bool {
493 matches!(self.kind(interner), TyKind::Alias(..))
494 }
495
496 pub fn is_integer(&self, interner: I) -> bool {
498 matches!(
499 self.kind(interner),
500 TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_))
501 )
502 }
503
504 pub fn is_float(&self, interner: I) -> bool {
506 matches!(self.kind(interner), TyKind::Scalar(Scalar::Float(_)))
507 }
508
509 pub fn adt_id(&self, interner: I) -> Option<AdtId<I>> {
511 match self.kind(interner) {
512 TyKind::Adt(adt_id, _) => Some(*adt_id),
513 _ => None,
514 }
515 }
516
517 pub fn needs_shift(&self, interner: I) -> bool {
521 self.has_free_vars(interner)
522 }
523}
524
525#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
527pub struct TyData<I: Interner> {
528 pub kind: TyKind<I>,
530 pub flags: TypeFlags,
532}
533
534bitflags! {
535 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
537 pub struct TypeFlags : u16 {
538 const HAS_TY_INFER = 1;
540 const HAS_RE_INFER = 1 << 1;
542 const HAS_CT_INFER = 1 << 2;
544 const HAS_TY_PLACEHOLDER = 1 << 3;
546 const HAS_RE_PLACEHOLDER = 1 << 4;
548 const HAS_CT_PLACEHOLDER = 1 << 5;
550 const HAS_FREE_LOCAL_REGIONS = 1 << 6;
552 const HAS_TY_PROJECTION = 1 << 7;
554 const HAS_TY_OPAQUE = 1 << 8;
556 const HAS_CT_PROJECTION = 1 << 9;
558 const HAS_ERROR = 1 << 10;
560 const HAS_RE_ERROR = 1 << 11;
562 const HAS_FREE_REGIONS = 1 << 12;
564 const HAS_RE_LATE_BOUND = 1 << 13;
566 const HAS_RE_ERASED = 1 << 14;
568 const STILL_FURTHER_SPECIALIZABLE = 1 << 15;
570
571 const HAS_FREE_LOCAL_NAMES = TypeFlags::HAS_TY_INFER.bits()
573 | TypeFlags::HAS_CT_INFER.bits()
574 | TypeFlags::HAS_TY_PLACEHOLDER.bits()
575 | TypeFlags::HAS_CT_PLACEHOLDER.bits()
576 | TypeFlags::HAS_FREE_LOCAL_REGIONS.bits();
577
578 const HAS_PROJECTION = TypeFlags::HAS_TY_PROJECTION.bits()
580 | TypeFlags::HAS_TY_OPAQUE.bits()
581 | TypeFlags::HAS_CT_PROJECTION.bits();
582 }
583}
584#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
586pub enum TyKind<I: Interner> {
587 Adt(AdtId<I>, Substitution<I>),
590
591 AssociatedType(AssocTypeId<I>, Substitution<I>),
593
594 Scalar(Scalar),
596
597 Tuple(usize, Substitution<I>),
599
600 Array(Ty<I>, Const<I>),
602
603 Slice(Ty<I>),
605
606 Raw(Mutability, Ty<I>),
608
609 Ref(Mutability, Lifetime<I>, Ty<I>),
611
612 OpaqueType(OpaqueTyId<I>, Substitution<I>),
614
615 FnDef(FnDefId<I>, Substitution<I>),
617
618 Str,
620
621 Never,
623
624 Closure(ClosureId<I>, Substitution<I>),
626
627 Coroutine(CoroutineId<I>, Substitution<I>),
629
630 CoroutineWitness(CoroutineId<I>, Substitution<I>),
632
633 Foreign(ForeignDefId<I>),
635
636 Error,
639
640 Placeholder(PlaceholderIndex),
644
645 Dyn(DynTy<I>),
653
654 Alias(AliasTy<I>),
659
660 Function(FnPointer<I>),
665
666 BoundVar(BoundVar),
669
670 InferenceVar(InferenceVar, TyVariableKind),
672}
673
674impl<I: Interner> Copy for TyKind<I>
675where
676 I::InternedLifetime: Copy,
677 I::InternedSubstitution: Copy,
678 I::InternedVariableKinds: Copy,
679 I::InternedQuantifiedWhereClauses: Copy,
680 I::InternedType: Copy,
681 I::InternedConst: Copy,
682{
683}
684
685impl<I: Interner> TyKind<I> {
686 pub fn intern(self, interner: I) -> Ty<I> {
688 Ty::new(interner, self)
689 }
690
691 pub fn compute_flags(&self, interner: I) -> TypeFlags {
693 match self {
694 TyKind::Adt(_, substitution)
695 | TyKind::AssociatedType(_, substitution)
696 | TyKind::Tuple(_, substitution)
697 | TyKind::Closure(_, substitution)
698 | TyKind::Coroutine(_, substitution)
699 | TyKind::CoroutineWitness(_, substitution)
700 | TyKind::FnDef(_, substitution)
701 | TyKind::OpaqueType(_, substitution) => substitution.compute_flags(interner),
702 TyKind::Scalar(_) | TyKind::Str | TyKind::Never | TyKind::Foreign(_) => {
703 TypeFlags::empty()
704 }
705 TyKind::Error => TypeFlags::HAS_ERROR,
706 TyKind::Slice(ty) | TyKind::Raw(_, ty) => ty.data(interner).flags,
707 TyKind::Ref(_, lifetime, ty) => {
708 lifetime.compute_flags(interner) | ty.data(interner).flags
709 }
710 TyKind::Array(ty, const_ty) => {
711 let flags = ty.data(interner).flags;
712 let const_data = const_ty.data(interner);
713 flags
714 | const_data.ty.data(interner).flags
715 | match const_data.value {
716 ConstValue::BoundVar(_) | ConstValue::Concrete(_) => TypeFlags::empty(),
717 ConstValue::InferenceVar(_) => {
718 TypeFlags::HAS_CT_INFER | TypeFlags::STILL_FURTHER_SPECIALIZABLE
719 }
720 ConstValue::Placeholder(_) => {
721 TypeFlags::HAS_CT_PLACEHOLDER | TypeFlags::STILL_FURTHER_SPECIALIZABLE
722 }
723 }
724 }
725 TyKind::Placeholder(_) => TypeFlags::HAS_TY_PLACEHOLDER,
726 TyKind::Dyn(dyn_ty) => {
727 let lifetime_flags = dyn_ty.lifetime.compute_flags(interner);
728 let mut dyn_flags = TypeFlags::empty();
729 for var_kind in dyn_ty.bounds.skip_binders().iter(interner) {
730 match &(var_kind.skip_binders()) {
731 WhereClause::Implemented(trait_ref) => {
732 dyn_flags |= trait_ref.substitution.compute_flags(interner)
733 }
734 WhereClause::AliasEq(alias_eq) => {
735 dyn_flags |= alias_eq.alias.compute_flags(interner);
736 dyn_flags |= alias_eq.ty.data(interner).flags;
737 }
738 WhereClause::LifetimeOutlives(lifetime_outlives) => {
739 dyn_flags |= lifetime_outlives.a.compute_flags(interner)
740 | lifetime_outlives.b.compute_flags(interner);
741 }
742 WhereClause::TypeOutlives(type_outlives) => {
743 dyn_flags |= type_outlives.ty.data(interner).flags;
744 dyn_flags |= type_outlives.lifetime.compute_flags(interner);
745 }
746 }
747 }
748 lifetime_flags | dyn_flags
749 }
750 TyKind::Alias(alias_ty) => alias_ty.compute_flags(interner),
751 TyKind::BoundVar(_) => TypeFlags::empty(),
752 TyKind::InferenceVar(_, _) => TypeFlags::HAS_TY_INFER,
753 TyKind::Function(fn_pointer) => fn_pointer.substitution.0.compute_flags(interner),
754 }
755 }
756}
757
758#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
783pub struct BoundVar {
784 pub debruijn: DebruijnIndex,
786 pub index: usize,
788}
789
790impl BoundVar {
791 pub fn new(debruijn: DebruijnIndex, index: usize) -> Self {
793 Self { debruijn, index }
794 }
795
796 pub fn to_ty<I: Interner>(self, interner: I) -> Ty<I> {
798 TyKind::<I>::BoundVar(self).intern(interner)
799 }
800
801 pub fn to_lifetime<I: Interner>(self, interner: I) -> Lifetime<I> {
803 LifetimeData::<I>::BoundVar(self).intern(interner)
804 }
805
806 pub fn to_const<I: Interner>(self, interner: I, ty: Ty<I>) -> Const<I> {
808 ConstData {
809 ty,
810 value: ConstValue::<I>::BoundVar(self),
811 }
812 .intern(interner)
813 }
814
815 pub fn bound_within(self, outer_binder: DebruijnIndex) -> bool {
817 self.debruijn.within(outer_binder)
818 }
819
820 #[must_use]
822 pub fn shifted_in(self) -> Self {
823 BoundVar::new(self.debruijn.shifted_in(), self.index)
824 }
825
826 #[must_use]
828 pub fn shifted_in_from(self, outer_binder: DebruijnIndex) -> Self {
829 BoundVar::new(self.debruijn.shifted_in_from(outer_binder), self.index)
830 }
831
832 #[must_use]
834 pub fn shifted_out(self) -> Option<Self> {
835 self.debruijn
836 .shifted_out()
837 .map(|db| BoundVar::new(db, self.index))
838 }
839
840 #[must_use]
842 pub fn shifted_out_to(self, outer_binder: DebruijnIndex) -> Option<Self> {
843 self.debruijn
844 .shifted_out_to(outer_binder)
845 .map(|db| BoundVar::new(db, self.index))
846 }
847
848 pub fn index_if_innermost(self) -> Option<usize> {
851 self.index_if_bound_at(DebruijnIndex::INNERMOST)
852 }
853
854 pub fn index_if_bound_at(self, debruijn: DebruijnIndex) -> Option<usize> {
857 if self.debruijn == debruijn {
858 Some(self.index)
859 } else {
860 None
861 }
862 }
863}
864
865#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
874pub struct DebruijnIndex {
875 depth: u32,
876}
877
878impl DebruijnIndex {
879 pub const INNERMOST: DebruijnIndex = DebruijnIndex { depth: 0 };
881 pub const ONE: DebruijnIndex = DebruijnIndex { depth: 1 };
883
884 pub fn new(depth: u32) -> Self {
886 DebruijnIndex { depth }
887 }
888
889 pub fn depth(self) -> u32 {
892 self.depth
893 }
894
895 pub fn within(self, outer_binder: DebruijnIndex) -> bool {
914 self < outer_binder
915 }
916
917 #[must_use]
920 pub fn shifted_in(self) -> DebruijnIndex {
921 self.shifted_in_from(DebruijnIndex::ONE)
922 }
923
924 pub fn shift_in(&mut self) {
927 *self = self.shifted_in();
928 }
929
930 #[must_use]
957 pub fn shifted_in_from(self, outer_binder: DebruijnIndex) -> DebruijnIndex {
958 DebruijnIndex::new(self.depth() + outer_binder.depth())
959 }
960
961 #[must_use]
964 pub fn shifted_out(self) -> Option<DebruijnIndex> {
965 self.shifted_out_to(DebruijnIndex::ONE)
966 }
967
968 pub fn shift_out(&mut self) {
970 *self = self.shifted_out().unwrap();
971 }
972
973 pub fn shifted_out_to(self, outer_binder: DebruijnIndex) -> Option<DebruijnIndex> {
1000 if self.within(outer_binder) {
1001 None
1002 } else {
1003 Some(DebruijnIndex::new(self.depth() - outer_binder.depth()))
1004 }
1005 }
1006}
1007
1008#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
1032pub struct DynTy<I: Interner> {
1033 pub bounds: Binders<QuantifiedWhereClauses<I>>,
1035 pub lifetime: Lifetime<I>,
1037}
1038
1039impl<I: Interner> Copy for DynTy<I>
1040where
1041 I::InternedLifetime: Copy,
1042 I::InternedQuantifiedWhereClauses: Copy,
1043 I::InternedVariableKinds: Copy,
1044{
1045}
1046
1047#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
1049pub struct InferenceVar {
1050 index: u32,
1051}
1052
1053impl From<u32> for InferenceVar {
1054 fn from(index: u32) -> InferenceVar {
1055 InferenceVar { index }
1056 }
1057}
1058
1059impl InferenceVar {
1060 pub fn index(self) -> u32 {
1062 self.index
1063 }
1064
1065 pub fn to_ty<I: Interner>(self, interner: I, kind: TyVariableKind) -> Ty<I> {
1067 TyKind::<I>::InferenceVar(self, kind).intern(interner)
1068 }
1069
1070 pub fn to_lifetime<I: Interner>(self, interner: I) -> Lifetime<I> {
1072 LifetimeData::<I>::InferenceVar(self).intern(interner)
1073 }
1074
1075 pub fn to_const<I: Interner>(self, interner: I, ty: Ty<I>) -> Const<I> {
1077 ConstData {
1078 ty,
1079 value: ConstValue::<I>::InferenceVar(self),
1080 }
1081 .intern(interner)
1082 }
1083}
1084
1085#[derive(Clone, Copy, PartialEq, Eq, Hash, HasInterner, Debug)]
1087#[allow(missing_docs)]
1088pub struct FnSig<I: Interner> {
1089 pub abi: I::FnAbi,
1090 pub safety: Safety,
1091 pub variadic: bool,
1092}
1093#[derive(Clone, PartialEq, Eq, Hash, HasInterner, TypeFoldable, TypeVisitable)]
1095pub struct FnSubst<I: Interner>(pub Substitution<I>);
1096
1097impl<I: Interner> Copy for FnSubst<I> where I::InternedSubstitution: Copy {}
1098
1099#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
1102#[allow(missing_docs)]
1103pub struct FnPointer<I: Interner> {
1104 pub num_binders: usize,
1105 pub sig: FnSig<I>,
1106 pub substitution: FnSubst<I>,
1107}
1108
1109impl<I: Interner> Copy for FnPointer<I> where I::InternedSubstitution: Copy {}
1110
1111impl<I: Interner> FnPointer<I> {
1112 pub fn into_binders(self, interner: I) -> Binders<FnSubst<I>> {
1114 Binders::new(
1115 VariableKinds::from_iter(
1116 interner,
1117 (0..self.num_binders).map(|_| VariableKind::Lifetime),
1118 ),
1119 self.substitution,
1120 )
1121 }
1122
1123 pub fn as_binders(&self, interner: I) -> Binders<&FnSubst<I>> {
1125 Binders::new(
1126 VariableKinds::from_iter(
1127 interner,
1128 (0..self.num_binders).map(|_| VariableKind::Lifetime),
1129 ),
1130 &self.substitution,
1131 )
1132 }
1133}
1134
1135#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
1137pub struct Const<I: Interner> {
1138 interned: I::InternedConst,
1139}
1140
1141impl<I: Interner> Const<I> {
1142 pub fn new(interner: I, data: impl CastTo<ConstData<I>>) -> Self {
1144 Const {
1145 interned: I::intern_const(interner, data.cast(interner)),
1146 }
1147 }
1148
1149 pub fn interned(&self) -> &I::InternedConst {
1151 &self.interned
1152 }
1153
1154 pub fn data(&self, interner: I) -> &ConstData<I> {
1156 I::const_data(interner, &self.interned)
1157 }
1158
1159 pub fn bound_var(&self, interner: I) -> Option<BoundVar> {
1161 if let ConstValue::BoundVar(bv) = &self.data(interner).value {
1162 Some(*bv)
1163 } else {
1164 None
1165 }
1166 }
1167
1168 pub fn inference_var(&self, interner: I) -> Option<InferenceVar> {
1170 if let ConstValue::InferenceVar(iv) = &self.data(interner).value {
1171 Some(*iv)
1172 } else {
1173 None
1174 }
1175 }
1176
1177 pub fn needs_shift(&self, interner: I) -> bool {
1180 match &self.data(interner).value {
1181 ConstValue::BoundVar(_) => true,
1182 ConstValue::InferenceVar(_) => false,
1183 ConstValue::Placeholder(_) => false,
1184 ConstValue::Concrete(_) => false,
1185 }
1186 }
1187}
1188
1189#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
1191pub struct ConstData<I: Interner> {
1192 pub ty: Ty<I>,
1194 pub value: ConstValue<I>,
1196}
1197
1198#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
1200pub enum ConstValue<I: Interner> {
1201 BoundVar(BoundVar),
1203 InferenceVar(InferenceVar),
1205 Placeholder(PlaceholderIndex),
1207 Concrete(ConcreteConst<I>),
1209}
1210
1211impl<I: Interner> Copy for ConstValue<I> where I::InternedConcreteConst: Copy {}
1212
1213impl<I: Interner> ConstData<I> {
1214 pub fn intern(self, interner: I) -> Const<I> {
1216 Const::new(interner, self)
1217 }
1218}
1219
1220#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
1223pub struct ConcreteConst<I: Interner> {
1224 pub interned: I::InternedConcreteConst,
1226}
1227
1228impl<I: Interner> ConcreteConst<I> {
1229 pub fn const_eq(&self, ty: &Ty<I>, other: &ConcreteConst<I>, interner: I) -> bool {
1231 interner.const_eq(&ty.interned, &self.interned, &other.interned)
1232 }
1233}
1234
1235#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
1237pub struct Lifetime<I: Interner> {
1238 interned: I::InternedLifetime,
1239}
1240
1241impl<I: Interner> Lifetime<I> {
1242 pub fn new(interner: I, data: impl CastTo<LifetimeData<I>>) -> Self {
1245 Lifetime {
1246 interned: I::intern_lifetime(interner, data.cast(interner)),
1247 }
1248 }
1249
1250 pub fn interned(&self) -> &I::InternedLifetime {
1252 &self.interned
1253 }
1254
1255 pub fn data(&self, interner: I) -> &LifetimeData<I> {
1257 I::lifetime_data(interner, &self.interned)
1258 }
1259
1260 pub fn bound_var(&self, interner: I) -> Option<BoundVar> {
1262 if let LifetimeData::BoundVar(bv) = self.data(interner) {
1263 Some(*bv)
1264 } else {
1265 None
1266 }
1267 }
1268
1269 pub fn inference_var(&self, interner: I) -> Option<InferenceVar> {
1271 if let LifetimeData::InferenceVar(depth) = self.data(interner) {
1272 Some(*depth)
1273 } else {
1274 None
1275 }
1276 }
1277
1278 pub fn needs_shift(&self, interner: I) -> bool {
1281 match self.data(interner) {
1282 LifetimeData::BoundVar(_) => true,
1283 LifetimeData::InferenceVar(_) => false,
1284 LifetimeData::Placeholder(_) => false,
1285 LifetimeData::Static => false,
1286 LifetimeData::Erased => false,
1287 LifetimeData::Error => false,
1288 LifetimeData::Phantom(..) => unreachable!(),
1289 }
1290 }
1291
1292 fn compute_flags(&self, interner: I) -> TypeFlags {
1294 match self.data(interner) {
1295 LifetimeData::InferenceVar(_) => {
1296 TypeFlags::HAS_RE_INFER
1297 | TypeFlags::HAS_FREE_LOCAL_REGIONS
1298 | TypeFlags::HAS_FREE_REGIONS
1299 }
1300 LifetimeData::Placeholder(_) => {
1301 TypeFlags::HAS_RE_PLACEHOLDER
1302 | TypeFlags::HAS_FREE_LOCAL_REGIONS
1303 | TypeFlags::HAS_FREE_REGIONS
1304 }
1305 LifetimeData::Static => TypeFlags::HAS_FREE_REGIONS,
1306 LifetimeData::Phantom(_, _) => TypeFlags::empty(),
1307 LifetimeData::BoundVar(_) => TypeFlags::HAS_RE_LATE_BOUND,
1308 LifetimeData::Erased => TypeFlags::HAS_RE_ERASED,
1309 LifetimeData::Error => TypeFlags::HAS_RE_ERROR,
1310 }
1311 }
1312}
1313
1314#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
1316pub enum LifetimeData<I: Interner> {
1317 BoundVar(BoundVar),
1319 InferenceVar(InferenceVar),
1321 Placeholder(PlaceholderIndex),
1323 Static,
1325 Erased,
1328 Phantom(Void, PhantomData<I>),
1330 Error,
1332}
1333
1334impl<I: Interner> LifetimeData<I> {
1335 pub fn intern(self, interner: I) -> Lifetime<I> {
1337 Lifetime::new(interner, self)
1338 }
1339}
1340
1341#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1345pub struct PlaceholderIndex {
1346 pub ui: UniverseIndex,
1348 pub idx: usize,
1350}
1351
1352impl PlaceholderIndex {
1353 pub fn to_lifetime<I: Interner>(self, interner: I) -> Lifetime<I> {
1355 LifetimeData::<I>::Placeholder(self).intern(interner)
1356 }
1357
1358 pub fn to_ty<I: Interner>(self, interner: I) -> Ty<I> {
1360 TyKind::Placeholder(self).intern(interner)
1361 }
1362
1363 pub fn to_const<I: Interner>(self, interner: I, ty: Ty<I>) -> Const<I> {
1365 ConstData {
1366 ty,
1367 value: ConstValue::Placeholder(self),
1368 }
1369 .intern(interner)
1370 }
1371}
1372#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1383#[allow(missing_docs)]
1384pub enum TyVariableKind {
1385 General,
1386 Integer,
1387 Float,
1388}
1389
1390#[derive(Clone, PartialEq, Eq, Hash)]
1392#[allow(missing_docs)]
1393pub enum VariableKind<I: Interner> {
1394 Ty(TyVariableKind),
1395 Lifetime,
1396 Const(Ty<I>),
1397}
1398
1399impl<I: Interner> interner::HasInterner for VariableKind<I> {
1400 type Interner = I;
1401}
1402
1403impl<I: Interner> Copy for VariableKind<I> where I::InternedType: Copy {}
1404
1405impl<I: Interner> VariableKind<I> {
1406 fn to_bound_variable(&self, interner: I, bound_var: BoundVar) -> GenericArg<I> {
1407 match self {
1408 VariableKind::Ty(_) => {
1409 GenericArgData::Ty(TyKind::BoundVar(bound_var).intern(interner)).intern(interner)
1410 }
1411 VariableKind::Lifetime => {
1412 GenericArgData::Lifetime(LifetimeData::BoundVar(bound_var).intern(interner))
1413 .intern(interner)
1414 }
1415 VariableKind::Const(ty) => GenericArgData::Const(
1416 ConstData {
1417 ty: ty.clone(),
1418 value: ConstValue::BoundVar(bound_var),
1419 }
1420 .intern(interner),
1421 )
1422 .intern(interner),
1423 }
1424 }
1425}
1426
1427#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
1429pub struct GenericArg<I: Interner> {
1430 interned: I::InternedGenericArg,
1431}
1432
1433impl<I: Interner> GenericArg<I> {
1434 pub fn new(interner: I, data: GenericArgData<I>) -> Self {
1436 let interned = I::intern_generic_arg(interner, data);
1437 GenericArg { interned }
1438 }
1439
1440 pub fn interned(&self) -> &I::InternedGenericArg {
1442 &self.interned
1443 }
1444
1445 pub fn data(&self, interner: I) -> &GenericArgData<I> {
1447 I::generic_arg_data(interner, &self.interned)
1448 }
1449
1450 pub fn assert_ty_ref(&self, interner: I) -> &Ty<I> {
1452 self.ty(interner).unwrap()
1453 }
1454
1455 pub fn assert_lifetime_ref(&self, interner: I) -> &Lifetime<I> {
1457 self.lifetime(interner).unwrap()
1458 }
1459
1460 pub fn assert_const_ref(&self, interner: I) -> &Const<I> {
1462 self.constant(interner).unwrap()
1463 }
1464
1465 pub fn is_ty(&self, interner: I) -> bool {
1467 match self.data(interner) {
1468 GenericArgData::Ty(_) => true,
1469 GenericArgData::Lifetime(_) => false,
1470 GenericArgData::Const(_) => false,
1471 }
1472 }
1473
1474 pub fn ty(&self, interner: I) -> Option<&Ty<I>> {
1476 match self.data(interner) {
1477 GenericArgData::Ty(t) => Some(t),
1478 _ => None,
1479 }
1480 }
1481
1482 pub fn lifetime(&self, interner: I) -> Option<&Lifetime<I>> {
1484 match self.data(interner) {
1485 GenericArgData::Lifetime(t) => Some(t),
1486 _ => None,
1487 }
1488 }
1489
1490 pub fn constant(&self, interner: I) -> Option<&Const<I>> {
1492 match self.data(interner) {
1493 GenericArgData::Const(c) => Some(c),
1494 _ => None,
1495 }
1496 }
1497
1498 fn compute_flags(&self, interner: I) -> TypeFlags {
1500 match self.data(interner) {
1501 GenericArgData::Ty(ty) => ty.data(interner).flags,
1502 GenericArgData::Lifetime(lifetime) => lifetime.compute_flags(interner),
1503 GenericArgData::Const(constant) => {
1504 let data = constant.data(interner);
1505 let flags = data.ty.data(interner).flags;
1506 match data.value {
1507 ConstValue::BoundVar(_) => flags,
1508 ConstValue::InferenceVar(_) => {
1509 flags | TypeFlags::HAS_CT_INFER | TypeFlags::STILL_FURTHER_SPECIALIZABLE
1510 }
1511 ConstValue::Placeholder(_) => {
1512 flags
1513 | TypeFlags::HAS_CT_PLACEHOLDER
1514 | TypeFlags::STILL_FURTHER_SPECIALIZABLE
1515 }
1516 ConstValue::Concrete(_) => flags,
1517 }
1518 }
1519 }
1520 }
1521}
1522
1523#[derive(Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable, Zip)]
1525pub enum GenericArgData<I: Interner> {
1526 Ty(Ty<I>),
1528 Lifetime(Lifetime<I>),
1530 Const(Const<I>),
1532}
1533
1534impl<I: Interner> Copy for GenericArgData<I>
1535where
1536 I::InternedType: Copy,
1537 I::InternedLifetime: Copy,
1538 I::InternedConst: Copy,
1539{
1540}
1541
1542impl<I: Interner> GenericArgData<I> {
1543 pub fn intern(self, interner: I) -> GenericArg<I> {
1545 GenericArg::new(interner, self)
1546 }
1547}
1548
1549#[derive(Clone, PartialEq, Eq, Hash)]
1551pub struct WithKind<I: Interner, T> {
1552 pub kind: VariableKind<I>,
1554 value: T,
1556}
1557
1558impl<I: Interner, T: Copy> Copy for WithKind<I, T> where I::InternedType: Copy {}
1559
1560impl<I: Interner, T> HasInterner for WithKind<I, T> {
1561 type Interner = I;
1562}
1563
1564impl<I: Interner, T> From<WithKind<I, T>> for (VariableKind<I>, T) {
1565 fn from(with_kind: WithKind<I, T>) -> Self {
1566 (with_kind.kind, with_kind.value)
1567 }
1568}
1569
1570impl<I: Interner, T> WithKind<I, T> {
1571 pub fn new(kind: VariableKind<I>, value: T) -> Self {
1573 Self { kind, value }
1574 }
1575
1576 pub fn map<U, OP>(self, op: OP) -> WithKind<I, U>
1578 where
1579 OP: FnOnce(T) -> U,
1580 {
1581 WithKind {
1582 kind: self.kind,
1583 value: op(self.value),
1584 }
1585 }
1586
1587 pub fn map_ref<U, OP>(&self, op: OP) -> WithKind<I, U>
1589 where
1590 OP: FnOnce(&T) -> U,
1591 {
1592 WithKind {
1593 kind: self.kind.clone(),
1594 value: op(&self.value),
1595 }
1596 }
1597
1598 pub fn skip_kind(&self) -> &T {
1600 &self.value
1601 }
1602}
1603
1604#[allow(type_alias_bounds)]
1606pub type CanonicalVarKind<I: Interner> = WithKind<I, UniverseIndex>;
1607
1608#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
1610pub enum AliasTy<I: Interner> {
1611 Projection(ProjectionTy<I>),
1613 Opaque(OpaqueTy<I>),
1615}
1616
1617impl<I: Interner> Copy for AliasTy<I> where I::InternedSubstitution: Copy {}
1618
1619impl<I: Interner> AliasTy<I> {
1620 pub fn intern(self, interner: I) -> Ty<I> {
1622 Ty::new(interner, self)
1623 }
1624
1625 fn compute_flags(&self, interner: I) -> TypeFlags {
1627 match self {
1628 AliasTy::Projection(projection_ty) => {
1629 TypeFlags::HAS_TY_PROJECTION | projection_ty.substitution.compute_flags(interner)
1630 }
1631 AliasTy::Opaque(opaque_ty) => {
1632 TypeFlags::HAS_TY_OPAQUE | opaque_ty.substitution.compute_flags(interner)
1633 }
1634 }
1635 }
1636}
1637
1638#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
1640pub struct ProjectionTy<I: Interner> {
1641 pub associated_ty_id: AssocTypeId<I>,
1643 pub substitution: Substitution<I>,
1645}
1646
1647impl<I: Interner> Copy for ProjectionTy<I> where I::InternedSubstitution: Copy {}
1648
1649#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
1651pub struct OpaqueTy<I: Interner> {
1652 pub opaque_ty_id: OpaqueTyId<I>,
1654 pub substitution: Substitution<I>,
1656}
1657
1658impl<I: Interner> Copy for OpaqueTy<I> where I::InternedSubstitution: Copy {}
1659
1660#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
1667pub struct TraitRef<I: Interner> {
1668 pub trait_id: TraitId<I>,
1670 pub substitution: Substitution<I>,
1672}
1673
1674impl<I: Interner> Copy for TraitRef<I> where I::InternedSubstitution: Copy {}
1675
1676impl<I: Interner> TraitRef<I> {
1677 pub fn type_parameters(&self, interner: I) -> impl Iterator<Item = Ty<I>> + '_ {
1679 self.substitution
1680 .iter(interner)
1681 .filter_map(move |p| p.ty(interner))
1682 .cloned()
1683 }
1684
1685 pub fn self_type_parameter(&self, interner: I) -> Ty<I> {
1687 self.type_parameters(interner).next().unwrap()
1688 }
1689
1690 pub fn from_env(self) -> FromEnv<I> {
1692 FromEnv::Trait(self)
1693 }
1694
1695 pub fn well_formed(self) -> WellFormed<I> {
1697 WellFormed::Trait(self)
1698 }
1699}
1700
1701#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
1704#[allow(missing_docs)]
1705pub struct LifetimeOutlives<I: Interner> {
1706 pub a: Lifetime<I>,
1707 pub b: Lifetime<I>,
1708}
1709
1710impl<I: Interner> Copy for LifetimeOutlives<I> where I::InternedLifetime: Copy {}
1711
1712#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
1715pub struct TypeOutlives<I: Interner> {
1716 pub ty: Ty<I>,
1718 pub lifetime: Lifetime<I>,
1720}
1721
1722impl<I: Interner> Copy for TypeOutlives<I>
1723where
1724 I::InternedLifetime: Copy,
1725 I::InternedType: Copy,
1726{
1727}
1728
1729#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeSuperVisitable, HasInterner, Zip)]
1731pub enum WhereClause<I: Interner> {
1732 Implemented(TraitRef<I>),
1734 AliasEq(AliasEq<I>),
1736 LifetimeOutlives(LifetimeOutlives<I>),
1738 TypeOutlives(TypeOutlives<I>),
1740}
1741
1742impl<I: Interner> Copy for WhereClause<I>
1743where
1744 I::InternedSubstitution: Copy,
1745 I::InternedLifetime: Copy,
1746 I::InternedType: Copy,
1747{
1748}
1749
1750#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
1752pub enum WellFormed<I: Interner> {
1753 Trait(TraitRef<I>),
1767
1768 Ty(Ty<I>),
1779}
1780
1781impl<I: Interner> Copy for WellFormed<I>
1782where
1783 I::InternedType: Copy,
1784 I::InternedSubstitution: Copy,
1785{
1786}
1787
1788#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
1790pub enum FromEnv<I: Interner> {
1791 Trait(TraitRef<I>),
1803
1804 Ty(Ty<I>),
1816}
1817
1818impl<I: Interner> Copy for FromEnv<I>
1819where
1820 I::InternedType: Copy,
1821 I::InternedSubstitution: Copy,
1822{
1823}
1824
1825#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeSuperVisitable, HasInterner, Zip)]
1829pub enum DomainGoal<I: Interner> {
1830 Holds(WhereClause<I>),
1832
1833 WellFormed(WellFormed<I>),
1835
1836 FromEnv(FromEnv<I>),
1838
1839 Normalize(Normalize<I>),
1841
1842 IsLocal(Ty<I>),
1846
1847 IsUpstream(Ty<I>),
1851
1852 IsFullyVisible(Ty<I>),
1866
1867 LocalImplAllowed(TraitRef<I>),
1875
1876 Compatible,
1880
1881 DownstreamType(Ty<I>),
1891
1892 Reveal,
1895
1896 ObjectSafe(TraitId<I>),
1898}
1899
1900impl<I: Interner> Copy for DomainGoal<I>
1901where
1902 I::InternedSubstitution: Copy,
1903 I::InternedLifetime: Copy,
1904 I::InternedType: Copy,
1905{
1906}
1907
1908pub type QuantifiedWhereClause<I> = Binders<WhereClause<I>>;
1910
1911impl<I: Interner> WhereClause<I> {
1912 pub fn into_well_formed_goal(self, interner: I) -> DomainGoal<I> {
1917 match self {
1918 WhereClause::Implemented(trait_ref) => WellFormed::Trait(trait_ref).cast(interner),
1919 wc => wc.cast(interner),
1920 }
1921 }
1922
1923 pub fn into_from_env_goal(self, interner: I) -> DomainGoal<I> {
1925 match self {
1926 WhereClause::Implemented(trait_ref) => FromEnv::Trait(trait_ref).cast(interner),
1927 wc => wc.cast(interner),
1928 }
1929 }
1930
1931 pub fn trait_id(&self) -> Option<TraitId<I>> {
1933 match self {
1934 WhereClause::Implemented(trait_ref) => Some(trait_ref.trait_id),
1935 WhereClause::AliasEq(_) => None,
1936 WhereClause::LifetimeOutlives(_) => None,
1937 WhereClause::TypeOutlives(_) => None,
1938 }
1939 }
1940}
1941
1942impl<I: Interner> QuantifiedWhereClause<I> {
1943 pub fn into_well_formed_goal(self, interner: I) -> Binders<DomainGoal<I>> {
1948 self.map(|wc| wc.into_well_formed_goal(interner))
1949 }
1950
1951 pub fn into_from_env_goal(self, interner: I) -> Binders<DomainGoal<I>> {
1956 self.map(|wc| wc.into_from_env_goal(interner))
1957 }
1958
1959 pub fn trait_id(&self) -> Option<TraitId<I>> {
1961 self.skip_binders().trait_id()
1962 }
1963}
1964
1965impl<I: Interner> DomainGoal<I> {
1966 pub fn into_from_env_goal(self, interner: I) -> DomainGoal<I> {
1969 match self {
1970 DomainGoal::Holds(wc) => wc.into_from_env_goal(interner),
1971 goal => goal,
1972 }
1973 }
1974
1975 pub fn inputs(&self, interner: I) -> Vec<GenericArg<I>> {
1977 match self {
1978 DomainGoal::Holds(WhereClause::AliasEq(alias_eq)) => {
1979 vec![GenericArgData::Ty(alias_eq.alias.clone().intern(interner)).intern(interner)]
1980 }
1981 _ => Vec::new(),
1982 }
1983 }
1984}
1985
1986#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, Zip)]
1988#[allow(missing_docs)]
1989pub struct EqGoal<I: Interner> {
1990 pub a: GenericArg<I>,
1991 pub b: GenericArg<I>,
1992}
1993
1994impl<I: Interner> Copy for EqGoal<I> where I::InternedGenericArg: Copy {}
1995
1996#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, Zip)]
1998#[allow(missing_docs)]
1999pub struct SubtypeGoal<I: Interner> {
2000 pub a: Ty<I>,
2001 pub b: Ty<I>,
2002}
2003
2004impl<I: Interner> Copy for SubtypeGoal<I> where I::InternedType: Copy {}
2005
2006#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, Zip)]
2011#[allow(missing_docs)]
2012pub struct Normalize<I: Interner> {
2013 pub alias: AliasTy<I>,
2014 pub ty: Ty<I>,
2015}
2016
2017impl<I: Interner> Copy for Normalize<I>
2018where
2019 I::InternedSubstitution: Copy,
2020 I::InternedType: Copy,
2021{
2022}
2023
2024#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, Zip)]
2026#[allow(missing_docs)]
2027pub struct AliasEq<I: Interner> {
2028 pub alias: AliasTy<I>,
2029 pub ty: Ty<I>,
2030}
2031
2032impl<I: Interner> Copy for AliasEq<I>
2033where
2034 I::InternedSubstitution: Copy,
2035 I::InternedType: Copy,
2036{
2037}
2038
2039impl<I: Interner> HasInterner for AliasEq<I> {
2040 type Interner = I;
2041}
2042
2043#[derive(Clone, PartialEq, Eq, Hash)]
2051pub struct Binders<T: HasInterner> {
2052 pub binders: VariableKinds<T::Interner>,
2054
2055 value: T,
2057}
2058
2059impl<T: HasInterner + Copy> Copy for Binders<T> where
2060 <T::Interner as Interner>::InternedVariableKinds: Copy
2061{
2062}
2063
2064impl<T: HasInterner> HasInterner for Binders<T> {
2065 type Interner = T::Interner;
2066}
2067
2068impl<T: Clone + HasInterner> Binders<&T> {
2069 pub fn cloned(self) -> Binders<T> {
2071 self.map(Clone::clone)
2072 }
2073}
2074
2075impl<T: HasInterner> Binders<T> {
2076 pub fn new(binders: VariableKinds<T::Interner>, value: T) -> Self {
2078 Self { binders, value }
2079 }
2080
2081 pub fn empty(interner: T::Interner, value: T) -> Self {
2085 let binders = VariableKinds::empty(interner);
2086 Self { binders, value }
2087 }
2088
2089 pub fn skip_binders(&self) -> &T {
2101 &self.value
2102 }
2103
2104 pub fn into_value_and_skipped_binders(self) -> (T, VariableKinds<T::Interner>) {
2107 (self.value, self.binders)
2108 }
2109
2110 pub fn as_ref(&self) -> Binders<&T> {
2114 Binders {
2115 binders: self.binders.clone(),
2116 value: &self.value,
2117 }
2118 }
2119
2120 pub fn map<U, OP>(self, op: OP) -> Binders<U>
2122 where
2123 OP: FnOnce(T) -> U,
2124 U: HasInterner<Interner = T::Interner>,
2125 {
2126 let value = op(self.value);
2127 Binders {
2128 binders: self.binders,
2129 value,
2130 }
2131 }
2132
2133 pub fn filter_map<U, OP>(self, op: OP) -> Option<Binders<U>>
2136 where
2137 OP: FnOnce(T) -> Option<U>,
2138 U: HasInterner<Interner = T::Interner>,
2139 {
2140 let value = op(self.value)?;
2141 Some(Binders {
2142 binders: self.binders,
2143 value,
2144 })
2145 }
2146
2147 pub fn map_ref<'a, U, OP>(&'a self, op: OP) -> Binders<U>
2149 where
2150 OP: FnOnce(&'a T) -> U,
2151 U: HasInterner<Interner = T::Interner>,
2152 {
2153 self.as_ref().map(op)
2154 }
2155
2156 pub fn identity_substitution(&self, interner: T::Interner) -> Substitution<T::Interner> {
2160 Substitution::from_iter(
2161 interner,
2162 self.binders
2163 .iter(interner)
2164 .enumerate()
2165 .map(|p| p.to_generic_arg(interner)),
2166 )
2167 }
2168
2169 pub fn with_fresh_type_var(
2176 interner: T::Interner,
2177 op: impl FnOnce(Ty<T::Interner>) -> T,
2178 ) -> Binders<T> {
2179 let new_var = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(interner);
2181 let value = op(new_var);
2182 let binders = VariableKinds::from1(interner, VariableKind::Ty(TyVariableKind::General));
2183 Binders { binders, value }
2184 }
2185
2186 pub fn len(&self, interner: T::Interner) -> usize {
2188 self.binders.len(interner)
2189 }
2190}
2191
2192impl<T, I> Binders<Binders<T>>
2193where
2194 T: TypeFoldable<I> + HasInterner<Interner = I>,
2195 I: Interner,
2196{
2197 pub fn fuse_binders(self, interner: T::Interner) -> Binders<T> {
2199 let num_binders = self.len(interner);
2200 let subst = Substitution::from_iter(
2202 interner,
2203 self.value
2204 .binders
2205 .iter(interner)
2206 .enumerate()
2207 .map(|(i, pk)| (i + num_binders, pk).to_generic_arg(interner)),
2208 );
2209 let binders = VariableKinds::from_iter(
2210 interner,
2211 self.binders
2212 .iter(interner)
2213 .chain(self.value.binders.iter(interner))
2214 .cloned(),
2215 );
2216 let value = self.value.substitute(interner, &subst);
2217 Binders { binders, value }
2218 }
2219}
2220
2221impl<T: HasInterner> From<Binders<T>> for (VariableKinds<T::Interner>, T) {
2222 fn from(binders: Binders<T>) -> Self {
2223 (binders.binders, binders.value)
2224 }
2225}
2226
2227impl<T, I> Binders<T>
2228where
2229 T: TypeFoldable<I> + HasInterner<Interner = I>,
2230 I: Interner,
2231{
2232 pub fn substitute(self, interner: I, parameters: &(impl AsParameters<I> + ?Sized)) -> T {
2237 let parameters = parameters.as_parameters(interner);
2238 assert_eq!(self.binders.len(interner), parameters.len());
2239 Subst::apply(interner, parameters, self.value)
2240 }
2241}
2242
2243impl<V, U> IntoIterator for Binders<V>
2246where
2247 V: HasInterner + IntoIterator<Item = U>,
2248 U: HasInterner<Interner = V::Interner>,
2249{
2250 type Item = Binders<U>;
2251 type IntoIter = BindersIntoIterator<V>;
2252
2253 fn into_iter(self) -> Self::IntoIter {
2254 BindersIntoIterator {
2255 iter: self.value.into_iter(),
2256 binders: self.binders,
2257 }
2258 }
2259}
2260
2261pub struct BindersIntoIterator<V: HasInterner + IntoIterator> {
2263 iter: <V as IntoIterator>::IntoIter,
2264 binders: VariableKinds<V::Interner>,
2265}
2266
2267impl<V> Iterator for BindersIntoIterator<V>
2268where
2269 V: HasInterner + IntoIterator,
2270 <V as IntoIterator>::Item: HasInterner<Interner = V::Interner>,
2271{
2272 type Item = Binders<<V as IntoIterator>::Item>;
2273 fn next(&mut self) -> Option<Self::Item> {
2274 self.iter
2275 .next()
2276 .map(|v| Binders::new(self.binders.clone(), v))
2277 }
2278}
2279
2280#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
2284pub struct ProgramClauseImplication<I: Interner> {
2285 pub consequence: DomainGoal<I>,
2287
2288 pub conditions: Goals<I>,
2290
2291 pub constraints: Constraints<I>,
2293
2294 pub priority: ClausePriority,
2296}
2297
2298#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
2300pub enum ClausePriority {
2301 High,
2303
2304 Low,
2306}
2307
2308impl std::ops::BitAnd for ClausePriority {
2309 type Output = ClausePriority;
2310 fn bitand(self, rhs: ClausePriority) -> Self::Output {
2311 match (self, rhs) {
2312 (ClausePriority::High, ClausePriority::High) => ClausePriority::High,
2313 _ => ClausePriority::Low,
2314 }
2315 }
2316}
2317
2318#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, HasInterner, Zip)]
2320pub struct ProgramClauseData<I: Interner>(pub Binders<ProgramClauseImplication<I>>);
2321
2322impl<I: Interner> ProgramClauseImplication<I> {
2323 pub fn into_from_env_clause(self, interner: I) -> ProgramClauseImplication<I> {
2325 if self.conditions.is_empty(interner) {
2326 ProgramClauseImplication {
2327 consequence: self.consequence.into_from_env_goal(interner),
2328 conditions: self.conditions.clone(),
2329 constraints: self.constraints.clone(),
2330 priority: self.priority,
2331 }
2332 } else {
2333 self
2334 }
2335 }
2336}
2337
2338impl<I: Interner> ProgramClauseData<I> {
2339 pub fn into_from_env_clause(self, interner: I) -> ProgramClauseData<I> {
2341 ProgramClauseData(self.0.map(|i| i.into_from_env_clause(interner)))
2342 }
2343
2344 pub fn intern(self, interner: I) -> ProgramClause<I> {
2346 ProgramClause {
2347 interned: interner.intern_program_clause(self),
2348 }
2349 }
2350}
2351
2352#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
2354pub struct ProgramClause<I: Interner> {
2355 interned: I::InternedProgramClause,
2356}
2357
2358impl<I: Interner> ProgramClause<I> {
2359 pub fn new(interner: I, clause: ProgramClauseData<I>) -> Self {
2361 let interned = interner.intern_program_clause(clause);
2362 Self { interned }
2363 }
2364
2365 pub fn into_from_env_clause(self, interner: I) -> ProgramClause<I> {
2367 let program_clause_data = self.data(interner);
2368 let new_clause = program_clause_data.clone().into_from_env_clause(interner);
2369 Self::new(interner, new_clause)
2370 }
2371
2372 pub fn interned(&self) -> &I::InternedProgramClause {
2374 &self.interned
2375 }
2376
2377 pub fn data(&self, interner: I) -> &ProgramClauseData<I> {
2379 interner.program_clause_data(&self.interned)
2380 }
2381}
2382
2383#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2389pub struct Canonical<T: HasInterner> {
2390 pub value: T,
2392
2393 pub binders: CanonicalVarKinds<T::Interner>,
2395}
2396
2397impl<T: HasInterner> HasInterner for Canonical<T> {
2398 type Interner = T::Interner;
2399}
2400
2401#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2408pub struct UCanonical<T: HasInterner> {
2409 pub canonical: Canonical<T>,
2411
2412 pub universes: usize,
2414}
2415
2416impl<T: HasInterner> UCanonical<T> {
2417 pub fn is_trivial_substitution(
2420 &self,
2421 interner: T::Interner,
2422 canonical_subst: &Canonical<AnswerSubst<T::Interner>>,
2423 ) -> bool {
2424 let subst = &canonical_subst.value.subst;
2425 assert_eq!(
2426 self.canonical.binders.len(interner),
2427 subst.as_slice(interner).len()
2428 );
2429 subst.is_identity_subst(interner)
2430 }
2431
2432 pub fn trivial_substitution(&self, interner: T::Interner) -> Substitution<T::Interner> {
2434 let binders = &self.canonical.binders;
2435 Substitution::from_iter(
2436 interner,
2437 binders
2438 .iter(interner)
2439 .enumerate()
2440 .map(|(index, pk)| {
2441 let bound_var = BoundVar::new(DebruijnIndex::INNERMOST, index);
2442 match &pk.kind {
2443 VariableKind::Ty(_) => {
2444 GenericArgData::Ty(TyKind::BoundVar(bound_var).intern(interner))
2445 .intern(interner)
2446 }
2447 VariableKind::Lifetime => GenericArgData::Lifetime(
2448 LifetimeData::BoundVar(bound_var).intern(interner),
2449 )
2450 .intern(interner),
2451 VariableKind::Const(ty) => GenericArgData::Const(
2452 ConstData {
2453 ty: ty.clone(),
2454 value: ConstValue::BoundVar(bound_var),
2455 }
2456 .intern(interner),
2457 )
2458 .intern(interner),
2459 }
2460 })
2461 .collect::<Vec<_>>(),
2462 )
2463 }
2464}
2465
2466#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
2467pub struct Goal<I: Interner> {
2469 interned: I::InternedGoal,
2470}
2471
2472impl<I: Interner> Goal<I> {
2473 pub fn new(interner: I, interned: GoalData<I>) -> Self {
2475 let interned = I::intern_goal(interner, interned);
2476 Self { interned }
2477 }
2478
2479 pub fn interned(&self) -> &I::InternedGoal {
2481 &self.interned
2482 }
2483
2484 pub fn data(&self, interner: I) -> &GoalData<I> {
2486 interner.goal_data(&self.interned)
2487 }
2488
2489 pub fn quantify(self, interner: I, kind: QuantifierKind, binders: VariableKinds<I>) -> Goal<I> {
2491 GoalData::Quantified(kind, Binders::new(binders, self)).intern(interner)
2492 }
2493
2494 pub fn negate(self, interner: I) -> Self {
2496 GoalData::Not(self).intern(interner)
2497 }
2498
2499 pub fn compatible(self, interner: I) -> Self {
2501 GoalData::Quantified(
2504 QuantifierKind::ForAll,
2505 Binders::with_fresh_type_var(interner, |ty| {
2506 GoalData::Implies(
2507 ProgramClauses::from_iter(
2508 interner,
2509 vec![DomainGoal::Compatible, DomainGoal::DownstreamType(ty)],
2510 ),
2511 self.shifted_in(interner),
2512 )
2513 .intern(interner)
2514 }),
2515 )
2516 .intern(interner)
2517 }
2518
2519 pub fn implied_by(self, interner: I, predicates: ProgramClauses<I>) -> Goal<I> {
2521 GoalData::Implies(predicates, self).intern(interner)
2522 }
2523
2524 pub fn is_trivially_true(&self, interner: I) -> bool {
2527 match self.data(interner) {
2528 GoalData::All(goals) => goals.is_empty(interner),
2529 _ => false,
2530 }
2531 }
2532}
2533
2534impl<I> Goal<I>
2535where
2536 I: Interner,
2537{
2538 pub fn all<II>(interner: I, iter: II) -> Self
2540 where
2541 II: IntoIterator<Item = Goal<I>>,
2542 {
2543 let mut iter = iter.into_iter();
2544 if let Some(goal0) = iter.next() {
2545 if let Some(goal1) = iter.next() {
2546 let goals = Goals::from_iter(
2548 interner,
2549 Some(goal0).into_iter().chain(Some(goal1)).chain(iter),
2550 );
2551 GoalData::All(goals).intern(interner)
2552 } else {
2553 goal0
2555 }
2556 } else {
2557 GoalData::All(Goals::empty(interner)).intern(interner)
2559 }
2560 }
2561}
2562
2563#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
2564pub enum GoalData<I: Interner> {
2566 Quantified(QuantifierKind, Binders<Goal<I>>),
2569
2570 Implies(ProgramClauses<I>, Goal<I>),
2572
2573 All(Goals<I>),
2575
2576 Not(Goal<I>),
2578
2579 EqGoal(EqGoal<I>),
2581
2582 SubtypeGoal(SubtypeGoal<I>),
2584
2585 DomainGoal(DomainGoal<I>),
2588
2589 CannotProve,
2597}
2598
2599impl<I: Interner> Copy for GoalData<I>
2600where
2601 I::InternedType: Copy,
2602 I::InternedLifetime: Copy,
2603 I::InternedGenericArg: Copy,
2604 I::InternedSubstitution: Copy,
2605 I::InternedGoal: Copy,
2606 I::InternedGoals: Copy,
2607 I::InternedProgramClauses: Copy,
2608 I::InternedVariableKinds: Copy,
2609{
2610}
2611
2612impl<I: Interner> GoalData<I> {
2613 pub fn intern(self, interner: I) -> Goal<I> {
2615 Goal::new(interner, self)
2616 }
2617}
2618
2619#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
2621pub enum QuantifierKind {
2622 ForAll,
2627
2628 Exists,
2638}
2639
2640#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
2647pub enum Constraint<I: Interner> {
2648 LifetimeOutlives(Lifetime<I>, Lifetime<I>),
2651
2652 TypeOutlives(Ty<I>, Lifetime<I>),
2655}
2656
2657impl<I: Interner> Copy for Constraint<I>
2658where
2659 I::InternedLifetime: Copy,
2660 I::InternedType: Copy,
2661{
2662}
2663
2664impl<I: Interner> Substitution<I> {
2665 pub fn is_identity_subst(&self, interner: I) -> bool {
2678 self.iter(interner).zip(0..).all(|(generic_arg, index)| {
2679 let index_db = BoundVar::new(DebruijnIndex::INNERMOST, index);
2680 match generic_arg.data(interner) {
2681 GenericArgData::Ty(ty) => match ty.kind(interner) {
2682 TyKind::BoundVar(depth) => index_db == *depth,
2683 _ => false,
2684 },
2685 GenericArgData::Lifetime(lifetime) => match lifetime.data(interner) {
2686 LifetimeData::BoundVar(depth) => index_db == *depth,
2687 _ => false,
2688 },
2689 GenericArgData::Const(constant) => match &constant.data(interner).value {
2690 ConstValue::BoundVar(depth) => index_db == *depth,
2691 _ => false,
2692 },
2693 }
2694 })
2695 }
2696
2697 pub fn apply<T>(&self, value: T, interner: I) -> T
2699 where
2700 T: TypeFoldable<I>,
2701 {
2702 Substitute::apply(self, value, interner)
2703 }
2704
2705 pub fn type_parameters(&self, interner: I) -> impl Iterator<Item = Ty<I>> + '_ {
2707 self.iter(interner)
2708 .filter_map(move |p| p.ty(interner))
2709 .cloned()
2710 }
2711
2712 fn compute_flags(&self, interner: I) -> TypeFlags {
2714 let mut flags = TypeFlags::empty();
2715 for generic_arg in self.iter(interner) {
2716 flags |= generic_arg.compute_flags(interner);
2717 }
2718 flags
2719 }
2720}
2721
2722#[derive(FallibleTypeFolder)]
2723struct SubstFolder<'i, I: Interner, A: AsParameters<I>> {
2724 interner: I,
2725 subst: &'i A,
2726}
2727
2728impl<I: Interner, A: AsParameters<I>> SubstFolder<'_, I, A> {
2729 pub fn at(&self, index: usize) -> &GenericArg<I> {
2731 let interner = self.interner;
2732 &self.subst.as_parameters(interner)[index]
2733 }
2734}
2735
2736pub trait AsParameters<I: Interner> {
2738 fn as_parameters(&self, interner: I) -> &[GenericArg<I>];
2740}
2741
2742impl<I: Interner> AsParameters<I> for Substitution<I> {
2743 #[allow(unreachable_code, unused_variables)]
2744 fn as_parameters(&self, interner: I) -> &[GenericArg<I>] {
2745 self.as_slice(interner)
2746 }
2747}
2748
2749impl<I: Interner> AsParameters<I> for [GenericArg<I>] {
2750 fn as_parameters(&self, _interner: I) -> &[GenericArg<I>] {
2751 self
2752 }
2753}
2754
2755impl<I: Interner> AsParameters<I> for [GenericArg<I>; 1] {
2756 fn as_parameters(&self, _interner: I) -> &[GenericArg<I>] {
2757 self
2758 }
2759}
2760
2761impl<I: Interner> AsParameters<I> for Vec<GenericArg<I>> {
2762 fn as_parameters(&self, _interner: I) -> &[GenericArg<I>] {
2763 self
2764 }
2765}
2766
2767impl<T, I: Interner> AsParameters<I> for &T
2768where
2769 T: ?Sized + AsParameters<I>,
2770{
2771 fn as_parameters(&self, interner: I) -> &[GenericArg<I>] {
2772 T::as_parameters(self, interner)
2773 }
2774}
2775
2776pub trait Substitute<I: Interner>: AsParameters<I> {
2779 fn apply<T: TypeFoldable<I>>(&self, value: T, interner: I) -> T;
2781}
2782
2783impl<I: Interner, A: AsParameters<I>> Substitute<I> for A {
2784 fn apply<T>(&self, value: T, interner: I) -> T
2785 where
2786 T: TypeFoldable<I>,
2787 {
2788 value
2789 .try_fold_with(
2790 &mut SubstFolder {
2791 interner,
2792 subst: self,
2793 },
2794 DebruijnIndex::INNERMOST,
2795 )
2796 .unwrap()
2797 }
2798}
2799
2800pub trait ToGenericArg<I: Interner> {
2806 fn to_generic_arg(&self, interner: I) -> GenericArg<I> {
2808 self.to_generic_arg_at_depth(interner, DebruijnIndex::INNERMOST)
2809 }
2810
2811 fn to_generic_arg_at_depth(&self, interner: I, debruijn: DebruijnIndex) -> GenericArg<I>;
2813}
2814
2815impl<'a, I: Interner> ToGenericArg<I> for (usize, &'a VariableKind<I>) {
2816 fn to_generic_arg_at_depth(&self, interner: I, debruijn: DebruijnIndex) -> GenericArg<I> {
2817 let &(index, binder) = self;
2818 let bound_var = BoundVar::new(debruijn, index);
2819 binder.to_bound_variable(interner, bound_var)
2820 }
2821}
2822
2823impl<'i, I: Interner, A: AsParameters<I>> TypeFolder<I> for SubstFolder<'i, I, A> {
2824 fn as_dyn(&mut self) -> &mut dyn TypeFolder<I> {
2825 self
2826 }
2827
2828 fn fold_free_var_ty(&mut self, bound_var: BoundVar, outer_binder: DebruijnIndex) -> Ty<I> {
2829 assert_eq!(bound_var.debruijn, DebruijnIndex::INNERMOST);
2830 let ty = self.at(bound_var.index);
2831 let ty = ty.assert_ty_ref(TypeFolder::interner(self));
2832 ty.clone()
2833 .shifted_in_from(TypeFolder::interner(self), outer_binder)
2834 }
2835
2836 fn fold_free_var_lifetime(
2837 &mut self,
2838 bound_var: BoundVar,
2839 outer_binder: DebruijnIndex,
2840 ) -> Lifetime<I> {
2841 assert_eq!(bound_var.debruijn, DebruijnIndex::INNERMOST);
2842 let l = self.at(bound_var.index);
2843 let l = l.assert_lifetime_ref(TypeFolder::interner(self));
2844 l.clone()
2845 .shifted_in_from(TypeFolder::interner(self), outer_binder)
2846 }
2847
2848 fn fold_free_var_const(
2849 &mut self,
2850 _ty: Ty<I>,
2851 bound_var: BoundVar,
2852 outer_binder: DebruijnIndex,
2853 ) -> Const<I> {
2854 assert_eq!(bound_var.debruijn, DebruijnIndex::INNERMOST);
2855 let c = self.at(bound_var.index);
2856 let c = c.assert_const_ref(TypeFolder::interner(self));
2857 c.clone()
2858 .shifted_in_from(TypeFolder::interner(self), outer_binder)
2859 }
2860
2861 fn interner(&self) -> I {
2862 self.interner
2863 }
2864}
2865
2866macro_rules! interned_slice_common {
2867 ($seq:ident, $data:ident => $elem:ty, $intern:ident => $interned:ident) => {
2868 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
2870 pub struct $seq<I: Interner> {
2871 interned: I::$interned,
2872 }
2873
2874 impl<I: Interner> $seq<I> {
2875 pub fn interned(&self) -> &I::$interned {
2877 &self.interned
2878 }
2879
2880 pub fn as_slice(&self, interner: I) -> &[$elem] {
2882 Interner::$data(interner, &self.interned)
2883 }
2884
2885 pub fn at(&self, interner: I, index: usize) -> &$elem {
2887 &self.as_slice(interner)[index]
2888 }
2889
2890 pub fn empty(interner: I) -> Self {
2892 Self::from_iter(interner, None::<$elem>)
2893 }
2894
2895 pub fn is_empty(&self, interner: I) -> bool {
2897 self.as_slice(interner).is_empty()
2898 }
2899
2900 pub fn iter(&self, interner: I) -> std::slice::Iter<'_, $elem> {
2902 self.as_slice(interner).iter()
2903 }
2904
2905 pub fn len(&self, interner: I) -> usize {
2907 self.as_slice(interner).len()
2908 }
2909 }
2910 };
2911}
2912
2913macro_rules! interned_slice {
2914 ($seq:ident, $data:ident => $elem:ty, $intern:ident => $interned:ident) => {
2915 interned_slice_common!($seq, $data => $elem, $intern => $interned);
2916
2917 impl<I: Interner> $seq<I> {
2918 pub fn from_fallible<E>(
2920 interner: I,
2921 elements: impl IntoIterator<Item = Result<impl CastTo<$elem>, E>>,
2922 ) -> Result<Self, E> {
2923 Ok(Self {
2924 interned: I::$intern(interner, elements.into_iter().casted(interner))?,
2925 })
2926 }
2927
2928 pub fn from_iter(
2930 interner: I,
2931 elements: impl IntoIterator<Item = impl CastTo<$elem>>,
2932 ) -> Self {
2933 Self::from_fallible(
2934 interner,
2935 elements
2936 .into_iter()
2937 .map(|el| -> Result<$elem, ()> { Ok(el.cast(interner)) }),
2938 )
2939 .unwrap()
2940 }
2941
2942 pub fn from1(interner: I, element: impl CastTo<$elem>) -> Self {
2944 Self::from_iter(interner, Some(element))
2945 }
2946 }
2947 };
2948}
2949
2950interned_slice!(
2951 QuantifiedWhereClauses,
2952 quantified_where_clauses_data => QuantifiedWhereClause<I>,
2953 intern_quantified_where_clauses => InternedQuantifiedWhereClauses
2954);
2955
2956interned_slice!(
2957 ProgramClauses,
2958 program_clauses_data => ProgramClause<I>,
2959 intern_program_clauses => InternedProgramClauses
2960);
2961
2962interned_slice!(
2963 VariableKinds,
2964 variable_kinds_data => VariableKind<I>,
2965 intern_generic_arg_kinds => InternedVariableKinds
2966);
2967
2968interned_slice!(
2969 CanonicalVarKinds,
2970 canonical_var_kinds_data => CanonicalVarKind<I>,
2971 intern_canonical_var_kinds => InternedCanonicalVarKinds
2972);
2973
2974interned_slice!(Goals, goals_data => Goal<I>, intern_goals => InternedGoals);
2975
2976interned_slice!(
2977 Constraints,
2978 constraints_data => InEnvironment<Constraint<I>>,
2979 intern_constraints => InternedConstraints
2980);
2981
2982interned_slice!(
2983 Substitution,
2984 substitution_data => GenericArg<I>,
2985 intern_substitution => InternedSubstitution
2986);
2987
2988interned_slice_common!(
2989 Variances,
2990 variances_data => Variance,
2991 intern_variance => InternedVariances
2992);
2993
2994impl<I: Interner> Variances<I> {
2995 pub fn from_fallible<E>(
2997 interner: I,
2998 variances: impl IntoIterator<Item = Result<Variance, E>>,
2999 ) -> Result<Self, E> {
3000 Ok(Variances {
3001 interned: I::intern_variances(interner, variances.into_iter())?,
3002 })
3003 }
3004
3005 pub fn from_iter(interner: I, variances: impl IntoIterator<Item = Variance>) -> Self {
3007 Self::from_fallible(
3008 interner,
3009 variances
3010 .into_iter()
3011 .map(|p| -> Result<Variance, ()> { Ok(p) }),
3012 )
3013 .unwrap()
3014 }
3015
3016 pub fn from1(interner: I, variance: Variance) -> Self {
3018 Self::from_iter(interner, Some(variance))
3019 }
3020}
3021
3022#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
3028pub struct ConstrainedSubst<I: Interner> {
3029 pub subst: Substitution<I>,
3033
3034 pub constraints: Constraints<I>,
3036}
3037
3038#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
3040pub struct AnswerSubst<I: Interner> {
3041 pub subst: Substitution<I>,
3045
3046 pub constraints: Constraints<I>,
3048
3049 pub delayed_subgoals: Vec<InEnvironment<Goal<I>>>,
3051}
3052
3053pub trait UnificationDatabase<I>
3055where
3056 Self: std::fmt::Debug,
3057 I: Interner,
3058{
3059 fn fn_def_variance(&self, fn_def_id: FnDefId<I>) -> Variances<I>;
3061
3062 fn adt_variance(&self, adt_id: AdtId<I>) -> Variances<I>;
3064}