chalk_ir/
lib.rs

1//! Defines the IR for types and logical predicates.
2
3#![deny(rust_2018_idioms)]
4#![warn(missing_docs)]
5
6// Allows macros to refer to this crate as `::chalk_ir`
7extern 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/// Uninhabited (empty) type, used in combination with `PhantomData`.
23#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
24pub enum Void {}
25
26/// Many of our internal operations (e.g., unification) are an attempt
27/// to perform some operation which may not complete.
28pub type Fallible<T> = Result<T, NoSolution>;
29
30/// A combination of `Fallible` and `Floundered`.
31pub enum FallibleOrFloundered<T> {
32    /// Success
33    Ok(T),
34    /// No solution. See `chalk_ir::NoSolution`.
35    NoSolution,
36    /// Floundered. See `chalk_ir::Floundered`.
37    Floundered,
38}
39
40/// Indicates that the attempted operation has "no solution" -- i.e.,
41/// cannot be performed.
42#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
43pub struct NoSolution;
44
45/// Indicates that the complete set of program clauses for this goal
46/// cannot be enumerated.
47pub 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/// Variance
79#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
80pub enum Variance {
81    /// a <: b
82    Covariant,
83    /// a == b
84    Invariant,
85    /// b <: a
86    Contravariant,
87}
88
89impl Variance {
90    /// `a.xform(b)` combines the variance of a context with the
91    /// variance of a type with the following meaning. If we are in a
92    /// context with variance `a`, and we encounter a type argument in
93    /// a position with variance `b`, then `a.xform(b)` is the new
94    /// variance with which the argument appears.
95    ///
96    /// Example 1:
97    ///
98    /// ```ignore
99    /// *mut Vec<i32>
100    /// ```
101    ///
102    /// Here, the "ambient" variance starts as covariant. `*mut T` is
103    /// invariant with respect to `T`, so the variance in which the
104    /// `Vec<i32>` appears is `Covariant.xform(Invariant)`, which
105    /// yields `Invariant`. Now, the type `Vec<T>` is covariant with
106    /// respect to its type argument `T`, and hence the variance of
107    /// the `i32` here is `Invariant.xform(Covariant)`, which results
108    /// (again) in `Invariant`.
109    ///
110    /// Example 2:
111    ///
112    /// ```ignore
113    /// fn(*const Vec<i32>, *mut Vec<i32)
114    /// ```
115    ///
116    /// The ambient variance is covariant. A `fn` type is
117    /// contravariant with respect to its parameters, so the variance
118    /// within which both pointer types appear is
119    /// `Covariant.xform(Contravariant)`, or `Contravariant`. `*const
120    /// T` is covariant with respect to `T`, so the variance within
121    /// which the first `Vec<i32>` appears is
122    /// `Contravariant.xform(Covariant)` or `Contravariant`. The same
123    /// is true for its `i32` argument. In the `*mut T` case, the
124    /// variance of `Vec<i32>` is `Contravariant.xform(Invariant)`,
125    /// and hence the outermost type is `Invariant` with respect to
126    /// `Vec<i32>` (and its `i32` argument).
127    ///
128    /// Source: Figure 1 of "Taming the Wildcards:
129    /// Combining Definition- and Use-Site Variance" published in PLDI'11.
130    /// (Doc from rustc)
131    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    /// Converts `Covariant` into `Contravariant` and vice-versa. `Invariant`
142    /// stays the same.
143    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)]
153/// The set of assumptions we've made so far, and the current number of
154/// universal (forall) quantifiers we're within.
155pub struct Environment<I: Interner> {
156    /// The clauses in the environment.
157    pub clauses: ProgramClauses<I>,
158}
159
160impl<I: Interner> Copy for Environment<I> where I::InternedProgramClauses: Copy {}
161
162impl<I: Interner> Environment<I> {
163    /// Creates a new environment.
164    pub fn new(interner: I) -> Self {
165        Environment {
166            clauses: ProgramClauses::empty(interner),
167        }
168    }
169
170    /// Adds (an iterator of) clauses to the environment.
171    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    /// True if any of the clauses in the environment have a consequence of `Compatible`.
182    /// Panics if the conditions or constraints of that clause are not empty.
183    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                    // We currently don't generate `Compatible` with any conditions or constraints
189                    // If this was needed, for whatever reason, then a third "yes, but must evaluate"
190                    // return value would have to be added.
191                    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/// A goal with an environment to solve it in.
202#[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    /// Creates a new environment/goal pair.
216    pub fn new(environment: &Environment<G::Interner>, goal: G) -> Self {
217        InEnvironment {
218            environment: environment.clone(),
219            goal,
220        }
221    }
222
223    /// Maps the goal without touching the environment.
224    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/// Different signed int types.
241#[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/// Different unsigned int types.
253#[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/// Different kinds of float types.
265#[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/// Types of scalar values.
275#[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/// Whether a function is safe or not.
286#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
287pub enum Safety {
288    /// Safe
289    Safe,
290    /// Unsafe
291    Unsafe,
292}
293
294/// Whether a type is mutable or not.
295#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
296pub enum Mutability {
297    /// Mutable
298    Mut,
299    /// Immutable
300    Not,
301}
302
303/// An universe index is how a universally quantified parameter is
304/// represented when it's binder is moved into the environment.
305/// An example chain of transformations would be:
306/// `forall<T> { Goal(T) }` (syntactical representation)
307/// `forall { Goal(?0) }` (used a DeBruijn index)
308/// `Goal(!U1)` (the quantifier was moved to the environment and replaced with a universe index)
309/// See <https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference.html#placeholders-and-universes> for more.
310#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
311pub struct UniverseIndex {
312    /// The counter for the universe index, starts with 0.
313    pub counter: usize,
314}
315
316impl UniverseIndex {
317    /// Root universe index (0).
318    pub const ROOT: UniverseIndex = UniverseIndex { counter: 0 };
319
320    /// Root universe index (0).
321    pub fn root() -> UniverseIndex {
322        Self::ROOT
323    }
324
325    /// Whether one universe can "see" another.
326    pub fn can_see(self, ui: UniverseIndex) -> bool {
327        self.counter >= ui.counter
328    }
329
330    /// Increases the index counter.
331    pub fn next(self) -> UniverseIndex {
332        UniverseIndex {
333            counter: self.counter + 1,
334        }
335    }
336}
337
338/// Maps the universes found in the `u_canonicalize` result (the
339/// "canonical" universes) to the universes found in the original
340/// value (and vice versa). When used as a folder -- i.e., from
341/// outside this module -- converts from "canonical" universes to the
342/// original (but see the `UMapToCanonical` folder).
343#[derive(Clone, Debug)]
344pub struct UniverseMap {
345    /// A reverse map -- for each universe Ux that appears in
346    /// `quantified`, the corresponding universe in the original was
347    /// `universes[x]`.
348    pub universes: Vec<UniverseIndex>,
349}
350
351impl UniverseMap {
352    /// Creates a new universe map.
353    pub fn new() -> Self {
354        UniverseMap {
355            universes: vec![UniverseIndex::root()],
356        }
357    }
358
359    /// Number of canonical universes.
360    pub fn num_canonical_universes(&self) -> usize {
361        self.universes.len()
362    }
363}
364
365/// The id for an Abstract Data Type (i.e. structs, unions and enums).
366#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
367pub struct AdtId<I: Interner>(pub I::InternedAdtId);
368
369/// The id of a trait definition; could be used to load the trait datum by
370/// invoking the [`trait_datum`] method.
371///
372/// [`trait_datum`]: ../chalk_solve/trait.RustIrDatabase.html#tymethod.trait_datum
373#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
374pub struct TraitId<I: Interner>(pub I::DefId);
375
376/// The id for an impl.
377#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
378pub struct ImplId<I: Interner>(pub I::DefId);
379
380/// Id for a specific clause.
381#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
382pub struct ClauseId<I: Interner>(pub I::DefId);
383
384/// The id for the associated type member of a trait. The details of the type
385/// can be found by invoking the [`associated_ty_data`] method.
386///
387/// [`associated_ty_data`]: ../chalk_solve/trait.RustIrDatabase.html#tymethod.associated_ty_data
388#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
389pub struct AssocTypeId<I: Interner>(pub I::DefId);
390
391/// Id for an opaque type.
392#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
393pub struct OpaqueTyId<I: Interner>(pub I::DefId);
394
395/// Function definition id.
396#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
397pub struct FnDefId<I: Interner>(pub I::DefId);
398
399/// Id for Rust closures.
400#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
401pub struct ClosureId<I: Interner>(pub I::DefId);
402
403/// Id for Rust coroutines.
404#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
405pub struct CoroutineId<I: Interner>(pub I::DefId);
406
407/// Id for foreign types.
408#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
409pub struct ForeignDefId<I: Interner>(pub I::DefId);
410
411impl_debugs!(ImplId, ClauseId);
412
413/// A Rust type. The actual type data is stored in `TyKind`.
414#[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    /// Creates a type from `TyKind`.
421    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    /// Gets the interned type.
429    pub fn interned(&self) -> &I::InternedType {
430        &self.interned
431    }
432
433    /// Gets the underlying type data.
434    pub fn data(&self, interner: I) -> &TyData<I> {
435        I::ty_data(interner, &self.interned)
436    }
437
438    /// Gets the underlying type kind.
439    pub fn kind(&self, interner: I) -> &TyKind<I> {
440        &I::ty_data(interner, &self.interned).kind
441    }
442
443    /// Creates a `FromEnv` constraint using this type.
444    pub fn from_env(&self) -> FromEnv<I> {
445        FromEnv::Ty(self.clone())
446    }
447
448    /// Creates a WF-constraint for this type.
449    pub fn well_formed(&self) -> WellFormed<I> {
450        WellFormed::Ty(self.clone())
451    }
452
453    /// Creates a domain goal `FromEnv(T)` where `T` is this type.
454    pub fn into_from_env_goal(self, interner: I) -> DomainGoal<I> {
455        self.from_env().cast(interner)
456    }
457
458    /// If this is a `TyKind::BoundVar(d)`, returns `Some(d)` else `None`.
459    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    /// If this is a `TyKind::InferenceVar(d)`, returns `Some(d)` else `None`.
468    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    /// Returns true if this is a `BoundVar` or an `InferenceVar` of `TyVariableKind::General`.
477    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    /// Returns true if this is an `Alias`.
492    pub fn is_alias(&self, interner: I) -> bool {
493        matches!(self.kind(interner), TyKind::Alias(..))
494    }
495
496    /// Returns true if this is an `IntTy` or `UintTy`.
497    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    /// Returns true if this is a `FloatTy`.
505    pub fn is_float(&self, interner: I) -> bool {
506        matches!(self.kind(interner), TyKind::Scalar(Scalar::Float(_)))
507    }
508
509    /// Returns `Some(adt_id)` if this is an ADT, `None` otherwise
510    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    /// True if this type contains "bound" types/lifetimes, and hence
518    /// needs to be shifted across binders. This is a very inefficient
519    /// check, intended only for debug assertions, because I am lazy.
520    pub fn needs_shift(&self, interner: I) -> bool {
521        self.has_free_vars(interner)
522    }
523}
524
525/// Contains the data for a Ty
526#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
527pub struct TyData<I: Interner> {
528    /// The kind
529    pub kind: TyKind<I>,
530    /// Type flags
531    pub flags: TypeFlags,
532}
533
534bitflags! {
535    /// Contains flags indicating various properties of a Ty
536    #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
537    pub struct TypeFlags : u16 {
538        /// Does the type contain an InferenceVar
539        const HAS_TY_INFER                = 1;
540        /// Does the type contain a lifetime with an InferenceVar
541        const HAS_RE_INFER                = 1 << 1;
542        /// Does the type contain a ConstValue with an InferenceVar
543        const HAS_CT_INFER                = 1 << 2;
544        /// Does the type contain a Placeholder TyKind
545        const HAS_TY_PLACEHOLDER          = 1 << 3;
546        /// Does the type contain a lifetime with a Placeholder
547        const HAS_RE_PLACEHOLDER          = 1 << 4;
548        /// Does the type contain a ConstValue Placeholder
549        const HAS_CT_PLACEHOLDER          = 1 << 5;
550        /// True when the type has free lifetimes related to a local context
551        const HAS_FREE_LOCAL_REGIONS      = 1 << 6;
552        /// Does the type contain a projection of an associated type
553        const HAS_TY_PROJECTION           = 1 << 7;
554        /// Does the type contain an opaque type
555        const HAS_TY_OPAQUE               = 1 << 8;
556        /// Does the type contain an unevaluated const projection
557        const HAS_CT_PROJECTION           = 1 << 9;
558        /// Does the type contain an error
559        const HAS_ERROR                   = 1 << 10;
560        /// Does the type contain an error lifetime
561        const HAS_RE_ERROR                = 1 << 11;
562        /// Does the type contain any free lifetimes
563        const HAS_FREE_REGIONS            = 1 << 12;
564        /// True when the type contains lifetimes that will be substituted when function is called
565        const HAS_RE_LATE_BOUND           = 1 << 13;
566        /// True when the type contains an erased lifetime
567        const HAS_RE_ERASED               = 1 << 14;
568        /// Does the type contain placeholders or inference variables that could be replaced later
569        const STILL_FURTHER_SPECIALIZABLE = 1 << 15;
570
571        /// True when the type contains free names local to a particular context
572        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        /// Does the type contain any form of projection
579        const HAS_PROJECTION              = TypeFlags::HAS_TY_PROJECTION.bits()
580                                          | TypeFlags::HAS_TY_OPAQUE.bits()
581                                          | TypeFlags::HAS_CT_PROJECTION.bits();
582    }
583}
584/// Type data, which holds the actual type information.
585#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
586pub enum TyKind<I: Interner> {
587    /// Abstract data types, i.e., structs, unions, or enumerations.
588    /// For example, a type like `Vec<T>`.
589    Adt(AdtId<I>, Substitution<I>),
590
591    /// an associated type like `Iterator::Item`; see `AssociatedType` for details
592    AssociatedType(AssocTypeId<I>, Substitution<I>),
593
594    /// a scalar type like `bool` or `u32`
595    Scalar(Scalar),
596
597    /// a tuple of the given arity
598    Tuple(usize, Substitution<I>),
599
600    /// an array type like `[T; N]`
601    Array(Ty<I>, Const<I>),
602
603    /// a slice type like `[T]`
604    Slice(Ty<I>),
605
606    /// a raw pointer type like `*const T` or `*mut T`
607    Raw(Mutability, Ty<I>),
608
609    /// a reference type like `&T` or `&mut T`
610    Ref(Mutability, Lifetime<I>, Ty<I>),
611
612    /// a placeholder for opaque types like `impl Trait`
613    OpaqueType(OpaqueTyId<I>, Substitution<I>),
614
615    /// a function definition
616    FnDef(FnDefId<I>, Substitution<I>),
617
618    /// the string primitive type
619    Str,
620
621    /// the never type `!`
622    Never,
623
624    /// A closure.
625    Closure(ClosureId<I>, Substitution<I>),
626
627    /// A coroutine.
628    Coroutine(CoroutineId<I>, Substitution<I>),
629
630    /// A coroutine witness.
631    CoroutineWitness(CoroutineId<I>, Substitution<I>),
632
633    /// foreign types
634    Foreign(ForeignDefId<I>),
635
636    /// This can be used to represent an error, e.g. during name resolution of a type.
637    /// Chalk itself will not produce this, just pass it through when given.
638    Error,
639
640    /// instantiated from a universally quantified type, e.g., from
641    /// `forall<T> { .. }`. Stands in as a representative of "some
642    /// unknown type".
643    Placeholder(PlaceholderIndex),
644
645    /// A "dyn" type is a trait object type created via the "dyn Trait" syntax.
646    /// In the chalk parser, the traits that the object represents is parsed as
647    /// a QuantifiedInlineBound, and is then changed to a list of where clauses
648    /// during lowering.
649    ///
650    /// See the `Opaque` variant for a discussion about the use of
651    /// binders here.
652    Dyn(DynTy<I>),
653
654    /// An "alias" type represents some form of type alias, such as:
655    /// - An associated type projection like `<T as Iterator>::Item`
656    /// - `impl Trait` types
657    /// - Named type aliases like `type Foo<X> = Vec<X>`
658    Alias(AliasTy<I>),
659
660    /// A function type such as `for<'a> fn(&'a u32)`.
661    /// Note that "higher-ranked" types (starting with `for<>`) are either
662    /// function types or dyn types, and do not appear otherwise in Rust
663    /// surface syntax.
664    Function(FnPointer<I>),
665
666    /// References the binding at the given depth. The index is a [de
667    /// Bruijn index], so it counts back through the in-scope binders.
668    BoundVar(BoundVar),
669
670    /// Inference variable defined in the current inference context.
671    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    /// Casts the type data to a type.
687    pub fn intern(self, interner: I) -> Ty<I> {
688        Ty::new(interner, self)
689    }
690
691    /// Compute type flags for a TyKind
692    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/// Identifies a particular bound variable within a binder.
759/// Variables are identified by the combination of a [`DebruijnIndex`],
760/// which identifies the *binder*, and an index within that binder.
761///
762/// Consider this case:
763///
764/// ```ignore
765/// forall<'a, 'b> { forall<'c, 'd> { ... } }
766/// ```
767///
768/// Within the `...` term:
769///
770/// * the variable `'a` have a debruijn index of 1 and index 0
771/// * the variable `'b` have a debruijn index of 1 and index 1
772/// * the variable `'c` have a debruijn index of 0 and index 0
773/// * the variable `'d` have a debruijn index of 0 and index 1
774///
775/// The variables `'a` and `'b` both have debruijn index of 1 because,
776/// counting out, they are the 2nd binder enclosing `...`. The indices
777/// identify the location *within* that binder.
778///
779/// The variables `'c` and `'d` both have debruijn index of 0 because
780/// they appear in the *innermost* binder enclosing the `...`. The
781/// indices identify the location *within* that binder.
782#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
783pub struct BoundVar {
784    /// Debruijn index, which identifies the binder.
785    pub debruijn: DebruijnIndex,
786    /// Index within the binder.
787    pub index: usize,
788}
789
790impl BoundVar {
791    /// Creates a new bound variable.
792    pub fn new(debruijn: DebruijnIndex, index: usize) -> Self {
793        Self { debruijn, index }
794    }
795
796    /// Casts the bound variable to a type.
797    pub fn to_ty<I: Interner>(self, interner: I) -> Ty<I> {
798        TyKind::<I>::BoundVar(self).intern(interner)
799    }
800
801    /// Wrap the bound variable in a lifetime.
802    pub fn to_lifetime<I: Interner>(self, interner: I) -> Lifetime<I> {
803        LifetimeData::<I>::BoundVar(self).intern(interner)
804    }
805
806    /// Wraps the bound variable in a constant.
807    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    /// True if this variable is bound within the `amount` innermost binders.
816    pub fn bound_within(self, outer_binder: DebruijnIndex) -> bool {
817        self.debruijn.within(outer_binder)
818    }
819
820    /// Adjusts the debruijn index (see [`DebruijnIndex::shifted_in`]).
821    #[must_use]
822    pub fn shifted_in(self) -> Self {
823        BoundVar::new(self.debruijn.shifted_in(), self.index)
824    }
825
826    /// Adjusts the debruijn index (see [`DebruijnIndex::shifted_in`]).
827    #[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    /// Adjusts the debruijn index (see [`DebruijnIndex::shifted_in`]).
833    #[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    /// Adjusts the debruijn index (see [`DebruijnIndex::shifted_in`]).
841    #[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    /// Return the index of the bound variable, but only if it is bound
849    /// at the innermost binder. Otherwise, returns `None`.
850    pub fn index_if_innermost(self) -> Option<usize> {
851        self.index_if_bound_at(DebruijnIndex::INNERMOST)
852    }
853
854    /// Return the index of the bound variable, but only if it is bound
855    /// at the innermost binder. Otherwise, returns `None`.
856    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/// References the binder at the given depth. The index is a [de
866/// Bruijn index], so it counts back through the in-scope binders,
867/// with 0 being the innermost binder. This is used in impls and
868/// the like. For example, if we had a rule like `for<T> { (T:
869/// Clone) :- (T: Copy) }`, then `T` would be represented as a
870/// `BoundVar(0)` (as the `for` is the innermost binder).
871///
872/// [de Bruijn index]: https://en.wikipedia.org/wiki/De_Bruijn_index
873#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
874pub struct DebruijnIndex {
875    depth: u32,
876}
877
878impl DebruijnIndex {
879    /// Innermost index.
880    pub const INNERMOST: DebruijnIndex = DebruijnIndex { depth: 0 };
881    /// One level higher than the innermost index.
882    pub const ONE: DebruijnIndex = DebruijnIndex { depth: 1 };
883
884    /// Creates a new de Bruijn index with a given depth.
885    pub fn new(depth: u32) -> Self {
886        DebruijnIndex { depth }
887    }
888
889    /// Depth of the De Bruijn index, counting from 0 starting with
890    /// the innermost binder.
891    pub fn depth(self) -> u32 {
892        self.depth
893    }
894
895    /// True if the binder identified by this index is within the
896    /// binder identified by the index `outer_binder`.
897    ///
898    /// # Example
899    ///
900    /// Imagine you have the following binders in scope
901    ///
902    /// ```ignore
903    /// forall<a> forall<b> forall<c>
904    /// ```
905    ///
906    /// then the Debruijn index for `c` would be `0`, the index for
907    /// `b` would be 1, and so on. Now consider the following calls:
908    ///
909    /// * `c.within(a) = true`
910    /// * `b.within(a) = true`
911    /// * `a.within(a) = false`
912    /// * `a.within(c) = false`
913    pub fn within(self, outer_binder: DebruijnIndex) -> bool {
914        self < outer_binder
915    }
916
917    /// Returns the resulting index when this value is moved into
918    /// through one binder.
919    #[must_use]
920    pub fn shifted_in(self) -> DebruijnIndex {
921        self.shifted_in_from(DebruijnIndex::ONE)
922    }
923
924    /// Update this index in place by shifting it "in" through
925    /// `amount` number of binders.
926    pub fn shift_in(&mut self) {
927        *self = self.shifted_in();
928    }
929
930    /// Adds `outer_binder` levels to the `self` index. Intuitively, this
931    /// shifts the `self` index, which was valid at the outer binder,
932    /// so that it is valid at the innermost binder.
933    ///
934    /// Example: Assume that the following binders are in scope:
935    ///
936    /// ```ignore
937    /// for<A> for<B> for<C> for<D>
938    ///            ^ outer binder
939    /// ```
940    ///
941    /// Assume further that the `outer_binder` argument is 2,
942    /// which means that it is referring to the `for<B>` binder
943    /// (since `D` would be the innermost binder).
944    ///
945    /// This means that `self` is relative to the binder `B` -- so
946    /// if `self` is 0 (`INNERMOST`), then it refers to `B`,
947    /// and if `self` is 1, then it refers to `A`.
948    ///
949    /// We will return as follows:
950    ///
951    /// * `0.shifted_in_from(2) = 2` -- i.e., `B`, when shifted in to the binding level `D`, has index 2
952    /// * `1.shifted_in_from(2) = 3` -- i.e., `A`, when shifted in to the binding level `D`, has index 3
953    /// * `2.shifted_in_from(1) = 3` -- here, we changed the `outer_binder`  to refer to `C`.
954    ///   Therefore `2` (relative to `C`) refers to `A`, so the result is still 3 (since `A`, relative to the
955    ///   innermost binder, has index 3).
956    #[must_use]
957    pub fn shifted_in_from(self, outer_binder: DebruijnIndex) -> DebruijnIndex {
958        DebruijnIndex::new(self.depth() + outer_binder.depth())
959    }
960
961    /// Returns the resulting index when this value is moved out from
962    /// `amount` number of new binders.
963    #[must_use]
964    pub fn shifted_out(self) -> Option<DebruijnIndex> {
965        self.shifted_out_to(DebruijnIndex::ONE)
966    }
967
968    /// Update in place by shifting out from `amount` binders.
969    pub fn shift_out(&mut self) {
970        *self = self.shifted_out().unwrap();
971    }
972
973    /// Subtracts `outer_binder` levels from the `self` index. Intuitively, this
974    /// shifts the `self` index, which was valid at the innermost
975    /// binder, to one that is valid at the binder `outer_binder`.
976    ///
977    /// This will return `None` if the `self` index is internal to the
978    /// outer binder (i.e., if `self < outer_binder`).
979    ///
980    /// Example: Assume that the following binders are in scope:
981    ///
982    /// ```ignore
983    /// for<A> for<B> for<C> for<D>
984    ///            ^ outer binder
985    /// ```
986    ///
987    /// Assume further that the `outer_binder` argument is 2,
988    /// which means that it is referring to the `for<B>` binder
989    /// (since `D` would be the innermost binder).
990    ///
991    /// This means that the result is relative to the binder `B` -- so
992    /// if `self` is 0 (`INNERMOST`), then it refers to `B`,
993    /// and if `self` is 1, then it refers to `A`.
994    ///
995    /// We will return as follows:
996    ///
997    /// * `1.shifted_out_to(2) = None` -- i.e., the binder for `C` can't be named from the binding level `B`
998    /// * `3.shifted_out_to(2) = Some(1)` -- i.e., `A`, when shifted out to the binding level `B`, has index 1
999    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/// A "DynTy" represents a trait object (`dyn Trait`). Trait objects
1009/// are conceptually very related to an "existential type" of the form
1010/// `exists<T> { T: Trait }` (another example of such type is `impl Trait`).
1011/// `DynTy` represents the bounds on that type.
1012///
1013/// The "bounds" here represents the unknown self type. So, a type like
1014/// `dyn for<'a> Fn(&'a u32)` would be represented with two-levels of
1015/// binder, as "depicted" here:
1016///
1017/// ```notrust
1018/// exists<type> {
1019///    vec![
1020///        // A QuantifiedWhereClause:
1021///        forall<region> { ^1.0: Fn(&^0.0 u32) }
1022///    ]
1023/// }
1024/// ```
1025///
1026/// The outer `exists<type>` binder indicates that there exists
1027/// some type that meets the criteria within, but that type is not
1028/// known. It is referenced within the type using `^1.0`, indicating
1029/// a bound type with debruijn index 1 (i.e., skipping through one
1030/// level of binder).
1031#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
1032pub struct DynTy<I: Interner> {
1033    /// The unknown self type.
1034    pub bounds: Binders<QuantifiedWhereClauses<I>>,
1035    /// Lifetime of the `DynTy`.
1036    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/// A type, lifetime or constant whose value is being inferred.
1048#[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    /// Gets the underlying index value.
1061    pub fn index(self) -> u32 {
1062        self.index
1063    }
1064
1065    /// Wraps the inference variable in a type.
1066    pub fn to_ty<I: Interner>(self, interner: I, kind: TyVariableKind) -> Ty<I> {
1067        TyKind::<I>::InferenceVar(self, kind).intern(interner)
1068    }
1069
1070    /// Wraps the inference variable in a lifetime.
1071    pub fn to_lifetime<I: Interner>(self, interner: I) -> Lifetime<I> {
1072        LifetimeData::<I>::InferenceVar(self).intern(interner)
1073    }
1074
1075    /// Wraps the inference variable in a constant.
1076    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/// A function signature.
1086#[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/// A wrapper for the substs on a Fn.
1094#[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/// for<'a...'z> X -- all binders are instantiated at once,
1100/// and we use deBruijn indices within `self.ty`
1101#[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    /// Represent the current `Fn` as if it was wrapped in `Binders`
1113    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    /// Represent the current `Fn` as if it was wrapped in `Binders`
1124    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/// Constants.
1136#[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    /// Create a `Const` using something that can be cast to const data.
1143    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    /// Gets the interned constant.
1150    pub fn interned(&self) -> &I::InternedConst {
1151        &self.interned
1152    }
1153
1154    /// Gets the constant data from the interner.
1155    pub fn data(&self, interner: I) -> &ConstData<I> {
1156        I::const_data(interner, &self.interned)
1157    }
1158
1159    /// If this is a `ConstData::BoundVar(d)`, returns `Some(d)` else `None`.
1160    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    /// If this is a `ConstData::InferenceVar(d)`, returns `Some(d)` else `None`.
1169    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    /// True if this const is a "bound" const, and hence
1178    /// needs to be shifted across binders. Meant for debug assertions.
1179    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/// Constant data, containing the constant's type and value.
1190#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
1191pub struct ConstData<I: Interner> {
1192    /// Type that holds the constant.
1193    pub ty: Ty<I>,
1194    /// The value of the constant.
1195    pub value: ConstValue<I>,
1196}
1197
1198/// A constant value, not necessarily concrete.
1199#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
1200pub enum ConstValue<I: Interner> {
1201    /// Bound var (e.g. a parameter).
1202    BoundVar(BoundVar),
1203    /// Constant whose value is being inferred.
1204    InferenceVar(InferenceVar),
1205    /// Lifetime on some yet-unknown placeholder.
1206    Placeholder(PlaceholderIndex),
1207    /// Concrete constant value.
1208    Concrete(ConcreteConst<I>),
1209}
1210
1211impl<I: Interner> Copy for ConstValue<I> where I::InternedConcreteConst: Copy {}
1212
1213impl<I: Interner> ConstData<I> {
1214    /// Wraps the constant data in a `Const`.
1215    pub fn intern(self, interner: I) -> Const<I> {
1216        Const::new(interner, self)
1217    }
1218}
1219
1220/// Concrete constant, whose value is known (as opposed to
1221/// inferred constants and placeholders).
1222#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
1223pub struct ConcreteConst<I: Interner> {
1224    /// The interned constant.
1225    pub interned: I::InternedConcreteConst,
1226}
1227
1228impl<I: Interner> ConcreteConst<I> {
1229    /// Checks whether two concrete constants are equal.
1230    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/// A Rust lifetime.
1236#[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    /// Create a lifetime from lifetime data
1243    /// (or something that can be cast to lifetime data).
1244    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    /// Gets the interned value.
1251    pub fn interned(&self) -> &I::InternedLifetime {
1252        &self.interned
1253    }
1254
1255    /// Gets the lifetime data.
1256    pub fn data(&self, interner: I) -> &LifetimeData<I> {
1257        I::lifetime_data(interner, &self.interned)
1258    }
1259
1260    /// If this is a `Lifetime::BoundVar(d)`, returns `Some(d)` else `None`.
1261    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    /// If this is a `Lifetime::InferenceVar(d)`, returns `Some(d)` else `None`.
1270    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    /// True if this lifetime is a "bound" lifetime, and hence
1279    /// needs to be shifted across binders. Meant for debug assertions.
1280    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    ///compute type flags for Lifetime
1293    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/// Lifetime data, including what kind of lifetime it is and what it points to.
1315#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
1316pub enum LifetimeData<I: Interner> {
1317    /// See TyKind::BoundVar.
1318    BoundVar(BoundVar),
1319    /// Lifetime whose value is being inferred.
1320    InferenceVar(InferenceVar),
1321    /// Lifetime on some yet-unknown placeholder.
1322    Placeholder(PlaceholderIndex),
1323    /// Static lifetime
1324    Static,
1325    /// An erased lifetime, used by rustc to improve caching when we doesn't
1326    /// care about lifetimes
1327    Erased,
1328    /// Lifetime on phantom data.
1329    Phantom(Void, PhantomData<I>),
1330    /// A lifetime that resulted from some error
1331    Error,
1332}
1333
1334impl<I: Interner> LifetimeData<I> {
1335    /// Wrap the lifetime data in a lifetime.
1336    pub fn intern(self, interner: I) -> Lifetime<I> {
1337        Lifetime::new(interner, self)
1338    }
1339}
1340
1341/// Index of an universally quantified parameter in the environment.
1342/// Two indexes are required, the one of the universe itself
1343/// and the relative index inside the universe.
1344#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1345pub struct PlaceholderIndex {
1346    /// Index *of* the universe.
1347    pub ui: UniverseIndex,
1348    /// Index *in* the universe.
1349    pub idx: usize,
1350}
1351
1352impl PlaceholderIndex {
1353    /// Wrap the placeholder instance in a lifetime.
1354    pub fn to_lifetime<I: Interner>(self, interner: I) -> Lifetime<I> {
1355        LifetimeData::<I>::Placeholder(self).intern(interner)
1356    }
1357
1358    /// Create an interned type.
1359    pub fn to_ty<I: Interner>(self, interner: I) -> Ty<I> {
1360        TyKind::Placeholder(self).intern(interner)
1361    }
1362
1363    /// Wrap the placeholder index in a constant.
1364    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/// Represents some extra knowledge we may have about the type variable.
1373/// ```ignore
1374/// let x: &[u32];
1375/// let i = 1;
1376/// x[i]
1377/// ```
1378/// In this example, `i` is known to be some type of integer. We can infer that
1379/// it is `usize` because that is the only integer type that slices have an
1380/// `Index` impl for. `i` would have a `TyVariableKind` of `Integer` to guide the
1381/// inference process.
1382#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1383#[allow(missing_docs)]
1384pub enum TyVariableKind {
1385    General,
1386    Integer,
1387    Float,
1388}
1389
1390/// The "kind" of variable. Type, lifetime or constant.
1391#[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/// A generic argument, see `GenericArgData` for more information.
1428#[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    /// Constructs a generic argument using `GenericArgData`.
1435    pub fn new(interner: I, data: GenericArgData<I>) -> Self {
1436        let interned = I::intern_generic_arg(interner, data);
1437        GenericArg { interned }
1438    }
1439
1440    /// Gets the interned value.
1441    pub fn interned(&self) -> &I::InternedGenericArg {
1442        &self.interned
1443    }
1444
1445    /// Gets the underlying data.
1446    pub fn data(&self, interner: I) -> &GenericArgData<I> {
1447        I::generic_arg_data(interner, &self.interned)
1448    }
1449
1450    /// Asserts that this is a type argument.
1451    pub fn assert_ty_ref(&self, interner: I) -> &Ty<I> {
1452        self.ty(interner).unwrap()
1453    }
1454
1455    /// Asserts that this is a lifetime argument.
1456    pub fn assert_lifetime_ref(&self, interner: I) -> &Lifetime<I> {
1457        self.lifetime(interner).unwrap()
1458    }
1459
1460    /// Asserts that this is a constant argument.
1461    pub fn assert_const_ref(&self, interner: I) -> &Const<I> {
1462        self.constant(interner).unwrap()
1463    }
1464
1465    /// Checks whether the generic argument is a type.
1466    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    /// Returns the type if it is one, `None` otherwise.
1475    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    /// Returns the lifetime if it is one, `None` otherwise.
1483    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    /// Returns the constant if it is one, `None` otherwise.
1491    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    /// Compute type flags for GenericArg<I>
1499    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/// Generic arguments data.
1524#[derive(Clone, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable, Zip)]
1525pub enum GenericArgData<I: Interner> {
1526    /// Type argument
1527    Ty(Ty<I>),
1528    /// Lifetime argument
1529    Lifetime(Lifetime<I>),
1530    /// Constant argument
1531    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    /// Create an interned type.
1544    pub fn intern(self, interner: I) -> GenericArg<I> {
1545        GenericArg::new(interner, self)
1546    }
1547}
1548
1549/// A value with an associated variable kind.
1550#[derive(Clone, PartialEq, Eq, Hash)]
1551pub struct WithKind<I: Interner, T> {
1552    /// The associated variable kind.
1553    pub kind: VariableKind<I>,
1554    /// The wrapped value.
1555    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    /// Creates a `WithKind` from a variable kind and a value.
1572    pub fn new(kind: VariableKind<I>, value: T) -> Self {
1573        Self { kind, value }
1574    }
1575
1576    /// Maps the value in `WithKind`.
1577    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    /// Maps a function taking `WithKind<I, &T>` over `&WithKind<I, T>`.
1588    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    /// Extract the value, ignoring the variable kind.
1599    pub fn skip_kind(&self) -> &T {
1600        &self.value
1601    }
1602}
1603
1604/// A variable kind with universe index.
1605#[allow(type_alias_bounds)]
1606pub type CanonicalVarKind<I: Interner> = WithKind<I, UniverseIndex>;
1607
1608/// An alias, which is a trait indirection such as a projection or opaque type.
1609#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
1610pub enum AliasTy<I: Interner> {
1611    /// An associated type projection.
1612    Projection(ProjectionTy<I>),
1613    /// An opaque type.
1614    Opaque(OpaqueTy<I>),
1615}
1616
1617impl<I: Interner> Copy for AliasTy<I> where I::InternedSubstitution: Copy {}
1618
1619impl<I: Interner> AliasTy<I> {
1620    /// Create an interned type for this alias.
1621    pub fn intern(self, interner: I) -> Ty<I> {
1622        Ty::new(interner, self)
1623    }
1624
1625    /// Compute type flags for aliases
1626    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/// A projection `<P0 as TraitName<P1..Pn>>::AssocItem<Pn+1..Pm>`.
1639#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
1640pub struct ProjectionTy<I: Interner> {
1641    /// The id for the associated type member.
1642    pub associated_ty_id: AssocTypeId<I>,
1643    /// The substitution for the projection.
1644    pub substitution: Substitution<I>,
1645}
1646
1647impl<I: Interner> Copy for ProjectionTy<I> where I::InternedSubstitution: Copy {}
1648
1649/// An opaque type `opaque type T<..>: Trait = HiddenTy`.
1650#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
1651pub struct OpaqueTy<I: Interner> {
1652    /// The id for the opaque type.
1653    pub opaque_ty_id: OpaqueTyId<I>,
1654    /// The substitution for the opaque type.
1655    pub substitution: Substitution<I>,
1656}
1657
1658impl<I: Interner> Copy for OpaqueTy<I> where I::InternedSubstitution: Copy {}
1659
1660/// A trait reference describes the relationship between a type and a trait.
1661/// This can be used in two forms:
1662/// - `P0: Trait<P1..Pn>` (e.g. `i32: Copy`), which mentions that the type
1663///   implements the trait.
1664/// - `<P0 as Trait<P1..Pn>>` (e.g. `i32 as Copy`), which casts the type to
1665///   that specific trait.
1666#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
1667pub struct TraitRef<I: Interner> {
1668    /// The trait id.
1669    pub trait_id: TraitId<I>,
1670    /// The substitution, containing both the `Self` type and the parameters.
1671    pub substitution: Substitution<I>,
1672}
1673
1674impl<I: Interner> Copy for TraitRef<I> where I::InternedSubstitution: Copy {}
1675
1676impl<I: Interner> TraitRef<I> {
1677    /// Gets all type parameters in this trait ref, including `Self`.
1678    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    /// Gets the type parameters of the `Self` type in this trait ref.
1686    pub fn self_type_parameter(&self, interner: I) -> Ty<I> {
1687        self.type_parameters(interner).next().unwrap()
1688    }
1689
1690    /// Construct a `FromEnv` using this trait ref.
1691    pub fn from_env(self) -> FromEnv<I> {
1692        FromEnv::Trait(self)
1693    }
1694
1695    /// Construct a `WellFormed` using this trait ref.
1696    pub fn well_formed(self) -> WellFormed<I> {
1697        WellFormed::Trait(self)
1698    }
1699}
1700
1701/// Lifetime outlives, which for `'a: 'b` checks that the lifetime `'a`
1702/// is a superset of the value of `'b`.
1703#[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/// Type outlives, which for `T: 'a` checks that the type `T`
1713/// lives at least as long as the lifetime `'a`
1714#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
1715pub struct TypeOutlives<I: Interner> {
1716    /// The type which must outlive the given lifetime.
1717    pub ty: Ty<I>,
1718    /// The lifetime which the type must outlive.
1719    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/// Where clauses that can be written by a Rust programmer.
1730#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeSuperVisitable, HasInterner, Zip)]
1731pub enum WhereClause<I: Interner> {
1732    /// Type implements a trait.
1733    Implemented(TraitRef<I>),
1734    /// Type is equal to an alias.
1735    AliasEq(AliasEq<I>),
1736    /// One lifetime outlives another.
1737    LifetimeOutlives(LifetimeOutlives<I>),
1738    /// Type outlives a lifetime.
1739    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/// Checks whether a type or trait ref is well-formed.
1751#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
1752pub enum WellFormed<I: Interner> {
1753    /// A predicate which is true when some trait ref is well-formed.
1754    /// For example, given the following trait definitions:
1755    ///
1756    /// ```notrust
1757    /// trait Clone { ... }
1758    /// trait Copy where Self: Clone { ... }
1759    /// ```
1760    ///
1761    /// then we have the following rule:
1762    ///
1763    /// ```notrust
1764    /// WellFormed(?Self: Copy) :- ?Self: Copy, WellFormed(?Self: Clone)
1765    /// ```
1766    Trait(TraitRef<I>),
1767
1768    /// A predicate which is true when some type is well-formed.
1769    /// For example, given the following type definition:
1770    ///
1771    /// ```notrust
1772    /// struct Set<K> where K: Hash {
1773    ///     ...
1774    /// }
1775    /// ```
1776    ///
1777    /// then we have the following rule: `WellFormedTy(Set<K>) :- Implemented(K: Hash)`.
1778    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/// Checks whether a type or trait ref can be derived from the contents of the environment.
1789#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
1790pub enum FromEnv<I: Interner> {
1791    /// A predicate which enables deriving everything which should be true if we *know* that
1792    /// some trait ref is well-formed. For example given the above trait definitions, we can use
1793    /// `FromEnv(T: Copy)` to derive that `T: Clone`, like in:
1794    ///
1795    /// ```notrust
1796    /// forall<T> {
1797    ///     if (FromEnv(T: Copy)) {
1798    ///         T: Clone
1799    ///     }
1800    /// }
1801    /// ```
1802    Trait(TraitRef<I>),
1803
1804    /// A predicate which enables deriving everything which should be true if we *know* that
1805    /// some type is well-formed. For example given the above type definition, we can use
1806    /// `FromEnv(Set<K>)` to derive that `K: Hash`, like in:
1807    ///
1808    /// ```notrust
1809    /// forall<K> {
1810    ///     if (FromEnv(Set<K>)) {
1811    ///         K: Hash
1812    ///     }
1813    /// }
1814    /// ```
1815    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/// A "domain goal" is a goal that is directly about Rust, rather than a pure
1826/// logical statement. As much as possible, the Chalk solver should avoid
1827/// decomposing this enum, and instead treat its values opaquely.
1828#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeSuperVisitable, HasInterner, Zip)]
1829pub enum DomainGoal<I: Interner> {
1830    /// Simple goal that is true if the where clause is true.
1831    Holds(WhereClause<I>),
1832
1833    /// True if the type or trait ref is well-formed.
1834    WellFormed(WellFormed<I>),
1835
1836    /// True if the trait ref can be derived from in-scope where clauses.
1837    FromEnv(FromEnv<I>),
1838
1839    /// True if the alias type can be normalized to some other type
1840    Normalize(Normalize<I>),
1841
1842    /// True if a type is considered to have been "defined" by the current crate. This is true for
1843    /// a `struct Foo { }` but false for a `#[upstream] struct Foo { }`. However, for fundamental types
1844    /// like `Box<T>`, it is true if `T` is local.
1845    IsLocal(Ty<I>),
1846
1847    /// True if a type is *not* considered to have been "defined" by the current crate. This is
1848    /// false for a `struct Foo { }` but true for a `#[upstream] struct Foo { }`. However, for
1849    /// fundamental types like `Box<T>`, it is true if `T` is upstream.
1850    IsUpstream(Ty<I>),
1851
1852    /// True if a type and its input types are fully visible, known types. That is, there are no
1853    /// unknown type parameters anywhere in this type.
1854    ///
1855    /// More formally, for each struct S<P0..Pn>:
1856    /// forall<P0..Pn> {
1857    ///     IsFullyVisible(S<P0...Pn>) :-
1858    ///         IsFullyVisible(P0),
1859    ///         ...
1860    ///         IsFullyVisible(Pn)
1861    /// }
1862    ///
1863    /// Note that any of these types can have lifetimes in their parameters too, but we only
1864    /// consider type parameters.
1865    IsFullyVisible(Ty<I>),
1866
1867    /// Used to dictate when trait impls are allowed in the current (local) crate based on the
1868    /// orphan rules.
1869    ///
1870    /// `LocalImplAllowed(T: Trait)` is true if the type T is allowed to impl trait Trait in
1871    /// the current crate. Under the current rules, this is unconditionally true for all types if
1872    /// the Trait is considered to be "defined" in the current crate. If that is not the case, then
1873    /// `LocalImplAllowed(T: Trait)` can still be true if `IsLocal(T)` is true.
1874    LocalImplAllowed(TraitRef<I>),
1875
1876    /// Used to activate the "compatible modality" rules. Rules that introduce predicates that have
1877    /// to do with "all compatible universes" should depend on this clause so that they only apply
1878    /// if this is present.
1879    Compatible,
1880
1881    /// Used to indicate that a given type is in a downstream crate. Downstream crates contain the
1882    /// current crate at some level of their dependencies.
1883    ///
1884    /// Since chalk does not actually see downstream types, this is usually introduced with
1885    /// implication on a fresh, universally quantified type.
1886    ///
1887    /// forall<T> { if (DownstreamType(T)) { /* ... */ } }
1888    ///
1889    /// This makes a new type `T` available and makes `DownstreamType(T)` provable for that type.
1890    DownstreamType(Ty<I>),
1891
1892    /// Used to activate the "reveal mode", in which opaque (`impl Trait`) types can be equated
1893    /// to their actual type.
1894    Reveal,
1895
1896    /// Used to indicate that a trait is object safe.
1897    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
1908/// A where clause that can contain `forall<>` or `exists<>` quantifiers.
1909pub type QuantifiedWhereClause<I> = Binders<WhereClause<I>>;
1910
1911impl<I: Interner> WhereClause<I> {
1912    /// Turn a where clause into the WF version of it i.e.:
1913    /// * `Implemented(T: Trait)` maps to `WellFormed(T: Trait)`
1914    /// * `ProjectionEq(<T as Trait>::Item = Foo)` maps to `WellFormed(<T as Trait>::Item = Foo)`
1915    /// * any other clause maps to itself
1916    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    /// Same as `into_well_formed_goal` but with the `FromEnv` predicate instead of `WellFormed`.
1924    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    /// If where clause is a `TraitRef`, returns its trait id.
1932    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    /// As with `WhereClause::into_well_formed_goal`, but for a
1944    /// quantified where clause. For example, `forall<T> {
1945    /// Implemented(T: Trait)}` would map to `forall<T> {
1946    /// WellFormed(T: Trait) }`.
1947    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    /// As with `WhereClause::into_from_env_goal`, but mapped over any
1952    /// binders. For example, `forall<T> {
1953    /// Implemented(T: Trait)}` would map to `forall<T> {
1954    /// FromEnv(T: Trait) }`.
1955    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    /// If the underlying where clause is a `TraitRef`, returns its trait id.
1960    pub fn trait_id(&self) -> Option<TraitId<I>> {
1961        self.skip_binders().trait_id()
1962    }
1963}
1964
1965impl<I: Interner> DomainGoal<I> {
1966    /// Convert `Implemented(...)` into `FromEnv(...)`, but leave other
1967    /// goals unchanged.
1968    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    /// Lists generic arguments that are inputs to this domain goal.
1976    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/// Equality goal: tries to prove that two values are equal.
1987#[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/// Subtype goal: tries to prove that `a` is a subtype of `b`
1997#[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/// Proves that the given type alias **normalizes** to the given
2007/// type. A projection `T::Foo` normalizes to the type `U` if we can
2008/// **match it to an impl** and that impl has a `type Foo = V` where
2009/// `U = V`.
2010#[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/// Proves **equality** between an alias and a type.
2025#[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/// Indicates that the `value` is universally quantified over `N`
2044/// parameters of the given kinds, where `N == self.binders.len()`. A
2045/// variable with depth `i < N` refers to the value at
2046/// `self.binders[i]`. Variables with depth `>= N` are free.
2047///
2048/// (IOW, we use deBruijn indices, where binders are introduced in reverse order
2049/// of `self.binders`.)
2050#[derive(Clone, PartialEq, Eq, Hash)]
2051pub struct Binders<T: HasInterner> {
2052    /// The binders that quantify over the value.
2053    pub binders: VariableKinds<T::Interner>,
2054
2055    /// The value being quantified over.
2056    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    /// Converts a `Binders<&T>` to a `Binders<T>` by cloning `T`.
2070    pub fn cloned(self) -> Binders<T> {
2071        self.map(Clone::clone)
2072    }
2073}
2074
2075impl<T: HasInterner> Binders<T> {
2076    /// Create new binders.
2077    pub fn new(binders: VariableKinds<T::Interner>, value: T) -> Self {
2078        Self { binders, value }
2079    }
2080
2081    /// Wraps the given value in a binder without variables, i.e. `for<>
2082    /// (value)`. Since our deBruijn indices count binders, not variables, this
2083    /// is sometimes useful.
2084    pub fn empty(interner: T::Interner, value: T) -> Self {
2085        let binders = VariableKinds::empty(interner);
2086        Self { binders, value }
2087    }
2088
2089    /// Skips the binder and returns the "bound" value. This is a
2090    /// risky thing to do because it's easy to get confused about
2091    /// De Bruijn indices and the like. `skip_binder` is only valid
2092    /// when you are either extracting data that has nothing to
2093    /// do with bound vars, or you are being very careful about
2094    /// your depth accounting.
2095    ///
2096    /// Some examples where `skip_binder` is reasonable:
2097    ///
2098    /// - extracting the `TraitId` from a TraitRef;
2099    /// - checking if there are any fields in a StructDatum
2100    pub fn skip_binders(&self) -> &T {
2101        &self.value
2102    }
2103
2104    /// Skips the binder and returns the "bound" value as well as the skipped free variables. This
2105    /// is just as risky as [`skip_binders`][Self::skip_binders].
2106    pub fn into_value_and_skipped_binders(self) -> (T, VariableKinds<T::Interner>) {
2107        (self.value, self.binders)
2108    }
2109
2110    /// Converts `&Binders<T>` to `Binders<&T>`. Produces new `Binders`
2111    /// with cloned quantifiers containing a reference to the original
2112    /// value, leaving the original in place.
2113    pub fn as_ref(&self) -> Binders<&T> {
2114        Binders {
2115            binders: self.binders.clone(),
2116            value: &self.value,
2117        }
2118    }
2119
2120    /// Maps the binders by applying a function.
2121    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    /// Transforms the inner value according to the given function; returns
2134    /// `None` if the function returns `None`.
2135    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    /// Maps a function taking `Binders<&T>` over `&Binders<T>`.
2148    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    /// Creates a `Substitution` containing bound vars such that applying this
2157    /// substitution will not change the value, i.e. `^0.0, ^0.1, ^0.2` and so
2158    /// on.
2159    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    /// Creates a fresh binders that contains a single type
2170    /// variable. The result of the closure will be embedded in this
2171    /// binder. Note that you should be careful with what you return
2172    /// from the closure to account for the binder that will be added.
2173    ///
2174    /// XXX FIXME -- this is potentially a pretty footgun-y function.
2175    pub fn with_fresh_type_var(
2176        interner: T::Interner,
2177        op: impl FnOnce(Ty<T::Interner>) -> T,
2178    ) -> Binders<T> {
2179        // The new variable is at the front and everything afterwards is shifted up by 1
2180        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    /// Returns the number of binders.
2187    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    /// This turns two levels of binders (`for<A> for<B>`) into one level (`for<A, B>`).
2198    pub fn fuse_binders(self, interner: T::Interner) -> Binders<T> {
2199        let num_binders = self.len(interner);
2200        // generate a substitution to shift the indexes of the inner binder:
2201        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    /// Substitute `parameters` for the variables introduced by these
2233    /// binders. So if the binders represent (e.g.) `<X, Y> { T }` and
2234    /// parameters is the slice `[A, B]`, then returns `[X => A, Y =>
2235    /// B] T`.
2236    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
2243/// Allows iterating over a Binders<Vec<T>>, for instance.
2244/// Each element will include the same set of parameter bounds.
2245impl<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
2261/// `IntoIterator` for binders.
2262pub 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/// Represents one clause of the form `consequence :- conditions` where
2281/// `conditions = cond_1 && cond_2 && ...` is the conjunction of the individual
2282/// conditions.
2283#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
2284pub struct ProgramClauseImplication<I: Interner> {
2285    /// The consequence of the clause, which holds if the conditions holds.
2286    pub consequence: DomainGoal<I>,
2287
2288    /// The condition goals that should hold.
2289    pub conditions: Goals<I>,
2290
2291    /// The lifetime constraints that should be proven.
2292    pub constraints: Constraints<I>,
2293
2294    /// The relative priority of the implication.
2295    pub priority: ClausePriority,
2296}
2297
2298/// Specifies how important an implication is.
2299#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
2300pub enum ClausePriority {
2301    /// High priority, the solver should prioritize this.
2302    High,
2303
2304    /// Low priority, this implication has lower chance to be relevant to the goal.
2305    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/// Contains the data for a program clause.
2319#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, HasInterner, Zip)]
2320pub struct ProgramClauseData<I: Interner>(pub Binders<ProgramClauseImplication<I>>);
2321
2322impl<I: Interner> ProgramClauseImplication<I> {
2323    /// Change the implication into an application holding a `FromEnv` goal.
2324    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    /// Change the program clause data into a `FromEnv` program clause.
2340    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    /// Intern the program clause data.
2345    pub fn intern(self, interner: I) -> ProgramClause<I> {
2346        ProgramClause {
2347            interned: interner.intern_program_clause(self),
2348        }
2349    }
2350}
2351
2352/// A program clause is a logic expression used to describe a part of the program.
2353#[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    /// Create a new program clause using `ProgramClauseData`.
2360    pub fn new(interner: I, clause: ProgramClauseData<I>) -> Self {
2361        let interned = interner.intern_program_clause(clause);
2362        Self { interned }
2363    }
2364
2365    /// Change the clause into a `FromEnv` clause.
2366    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    /// Get the interned program clause.
2373    pub fn interned(&self) -> &I::InternedProgramClause {
2374        &self.interned
2375    }
2376
2377    /// Get the program clause data.
2378    pub fn data(&self, interner: I) -> &ProgramClauseData<I> {
2379        interner.program_clause_data(&self.interned)
2380    }
2381}
2382
2383/// Wraps a "canonicalized item". Items are canonicalized as follows:
2384///
2385/// All unresolved existential variables are "renumbered" according to their
2386/// first appearance; the kind/universe of the variable is recorded in the
2387/// `binders` field.
2388#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2389pub struct Canonical<T: HasInterner> {
2390    /// The item that is canonicalized.
2391    pub value: T,
2392
2393    /// The kind/universe of the variable.
2394    pub binders: CanonicalVarKinds<T::Interner>,
2395}
2396
2397impl<T: HasInterner> HasInterner for Canonical<T> {
2398    type Interner = T::Interner;
2399}
2400
2401/// A "universe canonical" value. This is a wrapper around a
2402/// `Canonical`, indicating that the universes within have been
2403/// "renumbered" to start from 0 and collapse unimportant
2404/// distinctions.
2405///
2406/// To produce one of these values, use the `u_canonicalize` method.
2407#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2408pub struct UCanonical<T: HasInterner> {
2409    /// The wrapped `Canonical`.
2410    pub canonical: Canonical<T>,
2411
2412    /// The number of universes that have been collapsed.
2413    pub universes: usize,
2414}
2415
2416impl<T: HasInterner> UCanonical<T> {
2417    /// Checks whether the universe canonical value is a trivial
2418    /// substitution (e.g. an identity substitution).
2419    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    /// Creates an identity substitution.
2433    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)]
2467/// A general goal; this is the full range of questions you can pose to Chalk.
2468pub struct Goal<I: Interner> {
2469    interned: I::InternedGoal,
2470}
2471
2472impl<I: Interner> Goal<I> {
2473    /// Create a new goal using `GoalData`.
2474    pub fn new(interner: I, interned: GoalData<I>) -> Self {
2475        let interned = I::intern_goal(interner, interned);
2476        Self { interned }
2477    }
2478
2479    /// Gets the interned goal.
2480    pub fn interned(&self) -> &I::InternedGoal {
2481        &self.interned
2482    }
2483
2484    /// Gets the interned goal data.
2485    pub fn data(&self, interner: I) -> &GoalData<I> {
2486        interner.goal_data(&self.interned)
2487    }
2488
2489    /// Create a goal using a `forall` or `exists` quantifier.
2490    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    /// Takes a goal `G` and turns it into `not { G }`.
2495    pub fn negate(self, interner: I) -> Self {
2496        GoalData::Not(self).intern(interner)
2497    }
2498
2499    /// Takes a goal `G` and turns it into `compatible { G }`.
2500    pub fn compatible(self, interner: I) -> Self {
2501        // compatible { G } desugars into: forall<T> { if (Compatible, DownstreamType(T)) { G } }
2502        // This activates the compatible modality rules and introduces an anonymous downstream type
2503        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    /// Create an implication goal that holds if the predicates are true.
2520    pub fn implied_by(self, interner: I, predicates: ProgramClauses<I>) -> Goal<I> {
2521        GoalData::Implies(predicates, self).intern(interner)
2522    }
2523
2524    /// True if this goal is "trivially true" -- i.e., no work is
2525    /// required to prove it.
2526    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    /// Creates a single goal that only holds if a list of goals holds.
2539    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                // More than one goal to prove
2547                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                // One goal to prove
2554                goal0
2555            }
2556        } else {
2557            // No goals to prove, always true
2558            GoalData::All(Goals::empty(interner)).intern(interner)
2559        }
2560    }
2561}
2562
2563#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
2564/// A general goal; this is the full range of questions you can pose to Chalk.
2565pub enum GoalData<I: Interner> {
2566    /// Introduces a binding at depth 0, shifting other bindings up
2567    /// (deBruijn index).
2568    Quantified(QuantifierKind, Binders<Goal<I>>),
2569
2570    /// A goal that holds given some clauses (like an if-statement).
2571    Implies(ProgramClauses<I>, Goal<I>),
2572
2573    /// List of goals that all should hold.
2574    All(Goals<I>),
2575
2576    /// Negation: the inner goal should not hold.
2577    Not(Goal<I>),
2578
2579    /// Make two things equal; the rules for doing so are well known to the logic
2580    EqGoal(EqGoal<I>),
2581
2582    /// Make one thing a subtype of another; the rules for doing so are well known to the logic
2583    SubtypeGoal(SubtypeGoal<I>),
2584
2585    /// A "domain goal" indicates some base sort of goal that can be
2586    /// proven via program clauses
2587    DomainGoal(DomainGoal<I>),
2588
2589    /// Indicates something that cannot be proven to be true or false
2590    /// definitively. This can occur with overflow but also with
2591    /// unifications of skolemized variables like `forall<X,Y> { X = Y
2592    /// }`. Of course, that statement is false, as there exist types
2593    /// X, Y where `X = Y` is not true. But we treat it as "cannot
2594    /// prove" so that `forall<X,Y> { not { X = Y } }` also winds up
2595    /// as cannot prove.
2596    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    /// Create an interned goal.
2614    pub fn intern(self, interner: I) -> Goal<I> {
2615        Goal::new(interner, self)
2616    }
2617}
2618
2619/// Kinds of quantifiers in the logic, such as `forall` and `exists`.
2620#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
2621pub enum QuantifierKind {
2622    /// Universal quantifier `ForAll`.
2623    ///
2624    /// A formula with the universal quantifier `forall(x). P(x)` is satisfiable
2625    /// if and only if the subformula `P(x)` is true for all possible values for x.
2626    ForAll,
2627
2628    /// Existential quantifier `Exists`.
2629    ///
2630    /// A formula with the existential quantifier `exists(x). P(x)` is satisfiable
2631    /// if and only if there exists at least one value for all possible values of x
2632    /// which satisfies the subformula `P(x)`.
2633
2634    /// In the context of chalk, the existential quantifier usually demands the
2635    /// existence of exactly one instance (i.e. type) that satisfies the formula
2636    /// (i.e. type constraints). More than one instance means that the result is ambiguous.
2637    Exists,
2638}
2639
2640/// A constraint on lifetimes.
2641///
2642/// When we search for solutions within the trait system, we essentially ignore
2643/// lifetime constraints, instead gathering them up to return with our solution
2644/// for later checking. This allows for decoupling between type and region
2645/// checking in the compiler.
2646#[derive(Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner, Zip)]
2647pub enum Constraint<I: Interner> {
2648    /// Outlives constraint `'a: 'b`, indicating that the value of `'a` must be
2649    /// a superset of the value of `'b`.
2650    LifetimeOutlives(Lifetime<I>, Lifetime<I>),
2651
2652    /// Type outlives constraint `T: 'a`, indicating that the type `T` must live
2653    /// at least as long as the value of `'a`.
2654    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    /// A substitution is an **identity substitution** if it looks
2666    /// like this
2667    ///
2668    /// ```text
2669    /// ?0 := ?0
2670    /// ?1 := ?1
2671    /// ?2 := ?2
2672    /// ...
2673    /// ```
2674    ///
2675    /// Basically, each value is mapped to a type or lifetime with its
2676    /// same index.
2677    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    /// Apply the substitution to a value.
2698    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    /// Gets an iterator of all type parameters.
2706    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    /// Compute type flags for Substitution<I>
2713    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    /// Index into the list of parameters.
2730    pub fn at(&self, index: usize) -> &GenericArg<I> {
2731        let interner = self.interner;
2732        &self.subst.as_parameters(interner)[index]
2733    }
2734}
2735
2736/// Convert a value to a list of parameters.
2737pub trait AsParameters<I: Interner> {
2738    /// Convert the current value to parameters.
2739    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
2776/// An extension trait to anything that can be represented as list of `GenericArg`s that signifies
2777/// that it can applied as a substituion to a value
2778pub trait Substitute<I: Interner>: AsParameters<I> {
2779    /// Apply the substitution to a value.
2780    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
2800/// Utility for converting a list of all the binders into scope
2801/// into references to those binders. Simply pair the binders with
2802/// the indices, and invoke `to_generic_arg()` on the `(binder,
2803/// index)` pair. The result will be a reference to a bound
2804/// variable of appropriate kind at the corresponding index.
2805pub trait ToGenericArg<I: Interner> {
2806    /// Converts the binders in scope to references to those binders.
2807    fn to_generic_arg(&self, interner: I) -> GenericArg<I> {
2808        self.to_generic_arg_at_depth(interner, DebruijnIndex::INNERMOST)
2809    }
2810
2811    /// Converts the binders at the specified depth to references to those binders.
2812    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        /// List of interned elements.
2869        #[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            /// Get the interned elements.
2876            pub fn interned(&self) -> &I::$interned {
2877                &self.interned
2878            }
2879
2880            /// Returns a slice containing the elements.
2881            pub fn as_slice(&self, interner: I) -> &[$elem] {
2882                Interner::$data(interner, &self.interned)
2883            }
2884
2885            /// Index into the sequence.
2886            pub fn at(&self, interner: I, index: usize) -> &$elem {
2887                &self.as_slice(interner)[index]
2888            }
2889
2890            /// Create an empty sequence.
2891            pub fn empty(interner: I) -> Self {
2892                Self::from_iter(interner, None::<$elem>)
2893            }
2894
2895            /// Check whether this is an empty sequence.
2896            pub fn is_empty(&self, interner: I) -> bool {
2897                self.as_slice(interner).is_empty()
2898            }
2899
2900            /// Get an iterator over the elements of the sequence.
2901            pub fn iter(&self, interner: I) -> std::slice::Iter<'_, $elem> {
2902                self.as_slice(interner).iter()
2903            }
2904
2905            /// Get the length of the sequence.
2906            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            /// Tries to create a sequence using an iterator of element-like things.
2919            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            /// Create a sequence from elements
2929            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            /// Create a sequence from a single element.
2943            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    /// Tries to create a list of canonical variable kinds using an iterator.
2996    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    /// Creates a list of canonical variable kinds using an iterator.
3006    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    /// Creates a list of canonical variable kinds from a single canonical variable kind.
3017    pub fn from1(interner: I, variance: Variance) -> Self {
3018        Self::from_iter(interner, Some(variance))
3019    }
3020}
3021
3022/// Combines a substitution (`subst`) with a set of region constraints
3023/// (`constraints`). This represents the result of a query; the
3024/// substitution stores the values for the query's unknown variables,
3025/// and the constraints represents any region constraints that must
3026/// additionally be solved.
3027#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
3028pub struct ConstrainedSubst<I: Interner> {
3029    /// The substitution that is being constrained.
3030    ///
3031    /// NB: The `is_trivial` routine relies on the fact that `subst` is folded first.
3032    pub subst: Substitution<I>,
3033
3034    /// Region constraints that constrain the substitution.
3035    pub constraints: Constraints<I>,
3036}
3037
3038/// The resulting substitution after solving a goal.
3039#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
3040pub struct AnswerSubst<I: Interner> {
3041    /// The substitution result.
3042    ///
3043    /// NB: The `is_trivial` routine relies on the fact that `subst` is folded first.
3044    pub subst: Substitution<I>,
3045
3046    /// List of constraints that are part of the answer.
3047    pub constraints: Constraints<I>,
3048
3049    /// Delayed subgoals, used when the solver answered with an (incomplete) `Answer` (instead of a `CompleteAnswer`).
3050    pub delayed_subgoals: Vec<InEnvironment<Goal<I>>>,
3051}
3052
3053/// Logic to decide the Variance for a given subst
3054pub trait UnificationDatabase<I>
3055where
3056    Self: std::fmt::Debug,
3057    I: Interner,
3058{
3059    /// Gets the variances for the substitution of a fn def
3060    fn fn_def_variance(&self, fn_def_id: FnDefId<I>) -> Variances<I>;
3061
3062    /// Gets the variances for the substitution of a adt
3063    fn adt_variance(&self, adt_id: AdtId<I>) -> Variances<I>;
3064}