]> git.proxmox.com Git - rustc.git/blame - vendor/chalk-ir-0.25.0/src/lib.rs
New upstream version 1.48.0+dfsg1
[rustc.git] / vendor / chalk-ir-0.25.0 / src / lib.rs
CommitLineData
1b1a35ee
XL
1//! Defines the IR for types and logical predicates.
2
f035d41b 3#![deny(rust_2018_idioms)]
1b1a35ee 4#![warn(missing_docs)]
f035d41b
XL
5
6// Allows macros to refer to this crate as `::chalk_ir`
7extern crate self as chalk_ir;
8
1b1a35ee 9use crate::cast::{Cast, CastTo, Caster};
f035d41b
XL
10use crate::fold::shift::Shift;
11use crate::fold::{Fold, Folder, Subst, SuperFold};
12use crate::visit::{SuperVisit, Visit, VisitExt, VisitResult, Visitor};
13use chalk_derive::{Fold, HasInterner, SuperVisit, Visit, Zip};
f035d41b
XL
14use std::marker::PhantomData;
15
16pub use crate::debug::SeparatorTraitRef;
17
1b1a35ee 18/// Uninhabited (empty) type, used in combination with `PhantomData`.
f035d41b
XL
19#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
20pub enum Void {}
21
22/// Many of our internal operations (e.g., unification) are an attempt
23/// to perform some operation which may not complete.
24pub type Fallible<T> = Result<T, NoSolution>;
25
26/// Indicates that the attempted operation has "no solution" -- i.e.,
27/// cannot be performed.
28#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
29pub struct NoSolution;
30
31/// Error type for the `UnificationOps::program_clauses` method --
32/// indicates that the complete set of program clauses for this goal
33/// cannot be enumerated.
34pub struct Floundered;
35
36macro_rules! impl_debugs {
37 ($($id:ident), *) => {
38 $(
39 impl<I: Interner> std::fmt::Debug for $id<I> {
40 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
41 write!(fmt, "{}({:?})", stringify!($id), self.0)
42 }
43 }
44 )*
45 };
46}
47
48#[macro_use]
49pub mod zip;
50
51#[macro_use]
52pub mod fold;
53
54#[macro_use]
55pub mod visit;
56
57pub mod cast;
58
59pub mod interner;
60use interner::{HasInterner, Interner};
61
62pub mod could_match;
63pub mod debug;
64
65#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner)]
66/// The set of assumptions we've made so far, and the current number of
67/// universal (forall) quantifiers we're within.
68pub struct Environment<I: Interner> {
1b1a35ee 69 /// The clauses in the environment.
f035d41b
XL
70 pub clauses: ProgramClauses<I>,
71}
72
1b1a35ee
XL
73impl<I: Interner> Copy for Environment<I> where I::InternedProgramClauses: Copy {}
74
f035d41b 75impl<I: Interner> Environment<I> {
1b1a35ee 76 /// Creates a new environment.
f035d41b
XL
77 pub fn new(interner: &I) -> Self {
78 Environment {
1b1a35ee 79 clauses: ProgramClauses::empty(interner),
f035d41b
XL
80 }
81 }
82
1b1a35ee 83 /// Adds (an iterator of) clauses to the environment.
f035d41b
XL
84 pub fn add_clauses<II>(&self, interner: &I, clauses: II) -> Self
85 where
86 II: IntoIterator<Item = ProgramClause<I>>,
87 {
88 let mut env = self.clone();
89 env.clauses =
1b1a35ee 90 ProgramClauses::from_iter(interner, env.clauses.iter(interner).cloned().chain(clauses));
f035d41b
XL
91 env
92 }
1b1a35ee
XL
93
94 /// True if any of the clauses in the environment have a consequence of `Compatible`.
95 /// Panics if the conditions or constraints of that clause are not empty.
96 pub fn has_compatible_clause(&self, interner: &I) -> bool {
97 self.clauses.as_slice(interner).iter().any(|c| {
98 let ProgramClauseData(implication) = c.data(interner);
99 match implication.skip_binders().consequence {
100 DomainGoal::Compatible => {
101 // We currently don't generate `Compatible` with any conditions or constraints
102 // If this was needed, for whatever reason, then a third "yes, but must evaluate"
103 // return value would have to be added.
104 assert!(implication.skip_binders().conditions.is_empty(interner));
105 assert!(implication.skip_binders().constraints.is_empty(interner));
106 true
107 }
108 _ => false,
109 }
110 })
111 }
f035d41b
XL
112}
113
1b1a35ee 114/// A goal with an environment to solve it in.
f035d41b 115#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit)]
1b1a35ee 116#[allow(missing_docs)]
f035d41b
XL
117pub struct InEnvironment<G: HasInterner> {
118 pub environment: Environment<G::Interner>,
119 pub goal: G,
120}
121
1b1a35ee
XL
122impl<G: HasInterner<Interner = I> + Copy, I: Interner> Copy for InEnvironment<G> where
123 I::InternedProgramClauses: Copy
124{
125}
126
f035d41b 127impl<G: HasInterner> InEnvironment<G> {
1b1a35ee 128 /// Creates a new environment/goal pair.
f035d41b
XL
129 pub fn new(environment: &Environment<G::Interner>, goal: G) -> Self {
130 InEnvironment {
131 environment: environment.clone(),
132 goal,
133 }
134 }
135
1b1a35ee 136 /// Maps the goal without touching the environment.
f035d41b
XL
137 pub fn map<OP, H>(self, op: OP) -> InEnvironment<H>
138 where
139 OP: FnOnce(G) -> H,
140 H: HasInterner<Interner = G::Interner>,
141 {
142 InEnvironment {
143 environment: self.environment,
144 goal: op(self.goal),
145 }
146 }
147}
148
149impl<G: HasInterner> HasInterner for InEnvironment<G> {
150 type Interner = G::Interner;
151}
152
1b1a35ee 153/// Different signed int types.
f035d41b 154#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1b1a35ee 155#[allow(missing_docs)]
f035d41b
XL
156pub enum IntTy {
157 Isize,
158 I8,
159 I16,
160 I32,
161 I64,
162 I128,
163}
164
1b1a35ee 165/// Different unsigned int types.
f035d41b 166#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1b1a35ee 167#[allow(missing_docs)]
f035d41b
XL
168pub enum UintTy {
169 Usize,
170 U8,
171 U16,
172 U32,
173 U64,
174 U128,
175}
176
1b1a35ee 177/// Different kinds of float types.
f035d41b 178#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1b1a35ee 179#[allow(missing_docs)]
f035d41b
XL
180pub enum FloatTy {
181 F32,
182 F64,
183}
184
1b1a35ee 185/// Types of scalar values.
f035d41b 186#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
1b1a35ee 187#[allow(missing_docs)]
f035d41b
XL
188pub enum Scalar {
189 Bool,
190 Char,
191 Int(IntTy),
192 Uint(UintTy),
193 Float(FloatTy),
194}
195
1b1a35ee
XL
196/// Whether a function is safe or not.
197#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
198pub enum Safety {
199 /// Safe
200 Safe,
201 /// Unsafe
202 Unsafe,
203}
204
205/// Whether a type is mutable or not.
f035d41b
XL
206#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
207pub enum Mutability {
1b1a35ee 208 /// Mutable
f035d41b 209 Mut,
1b1a35ee 210 /// Immutable
f035d41b
XL
211 Not,
212}
213
1b1a35ee 214/// Different kinds of Rust types.
f035d41b
XL
215#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Fold, Visit)]
216pub enum TypeName<I: Interner> {
217 /// Abstract data types, i.e., structs, unions, or enumerations.
218 /// For example, a type like `Vec<T>`.
219 Adt(AdtId<I>),
220
221 /// an associated type like `Iterator::Item`; see `AssociatedType` for details
222 AssociatedType(AssocTypeId<I>),
223
224 /// a scalar type like `bool` or `u32`
225 Scalar(Scalar),
226
227 /// a tuple of the given arity
228 Tuple(usize),
229
230 /// an array type like `[T; N]`
231 Array,
232
233 /// a slice type like `[T]`
234 Slice,
235
236 /// a raw pointer type like `*const T` or `*mut T`
237 Raw(Mutability),
238
239 /// a reference type like `&T` or `&mut T`
240 Ref(Mutability),
241
242 /// a placeholder for opaque types like `impl Trait`
243 OpaqueType(OpaqueTyId<I>),
244
245 /// a function definition
246 FnDef(FnDefId<I>),
247
248 /// the string primitive type
249 Str,
250
251 /// the never type `!`
252 Never,
253
254 /// A closure.
255 Closure(ClosureId<I>),
256
257 /// This can be used to represent an error, e.g. during name resolution of a type.
258 /// Chalk itself will not produce this, just pass it through when given.
259 Error,
260}
261
262impl<I: Interner> HasInterner for TypeName<I> {
263 type Interner = I;
264}
265
266/// An universe index is how a universally quantified parameter is
267/// represented when it's binder is moved into the environment.
268/// An example chain of transformations would be:
269/// `forall<T> { Goal(T) }` (syntactical representation)
270/// `forall { Goal(?0) }` (used a DeBruijn index)
271/// `Goal(!U1)` (the quantifier was moved to the environment and replaced with a universe index)
272/// See https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference.html#placeholders-and-universes for more.
273#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
274pub struct UniverseIndex {
1b1a35ee 275 /// The counter for the universe index, starts with 0.
f035d41b
XL
276 pub counter: usize,
277}
278
279impl UniverseIndex {
1b1a35ee 280 /// Root universe index (0).
f035d41b
XL
281 pub const ROOT: UniverseIndex = UniverseIndex { counter: 0 };
282
1b1a35ee 283 /// Root universe index (0).
f035d41b
XL
284 pub fn root() -> UniverseIndex {
285 Self::ROOT
286 }
287
1b1a35ee 288 /// Whether one universe can "see" another.
f035d41b
XL
289 pub fn can_see(self, ui: UniverseIndex) -> bool {
290 self.counter >= ui.counter
291 }
292
1b1a35ee 293 /// Increases the index counter.
f035d41b
XL
294 pub fn next(self) -> UniverseIndex {
295 UniverseIndex {
296 counter: self.counter + 1,
297 }
298 }
299}
300
301/// Maps the universes found in the `u_canonicalize` result (the
302/// "canonical" universes) to the universes found in the original
303/// value (and vice versa). When used as a folder -- i.e., from
304/// outside this module -- converts from "canonical" universes to the
305/// original (but see the `UMapToCanonical` folder).
306#[derive(Clone, Debug)]
307pub struct UniverseMap {
308 /// A reverse map -- for each universe Ux that appears in
309 /// `quantified`, the corresponding universe in the original was
310 /// `universes[x]`.
311 pub universes: Vec<UniverseIndex>,
312}
313
314impl UniverseMap {
1b1a35ee 315 /// Creates a new universe map.
f035d41b
XL
316 pub fn new() -> Self {
317 UniverseMap {
318 universes: vec![UniverseIndex::root()],
319 }
320 }
321
322 /// Number of canonical universes.
323 pub fn num_canonical_universes(&self) -> usize {
324 self.universes.len()
325 }
326}
1b1a35ee
XL
327
328/// The id for an Abstract Data Type (i.e. structs, unions and enums).
f035d41b
XL
329#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
330pub struct AdtId<I: Interner>(pub I::InternedAdtId);
331
332/// The id of a trait definition; could be used to load the trait datum by
333/// invoking the [`trait_datum`] method.
334///
335/// [`trait_datum`]: ../chalk_solve/trait.RustIrDatabase.html#tymethod.trait_datum
336#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
337pub struct TraitId<I: Interner>(pub I::DefId);
338
1b1a35ee 339/// The id for an impl.
f035d41b
XL
340#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
341pub struct ImplId<I: Interner>(pub I::DefId);
342
1b1a35ee 343/// Id for a specific clause.
f035d41b
XL
344#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
345pub struct ClauseId<I: Interner>(pub I::DefId);
346
347/// The id for the associated type member of a trait. The details of the type
348/// can be found by invoking the [`associated_ty_data`] method.
349///
350/// [`associated_ty_data`]: ../chalk_solve/trait.RustIrDatabase.html#tymethod.associated_ty_data
351#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
352pub struct AssocTypeId<I: Interner>(pub I::DefId);
353
1b1a35ee 354/// Id for an opaque type.
f035d41b
XL
355#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
356pub struct OpaqueTyId<I: Interner>(pub I::DefId);
357
1b1a35ee 358/// Function definition id.
f035d41b
XL
359#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
360pub struct FnDefId<I: Interner>(pub I::DefId);
361
1b1a35ee 362/// Id for Rust closures.
f035d41b
XL
363#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
364pub struct ClosureId<I: Interner>(pub I::DefId);
365
366impl_debugs!(ImplId, ClauseId);
367
1b1a35ee 368/// A Rust type. The actual type data is stored in `TyData`.
f035d41b
XL
369#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
370pub struct Ty<I: Interner> {
371 interned: I::InternedType,
372}
373
374impl<I: Interner> Ty<I> {
1b1a35ee 375 /// Creates a type from `TyData`.
f035d41b
XL
376 pub fn new(interner: &I, data: impl CastTo<TyData<I>>) -> Self {
377 Ty {
378 interned: I::intern_ty(interner, data.cast(interner)),
379 }
380 }
381
1b1a35ee 382 /// Gets the interned type.
f035d41b
XL
383 pub fn interned(&self) -> &I::InternedType {
384 &self.interned
385 }
386
1b1a35ee 387 /// Gets the underlying type data.
f035d41b
XL
388 pub fn data(&self, interner: &I) -> &TyData<I> {
389 I::ty_data(interner, &self.interned)
390 }
391
1b1a35ee 392 /// Creates a `FromEnv` constraint using this type.
f035d41b
XL
393 pub fn from_env(&self) -> FromEnv<I> {
394 FromEnv::Ty(self.clone())
395 }
396
1b1a35ee 397 /// Creates a WF-constraint for this type.
f035d41b
XL
398 pub fn well_formed(&self) -> WellFormed<I> {
399 WellFormed::Ty(self.clone())
400 }
401
402 /// Creates a domain goal `FromEnv(T)` where `T` is this type.
403 pub fn into_from_env_goal(self, interner: &I) -> DomainGoal<I> {
404 self.from_env().cast(interner)
405 }
406
407 /// If this is a `TyData::BoundVar(d)`, returns `Some(d)` else `None`.
408 pub fn bound_var(&self, interner: &I) -> Option<BoundVar> {
409 if let TyData::BoundVar(bv) = self.data(interner) {
410 Some(*bv)
411 } else {
412 None
413 }
414 }
415
416 /// If this is a `TyData::InferenceVar(d)`, returns `Some(d)` else `None`.
417 pub fn inference_var(&self, interner: &I) -> Option<InferenceVar> {
418 if let TyData::InferenceVar(depth, _) = self.data(interner) {
419 Some(*depth)
420 } else {
421 None
422 }
423 }
424
1b1a35ee
XL
425 /// Returns true if this is a `BoundVar` or an `InferenceVar` of `TyKind::General`.
426 pub fn is_general_var(&self, interner: &I, binders: &CanonicalVarKinds<I>) -> bool {
f035d41b 427 match self.data(interner) {
1b1a35ee
XL
428 TyData::BoundVar(bv)
429 if bv.debruijn == DebruijnIndex::INNERMOST
430 && binders.at(interner, bv.index).kind == VariableKind::Ty(TyKind::General) =>
431 {
432 true
433 }
434 TyData::InferenceVar(_, TyKind::General) => true,
f035d41b
XL
435 _ => false,
436 }
437 }
438
1b1a35ee 439 /// Returns true if this is an `Alias`.
f035d41b
XL
440 pub fn is_alias(&self, interner: &I) -> bool {
441 match self.data(interner) {
442 TyData::Alias(..) => true,
443 _ => false,
444 }
445 }
446
1b1a35ee 447 /// Returns true if this is an `IntTy` or `UintTy`.
f035d41b
XL
448 pub fn is_integer(&self, interner: &I) -> bool {
449 match self.data(interner) {
450 TyData::Apply(ApplicationTy {
451 name: TypeName::Scalar(Scalar::Int(_)),
452 ..
453 })
454 | TyData::Apply(ApplicationTy {
455 name: TypeName::Scalar(Scalar::Uint(_)),
456 ..
457 }) => true,
458 _ => false,
459 }
460 }
461
1b1a35ee 462 /// Returns true if this is a `FloatTy`.
f035d41b
XL
463 pub fn is_float(&self, interner: &I) -> bool {
464 match self.data(interner) {
465 TyData::Apply(ApplicationTy {
466 name: TypeName::Scalar(Scalar::Float(_)),
467 ..
468 }) => true,
469 _ => false,
470 }
471 }
472
473 /// True if this type contains "bound" types/lifetimes, and hence
474 /// needs to be shifted across binders. This is a very inefficient
475 /// check, intended only for debug assertions, because I am lazy.
476 pub fn needs_shift(&self, interner: &I) -> bool {
477 self.has_free_vars(interner)
478 }
479}
480
1b1a35ee 481/// Type data, which holds the actual type information.
f035d41b
XL
482#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
483pub enum TyData<I: Interner> {
484 /// An "application" type is one that applies the set of type
485 /// arguments to some base type. For example, `Vec<u32>` would be
486 /// "applying" the parameters `[u32]` to the code type `Vec`.
487 /// This type is also used for base types like `u32` (which just apply
488 /// an empty list).
489 Apply(ApplicationTy<I>),
490
1b1a35ee 491 /// instantiated from a universally quantified type, e.g., from
f035d41b
XL
492 /// `forall<T> { .. }`. Stands in as a representative of "some
493 /// unknown type".
494 Placeholder(PlaceholderIndex),
495
496 /// A "dyn" type is a trait object type created via the "dyn Trait" syntax.
497 /// In the chalk parser, the traits that the object represents is parsed as
498 /// a QuantifiedInlineBound, and is then changed to a list of where clauses
499 /// during lowering.
500 ///
501 /// See the `Opaque` variant for a discussion about the use of
502 /// binders here.
503 Dyn(DynTy<I>),
504
505 /// An "alias" type represents some form of type alias, such as:
506 /// - An associated type projection like `<T as Iterator>::Item`
507 /// - `impl Trait` types
508 /// - Named type aliases like `type Foo<X> = Vec<X>`
509 Alias(AliasTy<I>),
510
511 /// A function type such as `for<'a> fn(&'a u32)`.
512 /// Note that "higher-ranked" types (starting with `for<>`) are either
513 /// function types or dyn types, and do not appear otherwise in Rust
514 /// surface syntax.
1b1a35ee 515 Function(FnPointer<I>),
f035d41b
XL
516
517 /// References the binding at the given depth. The index is a [de
518 /// Bruijn index], so it counts back through the in-scope binders.
519 BoundVar(BoundVar),
520
521 /// Inference variable defined in the current inference context.
522 InferenceVar(InferenceVar, TyKind),
523}
524
1b1a35ee
XL
525impl<I: Interner> Copy for TyData<I>
526where
527 I::InternedLifetime: Copy,
528 I::InternedSubstitution: Copy,
529 I::InternedVariableKinds: Copy,
530 I::InternedQuantifiedWhereClauses: Copy,
531{
532}
533
f035d41b 534impl<I: Interner> TyData<I> {
1b1a35ee 535 /// Casts the type data to a type.
f035d41b
XL
536 pub fn intern(self, interner: &I) -> Ty<I> {
537 Ty::new(interner, self)
538 }
539}
540
541/// Identifies a particular bound variable within a binder.
542/// Variables are identified by the combination of a [`DebruijnIndex`],
543/// which identifies the *binder*, and an index within that binder.
544///
545/// Consider this case:
546///
547/// ```ignore
548/// forall<'a, 'b> { forall<'c, 'd> { ... } }
549/// ```
550///
551/// Within the `...` term:
552///
553/// * the variable `'a` have a debruijn index of 1 and index 0
554/// * the variable `'b` have a debruijn index of 1 and index 1
555/// * the variable `'c` have a debruijn index of 0 and index 0
556/// * the variable `'d` have a debruijn index of 0 and index 1
557///
558/// The variables `'a` and `'b` both have debruijn index of 1 because,
559/// counting out, they are the 2nd binder enclosing `...`. The indices
560/// identify the location *within* that binder.
561///
562/// The variables `'c` and `'d` both have debruijn index of 0 because
563/// they appear in the *innermost* binder enclosing the `...`. The
564/// indices identify the location *within* that binder.
565#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
566pub struct BoundVar {
1b1a35ee 567 /// Debruijn index, which identifies the binder.
f035d41b 568 pub debruijn: DebruijnIndex,
1b1a35ee 569 /// Index within the binder.
f035d41b
XL
570 pub index: usize,
571}
572
573impl BoundVar {
1b1a35ee 574 /// Creates a new bound variable.
f035d41b
XL
575 pub fn new(debruijn: DebruijnIndex, index: usize) -> Self {
576 Self { debruijn, index }
577 }
578
1b1a35ee 579 /// Casts the bound variable to a type.
f035d41b
XL
580 pub fn to_ty<I: Interner>(self, interner: &I) -> Ty<I> {
581 TyData::<I>::BoundVar(self).intern(interner)
582 }
583
1b1a35ee 584 /// Wrap the bound variable in a lifetime.
f035d41b
XL
585 pub fn to_lifetime<I: Interner>(self, interner: &I) -> Lifetime<I> {
586 LifetimeData::<I>::BoundVar(self).intern(interner)
587 }
588
1b1a35ee 589 /// Wraps the bound variable in a constant.
f035d41b
XL
590 pub fn to_const<I: Interner>(self, interner: &I, ty: Ty<I>) -> Const<I> {
591 ConstData {
592 ty,
593 value: ConstValue::<I>::BoundVar(self),
594 }
595 .intern(interner)
596 }
597
598 /// True if this variable is bound within the `amount` innermost binders.
599 pub fn bound_within(self, outer_binder: DebruijnIndex) -> bool {
600 self.debruijn.within(outer_binder)
601 }
602
603 /// Adjusts the debruijn index (see [`DebruijnIndex::shifted_in`]).
604 #[must_use]
605 pub fn shifted_in(self) -> Self {
606 BoundVar::new(self.debruijn.shifted_in(), self.index)
607 }
608
609 /// Adjusts the debruijn index (see [`DebruijnIndex::shifted_in`]).
610 #[must_use]
611 pub fn shifted_in_from(self, outer_binder: DebruijnIndex) -> Self {
612 BoundVar::new(self.debruijn.shifted_in_from(outer_binder), self.index)
613 }
614
615 /// Adjusts the debruijn index (see [`DebruijnIndex::shifted_in`]).
616 #[must_use]
617 pub fn shifted_out(self) -> Option<Self> {
618 self.debruijn
619 .shifted_out()
620 .map(|db| BoundVar::new(db, self.index))
621 }
622
623 /// Adjusts the debruijn index (see [`DebruijnIndex::shifted_in`]).
624 #[must_use]
625 pub fn shifted_out_to(self, outer_binder: DebruijnIndex) -> Option<Self> {
626 self.debruijn
627 .shifted_out_to(outer_binder)
628 .map(|db| BoundVar::new(db, self.index))
629 }
630
631 /// Return the index of the bound variable, but only if it is bound
632 /// at the innermost binder. Otherwise, returns `None`.
633 pub fn index_if_innermost(self) -> Option<usize> {
634 self.index_if_bound_at(DebruijnIndex::INNERMOST)
635 }
636
637 /// Return the index of the bound variable, but only if it is bound
638 /// at the innermost binder. Otherwise, returns `None`.
639 pub fn index_if_bound_at(self, debruijn: DebruijnIndex) -> Option<usize> {
640 if self.debruijn == debruijn {
641 Some(self.index)
642 } else {
643 None
644 }
645 }
646}
647
648/// References the binder at the given depth. The index is a [de
649/// Bruijn index], so it counts back through the in-scope binders,
650/// with 0 being the innermost binder. This is used in impls and
651/// the like. For example, if we had a rule like `for<T> { (T:
652/// Clone) :- (T: Copy) }`, then `T` would be represented as a
653/// `BoundVar(0)` (as the `for` is the innermost binder).
654///
655/// [de Bruijn index]: https://en.wikipedia.org/wiki/De_Bruijn_index
656#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
657pub struct DebruijnIndex {
658 depth: u32,
659}
660
661impl DebruijnIndex {
1b1a35ee 662 /// Innermost index.
f035d41b 663 pub const INNERMOST: DebruijnIndex = DebruijnIndex { depth: 0 };
1b1a35ee 664 /// One level higher than the innermost index.
f035d41b
XL
665 pub const ONE: DebruijnIndex = DebruijnIndex { depth: 1 };
666
1b1a35ee 667 /// Creates a new de Bruijn index with a given depth.
f035d41b
XL
668 pub fn new(depth: u32) -> Self {
669 DebruijnIndex { depth }
670 }
671
1b1a35ee
XL
672 /// Depth of the De Bruijn index, counting from 0 starting with
673 /// the innermost binder.
f035d41b
XL
674 pub fn depth(self) -> u32 {
675 self.depth
676 }
677
678 /// True if the binder identified by this index is within the
679 /// binder identified by the index `outer_binder`.
680 ///
681 /// # Example
682 ///
683 /// Imagine you have the following binders in scope
684 ///
685 /// ```ignore
686 /// forall<a> forall<b> forall<c>
687 /// ```
688 ///
689 /// then the Debruijn index for `c` would be `0`, the index for
690 /// `b` would be 1, and so on. Now consider the following calls:
691 ///
692 /// * `c.within(a) = true`
693 /// * `b.within(a) = true`
694 /// * `a.within(a) = false`
695 /// * `a.within(c) = false`
696 pub fn within(self, outer_binder: DebruijnIndex) -> bool {
697 self < outer_binder
698 }
699
700 /// Returns the resulting index when this value is moved into
701 /// through one binder.
702 #[must_use]
703 pub fn shifted_in(self) -> DebruijnIndex {
704 self.shifted_in_from(DebruijnIndex::ONE)
705 }
706
707 /// Update this index in place by shifting it "in" through
708 /// `amount` number of binders.
709 pub fn shift_in(&mut self) {
710 *self = self.shifted_in();
711 }
712
713 /// Adds `outer_binder` levels to the `self` index. Intuitively, this
714 /// shifts the `self` index, which was valid at the outer binder,
715 /// so that it is valid at the innermost binder.
716 ///
717 /// Example: Assume that the following binders are in scope:
718 ///
719 /// ```ignore
720 /// for<A> for<B> for<C> for<D>
721 /// ^ outer binder
722 /// ```
723 ///
724 /// Assume further that the `outer_binder` argument is 2,
725 /// which means that it is referring to the `for<B>` binder
726 /// (since `D` would be the innermost binder).
727 ///
728 /// This means that `self` is relative to the binder `B` -- so
729 /// if `self` is 0 (`INNERMOST`), then it refers to `B`,
730 /// and if `self` is 1, then it refers to `A`.
731 ///
732 /// We will return as follows:
733 ///
734 /// * `0.shifted_in_from(2) = 2` -- i.e., `B`, when shifted in to the binding level `D`, has index 2
735 /// * `1.shifted_in_from(2) = 3` -- i.e., `A`, when shifted in to the binding level `D`, has index 3
736 /// * `2.shifted_in_from(1) = 3` -- here, we changed the `outer_binder` to refer to `C`.
737 /// Therefore `2` (relative to `C`) refers to `A`, so the result is still 3 (since `A`, relative to the
738 /// innermost binder, has index 3).
739 #[must_use]
740 pub fn shifted_in_from(self, outer_binder: DebruijnIndex) -> DebruijnIndex {
741 DebruijnIndex::new(self.depth() + outer_binder.depth())
742 }
743
744 /// Returns the resulting index when this value is moved out from
745 /// `amount` number of new binders.
746 #[must_use]
747 pub fn shifted_out(self) -> Option<DebruijnIndex> {
748 self.shifted_out_to(DebruijnIndex::ONE)
749 }
750
751 /// Update in place by shifting out from `amount` binders.
752 pub fn shift_out(&mut self) {
753 *self = self.shifted_out().unwrap();
754 }
755
756 /// Subtracts `outer_binder` levels from the `self` index. Intuitively, this
757 /// shifts the `self` index, which was valid at the innermost
758 /// binder, to one that is valid at the binder `outer_binder`.
759 ///
760 /// This will return `None` if the `self` index is internal to the
761 /// outer binder (i.e., if `self < outer_binder`).
762 ///
763 /// Example: Assume that the following binders are in scope:
764 ///
765 /// ```ignore
766 /// for<A> for<B> for<C> for<D>
767 /// ^ outer binder
768 /// ```
769 ///
770 /// Assume further that the `outer_binder` argument is 2,
771 /// which means that it is referring to the `for<B>` binder
772 /// (since `D` would be the innermost binder).
773 ///
774 /// This means that the result is relative to the binder `B` -- so
775 /// if `self` is 0 (`INNERMOST`), then it refers to `B`,
776 /// and if `self` is 1, then it refers to `A`.
777 ///
778 /// We will return as follows:
779 ///
780 /// * `1.shifted_out_to(2) = None` -- i.e., the binder for `C` can't be named from the binding level `B`
781 /// * `3.shifted_out_to(2) = Some(1)` -- i.e., `A`, when shifted out to the binding level `B`, has index 1
782 pub fn shifted_out_to(self, outer_binder: DebruijnIndex) -> Option<DebruijnIndex> {
783 if self.within(outer_binder) {
784 None
785 } else {
786 Some(DebruijnIndex::new(self.depth() - outer_binder.depth()))
787 }
788 }
789}
790
791/// A "DynTy" represents a trait object (`dyn Trait`). Trait objects
792/// are conceptually very related to an "existential type" of the form
1b1a35ee 793/// `exists<T> { T: Trait }` (another example of such type is `impl Trait`).
f035d41b
XL
794/// `DynTy` represents the bounds on that type.
795///
1b1a35ee 796/// The "bounds" here represents the unknown self type. So, a type like
f035d41b
XL
797/// `dyn for<'a> Fn(&'a u32)` would be represented with two-levels of
798/// binder, as "depicted" here:
799///
800/// ```notrust
801/// exists<type> {
802/// vec![
803/// // A QuantifiedWhereClause:
804/// forall<region> { ^1.0: Fn(&^0.0 u32) }
805/// ]
806/// }
807/// ```
808///
809/// The outer `exists<type>` binder indicates that there exists
810/// some type that meets the criteria within, but that type is not
811/// known. It is referenced within the type using `^1.0`, indicating
812/// a bound type with debruijn index 1 (i.e., skipping through one
813/// level of binder).
814#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
815pub struct DynTy<I: Interner> {
1b1a35ee 816 /// The unknown self type.
f035d41b 817 pub bounds: Binders<QuantifiedWhereClauses<I>>,
1b1a35ee 818 /// Lifetime of the `DynTy`.
f035d41b
XL
819 pub lifetime: Lifetime<I>,
820}
821
1b1a35ee
XL
822impl<I: Interner> Copy for DynTy<I>
823where
824 I::InternedLifetime: Copy,
825 I::InternedQuantifiedWhereClauses: Copy,
826 I::InternedVariableKinds: Copy,
827{
828}
829
830/// A type, lifetime or constant whose value is being inferred.
f035d41b
XL
831#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
832pub struct InferenceVar {
833 index: u32,
834}
835
836impl From<u32> for InferenceVar {
837 fn from(index: u32) -> InferenceVar {
838 InferenceVar { index }
839 }
840}
841
842impl InferenceVar {
1b1a35ee 843 /// Gets the underlying index value.
f035d41b
XL
844 pub fn index(self) -> u32 {
845 self.index
846 }
847
1b1a35ee 848 /// Wraps the inference variable in a type.
f035d41b
XL
849 pub fn to_ty<I: Interner>(self, interner: &I, kind: TyKind) -> Ty<I> {
850 TyData::<I>::InferenceVar(self, kind).intern(interner)
851 }
852
1b1a35ee 853 /// Wraps the inference variable in a lifetime.
f035d41b
XL
854 pub fn to_lifetime<I: Interner>(self, interner: &I) -> Lifetime<I> {
855 LifetimeData::<I>::InferenceVar(self).intern(interner)
856 }
857
1b1a35ee 858 /// Wraps the inference variable in a constant.
f035d41b
XL
859 pub fn to_const<I: Interner>(self, interner: &I, ty: Ty<I>) -> Const<I> {
860 ConstData {
861 ty,
862 value: ConstValue::<I>::InferenceVar(self),
863 }
864 .intern(interner)
865 }
866}
867
868/// for<'a...'z> X -- all binders are instantiated at once,
869/// and we use deBruijn indices within `self.ty`
870#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
1b1a35ee
XL
871#[allow(missing_docs)]
872pub struct FnPointer<I: Interner> {
f035d41b 873 pub num_binders: usize,
1b1a35ee
XL
874 pub abi: I::FnAbi,
875 pub safety: Safety,
876 pub variadic: bool,
f035d41b
XL
877 pub substitution: Substitution<I>,
878}
879
1b1a35ee
XL
880impl<I: Interner> Copy for FnPointer<I> where I::InternedSubstitution: Copy {}
881
882/// Constants.
883#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
f035d41b
XL
884pub struct Const<I: Interner> {
885 interned: I::InternedConst,
886}
887
888impl<I: Interner> Const<I> {
1b1a35ee 889 /// Create a `Const` using something that can be cast to const data.
f035d41b
XL
890 pub fn new(interner: &I, data: impl CastTo<ConstData<I>>) -> Self {
891 Const {
892 interned: I::intern_const(interner, data.cast(interner)),
893 }
894 }
895
1b1a35ee 896 /// Gets the interned constant.
f035d41b
XL
897 pub fn interned(&self) -> &I::InternedConst {
898 &self.interned
899 }
900
1b1a35ee 901 /// Gets the constant data from the interner.
f035d41b
XL
902 pub fn data(&self, interner: &I) -> &ConstData<I> {
903 I::const_data(interner, &self.interned)
904 }
905
906 /// If this is a `ConstData::BoundVar(d)`, returns `Some(d)` else `None`.
907 pub fn bound_var(&self, interner: &I) -> Option<BoundVar> {
908 if let ConstValue::BoundVar(bv) = &self.data(interner).value {
909 Some(*bv)
910 } else {
911 None
912 }
913 }
914
915 /// If this is a `ConstData::InferenceVar(d)`, returns `Some(d)` else `None`.
916 pub fn inference_var(&self, interner: &I) -> Option<InferenceVar> {
917 if let ConstValue::InferenceVar(iv) = &self.data(interner).value {
918 Some(*iv)
919 } else {
920 None
921 }
922 }
923
924 /// True if this const is a "bound" const, and hence
925 /// needs to be shifted across binders. Meant for debug assertions.
926 pub fn needs_shift(&self, interner: &I) -> bool {
927 match &self.data(interner).value {
928 ConstValue::BoundVar(_) => true,
929 ConstValue::InferenceVar(_) => false,
930 ConstValue::Placeholder(_) => false,
931 ConstValue::Concrete(_) => false,
932 }
933 }
934}
935
1b1a35ee 936/// Constant data, containing the constant's type and value.
f035d41b
XL
937#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
938pub struct ConstData<I: Interner> {
1b1a35ee 939 /// Type that holds the constant.
f035d41b 940 pub ty: Ty<I>,
1b1a35ee 941 /// The value of the constant.
f035d41b
XL
942 pub value: ConstValue<I>,
943}
944
1b1a35ee 945/// A constant value, not necessarily concrete.
f035d41b
XL
946#[derive(Clone, PartialEq, Eq, Hash, HasInterner)]
947pub enum ConstValue<I: Interner> {
1b1a35ee 948 /// Bound var (e.g. a parameter).
f035d41b 949 BoundVar(BoundVar),
1b1a35ee 950 /// Constant whose value is being inferred.
f035d41b 951 InferenceVar(InferenceVar),
1b1a35ee 952 /// Lifetime on some yet-unknown placeholder.
f035d41b 953 Placeholder(PlaceholderIndex),
1b1a35ee 954 /// Concrete constant value.
f035d41b
XL
955 Concrete(ConcreteConst<I>),
956}
957
1b1a35ee
XL
958impl<I: Interner> Copy for ConstValue<I> where I::InternedConcreteConst: Copy {}
959
f035d41b 960impl<I: Interner> ConstData<I> {
1b1a35ee 961 /// Wraps the constant data in a `Const`.
f035d41b
XL
962 pub fn intern(self, interner: &I) -> Const<I> {
963 Const::new(interner, self)
964 }
965}
966
1b1a35ee
XL
967/// Concrete constant, whose value is known (as opposed to
968/// inferred constants and placeholders).
969#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
f035d41b 970pub struct ConcreteConst<I: Interner> {
1b1a35ee 971 /// The interned constant.
f035d41b
XL
972 pub interned: I::InternedConcreteConst,
973}
974
975impl<I: Interner> ConcreteConst<I> {
1b1a35ee 976 /// Checks whether two concrete constants are equal.
f035d41b
XL
977 pub fn const_eq(&self, ty: &Ty<I>, other: &ConcreteConst<I>, interner: &I) -> bool {
978 interner.const_eq(&ty.interned, &self.interned, &other.interned)
979 }
980}
981
1b1a35ee 982/// A Rust lifetime.
f035d41b
XL
983#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
984pub struct Lifetime<I: Interner> {
985 interned: I::InternedLifetime,
986}
987
988impl<I: Interner> Lifetime<I> {
1b1a35ee
XL
989 /// Create a lifetime from lifetime data
990 /// (or something that can be cast to lifetime data).
f035d41b
XL
991 pub fn new(interner: &I, data: impl CastTo<LifetimeData<I>>) -> Self {
992 Lifetime {
993 interned: I::intern_lifetime(interner, data.cast(interner)),
994 }
995 }
996
1b1a35ee 997 /// Gets the interned value.
f035d41b
XL
998 pub fn interned(&self) -> &I::InternedLifetime {
999 &self.interned
1000 }
1001
1b1a35ee 1002 /// Gets the lifetime data.
f035d41b
XL
1003 pub fn data(&self, interner: &I) -> &LifetimeData<I> {
1004 I::lifetime_data(interner, &self.interned)
1005 }
1006
1007 /// If this is a `Lifetime::BoundVar(d)`, returns `Some(d)` else `None`.
1008 pub fn bound_var(&self, interner: &I) -> Option<BoundVar> {
1009 if let LifetimeData::BoundVar(bv) = self.data(interner) {
1010 Some(*bv)
1011 } else {
1012 None
1013 }
1014 }
1015
1016 /// If this is a `Lifetime::InferenceVar(d)`, returns `Some(d)` else `None`.
1017 pub fn inference_var(&self, interner: &I) -> Option<InferenceVar> {
1018 if let LifetimeData::InferenceVar(depth) = self.data(interner) {
1019 Some(*depth)
1020 } else {
1021 None
1022 }
1023 }
1024
1025 /// True if this lifetime is a "bound" lifetime, and hence
1026 /// needs to be shifted across binders. Meant for debug assertions.
1027 pub fn needs_shift(&self, interner: &I) -> bool {
1028 match self.data(interner) {
1029 LifetimeData::BoundVar(_) => true,
1030 LifetimeData::InferenceVar(_) => false,
1031 LifetimeData::Placeholder(_) => false,
1032 LifetimeData::Phantom(..) => unreachable!(),
1033 }
1034 }
1035}
1036
1b1a35ee 1037/// Lifetime data, including what kind of lifetime it is and what it points to.
f035d41b
XL
1038#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
1039pub enum LifetimeData<I: Interner> {
1b1a35ee 1040 /// See TyData::BoundVar.
f035d41b 1041 BoundVar(BoundVar),
1b1a35ee 1042 /// Lifetime whose value is being inferred.
f035d41b 1043 InferenceVar(InferenceVar),
1b1a35ee 1044 /// Lifetime on some yet-unknown placeholder.
f035d41b 1045 Placeholder(PlaceholderIndex),
1b1a35ee 1046 /// Lifetime on phantom data.
f035d41b
XL
1047 Phantom(Void, PhantomData<I>),
1048}
1049
1050impl<I: Interner> LifetimeData<I> {
1b1a35ee 1051 /// Wrap the lifetime data in a lifetime.
f035d41b
XL
1052 pub fn intern(self, interner: &I) -> Lifetime<I> {
1053 Lifetime::new(interner, self)
1054 }
1055}
1056
1057/// Index of an universally quantified parameter in the environment.
1058/// Two indexes are required, the one of the universe itself
1059/// and the relative index inside the universe.
1060#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1061pub struct PlaceholderIndex {
1062 /// Index *of* the universe.
1063 pub ui: UniverseIndex,
1064 /// Index *in* the universe.
1065 pub idx: usize,
1066}
1067
1068impl PlaceholderIndex {
1b1a35ee 1069 /// Wrap the placeholder instance in a lifetime.
f035d41b
XL
1070 pub fn to_lifetime<I: Interner>(self, interner: &I) -> Lifetime<I> {
1071 LifetimeData::<I>::Placeholder(self).intern(interner)
1072 }
1073
1b1a35ee 1074 /// Create an interned type.
f035d41b
XL
1075 pub fn to_ty<I: Interner>(self, interner: &I) -> Ty<I> {
1076 TyData::Placeholder(self).intern(interner)
1077 }
1078
1b1a35ee 1079 /// Wrap the placeholder index in a constant.
f035d41b
XL
1080 pub fn to_const<I: Interner>(self, interner: &I, ty: Ty<I>) -> Const<I> {
1081 ConstData {
1082 ty,
1083 value: ConstValue::Placeholder(self),
1084 }
1085 .intern(interner)
1086 }
1087}
1088
1b1a35ee
XL
1089/// Normal Rust types, containing the type name and zero or more generic arguments.
1090/// For example, in `Vec<u32>` those would be `Vec` and `[u32]` respectively.
f035d41b
XL
1091#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
1092pub struct ApplicationTy<I: Interner> {
1b1a35ee 1093 /// The type name.
f035d41b 1094 pub name: TypeName<I>,
1b1a35ee 1095 /// The substitution containing the generic arguments.
f035d41b
XL
1096 pub substitution: Substitution<I>,
1097}
1098
1b1a35ee
XL
1099impl<I: Interner> Copy for ApplicationTy<I> where I::InternedSubstitution: Copy {}
1100
f035d41b 1101impl<I: Interner> ApplicationTy<I> {
1b1a35ee 1102 /// Create an interned type from this application type.
f035d41b
XL
1103 pub fn intern(self, interner: &I) -> Ty<I> {
1104 Ty::new(interner, self)
1105 }
1106
1b1a35ee 1107 /// Gets an iterator of all type parameters.
f035d41b
XL
1108 pub fn type_parameters<'a>(&'a self, interner: &'a I) -> impl Iterator<Item = Ty<I>> + 'a {
1109 self.substitution
1110 .iter(interner)
1111 .filter_map(move |p| p.ty(interner))
1112 .cloned()
1113 }
1114
1b1a35ee 1115 /// Gets the first type parameter.
f035d41b
XL
1116 pub fn first_type_parameter(&self, interner: &I) -> Option<Ty<I>> {
1117 self.type_parameters(interner).next()
1118 }
1119
1b1a35ee 1120 /// Gets the number of type parameters.
f035d41b
XL
1121 pub fn len_type_parameters(&self, interner: &I) -> usize {
1122 self.type_parameters(interner).count()
1123 }
1124}
1125
1126/// Represents some extra knowledge we may have about the type variable.
1127/// ```ignore
1128/// let x: &[u32];
1129/// let i = 1;
1130/// x[i]
1131/// ```
1132/// In this example, `i` is known to be some type of integer. We can infer that
1133/// it is `usize` because that is the only integer type that slices have an
1134/// `Index` impl for. `i` would have a `TyKind` of `Integer` to guide the
1135/// inference process.
1136#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
1b1a35ee 1137#[allow(missing_docs)]
f035d41b
XL
1138pub enum TyKind {
1139 General,
1140 Integer,
1141 Float,
1142}
1143
1b1a35ee 1144/// The "kind" of variable. Type, lifetime or constant.
f035d41b 1145#[derive(Clone, PartialEq, Eq, Hash)]
1b1a35ee 1146#[allow(missing_docs)]
f035d41b
XL
1147pub enum VariableKind<I: Interner> {
1148 Ty(TyKind),
1149 Lifetime,
1150 Const(Ty<I>),
1151}
1152
1b1a35ee
XL
1153impl<I: Interner> interner::HasInterner for VariableKind<I> {
1154 type Interner = I;
1155}
1156
1157impl<I: Interner> Copy for VariableKind<I> where I::InternedType: Copy {}
1158
f035d41b
XL
1159impl<I: Interner> VariableKind<I> {
1160 fn to_bound_variable(&self, interner: &I, bound_var: BoundVar) -> GenericArg<I> {
1161 match self {
1162 VariableKind::Ty(_) => {
1163 GenericArgData::Ty(TyData::BoundVar(bound_var).intern(interner)).intern(interner)
1164 }
1165 VariableKind::Lifetime => {
1166 GenericArgData::Lifetime(LifetimeData::BoundVar(bound_var).intern(interner))
1167 .intern(interner)
1168 }
1169 VariableKind::Const(ty) => GenericArgData::Const(
1170 ConstData {
1171 ty: ty.clone(),
1172 value: ConstValue::BoundVar(bound_var),
1173 }
1174 .intern(interner),
1175 )
1176 .intern(interner),
1177 }
1178 }
1179}
1180
1b1a35ee 1181/// A generic argument, see `GenericArgData` for more information.
f035d41b
XL
1182#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
1183pub struct GenericArg<I: Interner> {
1184 interned: I::InternedGenericArg,
1185}
1186
1187impl<I: Interner> GenericArg<I> {
1b1a35ee 1188 /// Constructs a generic argument using `GenericArgData`.
f035d41b
XL
1189 pub fn new(interner: &I, data: GenericArgData<I>) -> Self {
1190 let interned = I::intern_generic_arg(interner, data);
1191 GenericArg { interned }
1192 }
1193
1b1a35ee 1194 /// Gets the interned value.
f035d41b
XL
1195 pub fn interned(&self) -> &I::InternedGenericArg {
1196 &self.interned
1197 }
1198
1b1a35ee 1199 /// Gets the underlying data.
f035d41b
XL
1200 pub fn data(&self, interner: &I) -> &GenericArgData<I> {
1201 I::generic_arg_data(interner, &self.interned)
1202 }
1203
1b1a35ee 1204 /// Asserts that this is a type argument.
f035d41b
XL
1205 pub fn assert_ty_ref(&self, interner: &I) -> &Ty<I> {
1206 self.ty(interner).unwrap()
1207 }
1208
1b1a35ee 1209 /// Asserts that this is a lifetime argument.
f035d41b
XL
1210 pub fn assert_lifetime_ref(&self, interner: &I) -> &Lifetime<I> {
1211 self.lifetime(interner).unwrap()
1212 }
1213
1b1a35ee 1214 /// Asserts that this is a constant argument.
f035d41b
XL
1215 pub fn assert_const_ref(&self, interner: &I) -> &Const<I> {
1216 self.constant(interner).unwrap()
1217 }
1218
1b1a35ee 1219 /// Checks whether the generic argument is a type.
f035d41b
XL
1220 pub fn is_ty(&self, interner: &I) -> bool {
1221 match self.data(interner) {
1222 GenericArgData::Ty(_) => true,
1223 GenericArgData::Lifetime(_) => false,
1224 GenericArgData::Const(_) => false,
1225 }
1226 }
1227
1b1a35ee 1228 /// Returns the type if it is one, `None` otherwise.
f035d41b
XL
1229 pub fn ty(&self, interner: &I) -> Option<&Ty<I>> {
1230 match self.data(interner) {
1231 GenericArgData::Ty(t) => Some(t),
1232 _ => None,
1233 }
1234 }
1235
1b1a35ee 1236 /// Returns the lifetime if it is one, `None` otherwise.
f035d41b
XL
1237 pub fn lifetime(&self, interner: &I) -> Option<&Lifetime<I>> {
1238 match self.data(interner) {
1239 GenericArgData::Lifetime(t) => Some(t),
1240 _ => None,
1241 }
1242 }
1243
1b1a35ee 1244 /// Returns the constant if it is one, `None` otherwise.
f035d41b
XL
1245 pub fn constant(&self, interner: &I) -> Option<&Const<I>> {
1246 match self.data(interner) {
1247 GenericArgData::Const(c) => Some(c),
1248 _ => None,
1249 }
1250 }
1251}
1252
1b1a35ee 1253/// Generic arguments data.
f035d41b
XL
1254#[derive(Clone, PartialEq, Eq, Hash, Visit, Fold, Zip)]
1255pub enum GenericArgData<I: Interner> {
1b1a35ee 1256 /// Type argument
f035d41b 1257 Ty(Ty<I>),
1b1a35ee 1258 /// Lifetime argument
f035d41b 1259 Lifetime(Lifetime<I>),
1b1a35ee 1260 /// Constant argument
f035d41b
XL
1261 Const(Const<I>),
1262}
1263
1b1a35ee
XL
1264impl<I: Interner> Copy for GenericArgData<I>
1265where
1266 I::InternedType: Copy,
1267 I::InternedLifetime: Copy,
1268 I::InternedConst: Copy,
1269{
1270}
1271
f035d41b 1272impl<I: Interner> GenericArgData<I> {
1b1a35ee 1273 /// Create an interned type.
f035d41b
XL
1274 pub fn intern(self, interner: &I) -> GenericArg<I> {
1275 GenericArg::new(interner, self)
1276 }
1277}
1278
1b1a35ee 1279/// A value with an associated variable kind.
f035d41b
XL
1280#[derive(Clone, PartialEq, Eq, Hash)]
1281pub struct WithKind<I: Interner, T> {
1b1a35ee 1282 /// The associated variable kind.
f035d41b 1283 pub kind: VariableKind<I>,
1b1a35ee 1284 /// The wrapped value.
f035d41b
XL
1285 value: T,
1286}
1287
1b1a35ee
XL
1288impl<I: Interner, T: Copy> Copy for WithKind<I, T> where I::InternedType: Copy {}
1289
f035d41b
XL
1290impl<I: Interner, T> HasInterner for WithKind<I, T> {
1291 type Interner = I;
1292}
1293
1294impl<I: Interner, T> From<WithKind<I, T>> for (VariableKind<I>, T) {
1295 fn from(with_kind: WithKind<I, T>) -> Self {
1296 (with_kind.kind, with_kind.value)
1297 }
1298}
1299
1300impl<I: Interner, T> WithKind<I, T> {
1b1a35ee 1301 /// Creates a `WithKind` from a variable kind and a value.
f035d41b
XL
1302 pub fn new(kind: VariableKind<I>, value: T) -> Self {
1303 Self { kind, value }
1304 }
1305
1b1a35ee 1306 /// Maps the value in `WithKind`.
f035d41b
XL
1307 pub fn map<U, OP>(self, op: OP) -> WithKind<I, U>
1308 where
1309 OP: FnOnce(T) -> U,
1310 {
1311 WithKind {
1312 kind: self.kind,
1313 value: op(self.value),
1314 }
1315 }
1316
1b1a35ee 1317 /// Maps a function taking `WithKind<I, &T>` over `&WithKind<I, T>`.
f035d41b
XL
1318 pub fn map_ref<U, OP>(&self, op: OP) -> WithKind<I, U>
1319 where
1320 OP: FnOnce(&T) -> U,
1321 {
1322 WithKind {
1323 kind: self.kind.clone(),
1324 value: op(&self.value),
1325 }
1326 }
1327
1b1a35ee 1328 /// Extract the value, ignoring the variable kind.
f035d41b
XL
1329 pub fn skip_kind(&self) -> &T {
1330 &self.value
1331 }
1332}
1333
1b1a35ee 1334/// A variable kind with universe index.
f035d41b
XL
1335#[allow(type_alias_bounds)]
1336pub type CanonicalVarKind<I: Interner> = WithKind<I, UniverseIndex>;
1337
1b1a35ee 1338/// An alias, which is a trait indirection such as a projection or opaque type.
f035d41b
XL
1339#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
1340pub enum AliasTy<I: Interner> {
1b1a35ee 1341 /// An associated type projection.
f035d41b 1342 Projection(ProjectionTy<I>),
1b1a35ee 1343 /// An opaque type.
f035d41b
XL
1344 Opaque(OpaqueTy<I>),
1345}
1346
1b1a35ee
XL
1347impl<I: Interner> Copy for AliasTy<I> where I::InternedSubstitution: Copy {}
1348
f035d41b 1349impl<I: Interner> AliasTy<I> {
1b1a35ee 1350 /// Create an interned type for this alias.
f035d41b
XL
1351 pub fn intern(self, interner: &I) -> Ty<I> {
1352 Ty::new(interner, self)
1353 }
1354
1b1a35ee 1355 /// Gets the type parameters of the `Self` type in this alias type.
f035d41b
XL
1356 pub fn self_type_parameter(&self, interner: &I) -> Ty<I> {
1357 match self {
1358 AliasTy::Projection(projection_ty) => projection_ty
1359 .substitution
1360 .iter(interner)
1361 .find_map(move |p| p.ty(interner))
1362 .unwrap()
1363 .clone(),
1364 _ => todo!(),
1365 }
1366 }
1367}
1368
1b1a35ee 1369/// A projection `<P0 as TraitName<P1..Pn>>::AssocItem<Pn+1..Pm>`.
f035d41b
XL
1370#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
1371pub struct ProjectionTy<I: Interner> {
1b1a35ee 1372 /// The id for the associated type member.
f035d41b 1373 pub associated_ty_id: AssocTypeId<I>,
1b1a35ee 1374 /// The substitution for the projection.
f035d41b
XL
1375 pub substitution: Substitution<I>,
1376}
1377
1b1a35ee
XL
1378impl<I: Interner> Copy for ProjectionTy<I> where I::InternedSubstitution: Copy {}
1379
1380/// An opaque type `opaque type T<..>: Trait = HiddenTy`.
f035d41b
XL
1381#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
1382pub struct OpaqueTy<I: Interner> {
1b1a35ee 1383 /// The id for the opaque type.
f035d41b 1384 pub opaque_ty_id: OpaqueTyId<I>,
1b1a35ee 1385 /// The substitution for the opaque type.
f035d41b
XL
1386 pub substitution: Substitution<I>,
1387}
1388
1b1a35ee
XL
1389impl<I: Interner> Copy for OpaqueTy<I> where I::InternedSubstitution: Copy {}
1390
1391/// A trait reference describes the relationship between a type and a trait.
1392/// This can be used in two forms:
1393/// - `P0: Trait<P1..Pn>` (e.g. `i32: Copy`), which mentions that the type
1394/// implements the trait.
1395/// - `<P0 as Trait<P1..Pn>>` (e.g. `i32 as Copy`), which casts the type to
1396/// that specific trait.
f035d41b
XL
1397#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
1398pub struct TraitRef<I: Interner> {
1b1a35ee 1399 /// The trait id.
f035d41b 1400 pub trait_id: TraitId<I>,
1b1a35ee 1401 /// The substitution, containing both the `Self` type and the parameters.
f035d41b
XL
1402 pub substitution: Substitution<I>,
1403}
1404
1b1a35ee
XL
1405impl<I: Interner> Copy for TraitRef<I> where I::InternedSubstitution: Copy {}
1406
f035d41b 1407impl<I: Interner> TraitRef<I> {
1b1a35ee 1408 /// Gets all type parameters in this trait ref, including `Self`.
f035d41b
XL
1409 pub fn type_parameters<'a>(&'a self, interner: &'a I) -> impl Iterator<Item = Ty<I>> + 'a {
1410 self.substitution
1411 .iter(interner)
1412 .filter_map(move |p| p.ty(interner))
1413 .cloned()
1414 }
1415
1b1a35ee 1416 /// Gets the type parameters of the `Self` type in this trait ref.
f035d41b
XL
1417 pub fn self_type_parameter(&self, interner: &I) -> Ty<I> {
1418 self.type_parameters(interner).next().unwrap()
1419 }
1420
1b1a35ee 1421 /// Construct a `FromEnv` using this trait ref.
f035d41b
XL
1422 pub fn from_env(self) -> FromEnv<I> {
1423 FromEnv::Trait(self)
1424 }
1425
1b1a35ee 1426 /// Construct a `WellFormed` using this trait ref.
f035d41b
XL
1427 pub fn well_formed(self) -> WellFormed<I> {
1428 WellFormed::Trait(self)
1429 }
1430}
1431
1b1a35ee
XL
1432/// Lifetime outlives, which for `'a: 'b`` checks that the lifetime `'a`
1433/// is a superset of the value of `'b`.
f035d41b 1434#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
1b1a35ee 1435#[allow(missing_docs)]
f035d41b
XL
1436pub struct LifetimeOutlives<I: Interner> {
1437 pub a: Lifetime<I>,
1438 pub b: Lifetime<I>,
1439}
1b1a35ee
XL
1440
1441impl<I: Interner> Copy for LifetimeOutlives<I> where I::InternedLifetime: Copy {}
1442
1443/// Type outlives, which for `T: 'a` checks that the type `T`
1444/// lives at least as long as the lifetime `'a`
1445#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
1446pub struct TypeOutlives<I: Interner> {
1447 /// The type which must outlive the given lifetime.
1448 pub ty: Ty<I>,
1449 /// The lifetime which the type must outlive.
1450 pub lifetime: Lifetime<I>,
1451}
1452
1453impl<I: Interner> Copy for TypeOutlives<I>
1454where
1455 I::InternedLifetime: Copy,
1456 I::InternedType: Copy,
1457{
1458}
1459
f035d41b
XL
1460/// Where clauses that can be written by a Rust programmer.
1461#[derive(Clone, PartialEq, Eq, Hash, Fold, SuperVisit, HasInterner, Zip)]
1462pub enum WhereClause<I: Interner> {
1b1a35ee 1463 /// Type implements a trait.
f035d41b 1464 Implemented(TraitRef<I>),
1b1a35ee 1465 /// Type is equal to an alias.
f035d41b 1466 AliasEq(AliasEq<I>),
1b1a35ee 1467 /// One lifetime outlives another.
f035d41b 1468 LifetimeOutlives(LifetimeOutlives<I>),
1b1a35ee
XL
1469 /// Type outlives a lifetime.
1470 TypeOutlives(TypeOutlives<I>),
f035d41b
XL
1471}
1472
1b1a35ee
XL
1473impl<I: Interner> Copy for WhereClause<I>
1474where
1475 I::InternedSubstitution: Copy,
1476 I::InternedLifetime: Copy,
1477 I::InternedType: Copy,
1478{
1479}
1480
1481/// Checks whether a type or trait ref is well-formed.
f035d41b
XL
1482#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
1483pub enum WellFormed<I: Interner> {
1484 /// A predicate which is true when some trait ref is well-formed.
1485 /// For example, given the following trait definitions:
1486 ///
1487 /// ```notrust
1488 /// trait Clone { ... }
1489 /// trait Copy where Self: Clone { ... }
1490 /// ```
1491 ///
1492 /// then we have the following rule:
1493 ///
1494 /// ```notrust
1495 /// WellFormed(?Self: Copy) :- ?Self: Copy, WellFormed(?Self: Clone)
1496 /// ```
1497 Trait(TraitRef<I>),
1498
1499 /// A predicate which is true when some type is well-formed.
1500 /// For example, given the following type definition:
1501 ///
1502 /// ```notrust
1503 /// struct Set<K> where K: Hash {
1504 /// ...
1505 /// }
1506 /// ```
1507 ///
1508 /// then we have the following rule: `WellFormedTy(Set<K>) :- Implemented(K: Hash)`.
1509 Ty(Ty<I>),
1510}
1511
1b1a35ee
XL
1512impl<I: Interner> Copy for WellFormed<I>
1513where
1514 I::InternedType: Copy,
1515 I::InternedSubstitution: Copy,
1516{
1517}
1518
1519/// Checks whether a type or trait ref can be derived from the contents of the environment.
f035d41b
XL
1520#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
1521pub enum FromEnv<I: Interner> {
1522 /// A predicate which enables deriving everything which should be true if we *know* that
1523 /// some trait ref is well-formed. For example given the above trait definitions, we can use
1524 /// `FromEnv(T: Copy)` to derive that `T: Clone`, like in:
1525 ///
1526 /// ```notrust
1527 /// forall<T> {
1528 /// if (FromEnv(T: Copy)) {
1529 /// T: Clone
1530 /// }
1531 /// }
1532 /// ```
1533 Trait(TraitRef<I>),
1534
1535 /// A predicate which enables deriving everything which should be true if we *know* that
1536 /// some type is well-formed. For example given the above type definition, we can use
1537 /// `FromEnv(Set<K>)` to derive that `K: Hash`, like in:
1538 ///
1539 /// ```notrust
1540 /// forall<K> {
1541 /// if (FromEnv(Set<K>)) {
1542 /// K: Hash
1543 /// }
1544 /// }
1545 /// ```
1546 Ty(Ty<I>),
1547}
1548
1b1a35ee
XL
1549impl<I: Interner> Copy for FromEnv<I>
1550where
1551 I::InternedType: Copy,
1552 I::InternedSubstitution: Copy,
1553{
1554}
1555
f035d41b
XL
1556/// A "domain goal" is a goal that is directly about Rust, rather than a pure
1557/// logical statement. As much as possible, the Chalk solver should avoid
1558/// decomposing this enum, and instead treat its values opaquely.
1559#[derive(Clone, PartialEq, Eq, Hash, Fold, SuperVisit, HasInterner, Zip)]
1560pub enum DomainGoal<I: Interner> {
1b1a35ee 1561 /// Simple goal that is true if the where clause is true.
f035d41b
XL
1562 Holds(WhereClause<I>),
1563
1b1a35ee 1564 /// True if the type or trait ref is well-formed.
f035d41b
XL
1565 WellFormed(WellFormed<I>),
1566
1b1a35ee 1567 /// True if the trait ref can be derived from in-scope where clauses.
f035d41b
XL
1568 FromEnv(FromEnv<I>),
1569
1b1a35ee 1570 /// True if the alias type can be normalized to some other type
f035d41b
XL
1571 Normalize(Normalize<I>),
1572
1573 /// True if a type is considered to have been "defined" by the current crate. This is true for
1574 /// a `struct Foo { }` but false for a `#[upstream] struct Foo { }`. However, for fundamental types
1575 /// like `Box<T>`, it is true if `T` is local.
1576 IsLocal(Ty<I>),
1577
1578 /// True if a type is *not* considered to have been "defined" by the current crate. This is
1579 /// false for a `struct Foo { }` but true for a `#[upstream] struct Foo { }`. However, for
1580 /// fundamental types like `Box<T>`, it is true if `T` is upstream.
1581 IsUpstream(Ty<I>),
1582
1583 /// True if a type and its input types are fully visible, known types. That is, there are no
1584 /// unknown type parameters anywhere in this type.
1585 ///
1586 /// More formally, for each struct S<P0..Pn>:
1587 /// forall<P0..Pn> {
1588 /// IsFullyVisible(S<P0...Pn>) :-
1589 /// IsFullyVisible(P0),
1590 /// ...
1591 /// IsFullyVisible(Pn)
1592 /// }
1593 ///
1594 /// Note that any of these types can have lifetimes in their parameters too, but we only
1595 /// consider type parameters.
1596 IsFullyVisible(Ty<I>),
1597
1598 /// Used to dictate when trait impls are allowed in the current (local) crate based on the
1599 /// orphan rules.
1600 ///
1601 /// `LocalImplAllowed(T: Trait)` is true if the type T is allowed to impl trait Trait in
1602 /// the current crate. Under the current rules, this is unconditionally true for all types if
1603 /// the Trait is considered to be "defined" in the current crate. If that is not the case, then
1604 /// `LocalImplAllowed(T: Trait)` can still be true if `IsLocal(T)` is true.
1605 LocalImplAllowed(TraitRef<I>),
1606
1607 /// Used to activate the "compatible modality" rules. Rules that introduce predicates that have
1608 /// to do with "all compatible universes" should depend on this clause so that they only apply
1609 /// if this is present.
1b1a35ee 1610 Compatible,
f035d41b
XL
1611
1612 /// Used to indicate that a given type is in a downstream crate. Downstream crates contain the
1613 /// current crate at some level of their dependencies.
1614 ///
1615 /// Since chalk does not actually see downstream types, this is usually introduced with
1616 /// implication on a fresh, universally quantified type.
1617 ///
1618 /// forall<T> { if (DownstreamType(T)) { /* ... */ } }
1619 ///
1620 /// This makes a new type `T` available and makes `DownstreamType(T)` provable for that type.
1621 DownstreamType(Ty<I>),
1622
1623 /// Used to activate the "reveal mode", in which opaque (`impl Trait`) types can be equated
1624 /// to their actual type.
1b1a35ee 1625 Reveal,
f035d41b
XL
1626
1627 /// Used to indicate that a trait is object safe.
1628 ObjectSafe(TraitId<I>),
1629}
1630
1b1a35ee
XL
1631impl<I: Interner> Copy for DomainGoal<I>
1632where
1633 I::InternedSubstitution: Copy,
1634 I::InternedLifetime: Copy,
1635 I::InternedType: Copy,
1636{
1637}
1638
1639/// A where clause that can contain `forall<>` or `exists<>` quantifiers.
f035d41b
XL
1640pub type QuantifiedWhereClause<I> = Binders<WhereClause<I>>;
1641
1642impl<I: Interner> WhereClause<I> {
1643 /// Turn a where clause into the WF version of it i.e.:
1644 /// * `Implemented(T: Trait)` maps to `WellFormed(T: Trait)`
1645 /// * `ProjectionEq(<T as Trait>::Item = Foo)` maps to `WellFormed(<T as Trait>::Item = Foo)`
1646 /// * any other clause maps to itself
1647 pub fn into_well_formed_goal(self, interner: &I) -> DomainGoal<I> {
1648 match self {
1649 WhereClause::Implemented(trait_ref) => WellFormed::Trait(trait_ref).cast(interner),
1650 wc => wc.cast(interner),
1651 }
1652 }
1653
1654 /// Same as `into_well_formed_goal` but with the `FromEnv` predicate instead of `WellFormed`.
1655 pub fn into_from_env_goal(self, interner: &I) -> DomainGoal<I> {
1656 match self {
1657 WhereClause::Implemented(trait_ref) => FromEnv::Trait(trait_ref).cast(interner),
1658 wc => wc.cast(interner),
1659 }
1660 }
1661
1b1a35ee 1662 /// If where clause is a `TraitRef`, returns its trait id.
f035d41b
XL
1663 pub fn trait_id(&self) -> Option<TraitId<I>> {
1664 match self {
1665 WhereClause::Implemented(trait_ref) => Some(trait_ref.trait_id),
1666 WhereClause::AliasEq(_) => None,
1667 WhereClause::LifetimeOutlives(_) => None,
1b1a35ee 1668 WhereClause::TypeOutlives(_) => None,
f035d41b
XL
1669 }
1670 }
1671}
1672
1673impl<I: Interner> QuantifiedWhereClause<I> {
1674 /// As with `WhereClause::into_well_formed_goal`, but for a
1675 /// quantified where clause. For example, `forall<T> {
1676 /// Implemented(T: Trait)}` would map to `forall<T> {
1677 /// WellFormed(T: Trait) }`.
1678 pub fn into_well_formed_goal(self, interner: &I) -> Binders<DomainGoal<I>> {
1679 self.map(|wc| wc.into_well_formed_goal(interner))
1680 }
1681
1682 /// As with `WhereClause::into_from_env_goal`, but mapped over any
1683 /// binders. For example, `forall<T> {
1684 /// Implemented(T: Trait)}` would map to `forall<T> {
1685 /// FromEnv(T: Trait) }`.
1686 pub fn into_from_env_goal(self, interner: &I) -> Binders<DomainGoal<I>> {
1687 self.map(|wc| wc.into_from_env_goal(interner))
1688 }
1689
1b1a35ee 1690 /// If the underlying where clause is a `TraitRef`, returns its trait id.
f035d41b
XL
1691 pub fn trait_id(&self) -> Option<TraitId<I>> {
1692 self.skip_binders().trait_id()
1693 }
1694}
1695
f035d41b
XL
1696impl<I: Interner> DomainGoal<I> {
1697 /// Convert `Implemented(...)` into `FromEnv(...)`, but leave other
1698 /// goals unchanged.
1699 pub fn into_from_env_goal(self, interner: &I) -> DomainGoal<I> {
1700 match self {
1701 DomainGoal::Holds(wc) => wc.into_from_env_goal(interner),
1702 goal => goal,
1703 }
1704 }
1705
1b1a35ee 1706 /// Lists generic arguments that are inputs to this domain goal.
f035d41b
XL
1707 pub fn inputs(&self, interner: &I) -> Vec<GenericArg<I>> {
1708 match self {
1709 DomainGoal::Holds(WhereClause::AliasEq(alias_eq)) => {
1710 vec![GenericArgData::Ty(alias_eq.alias.clone().intern(interner)).intern(interner)]
1711 }
1712 _ => Vec::new(),
1713 }
1714 }
1715}
1716
1b1a35ee 1717/// Equality goal: tries to prove that two values are equal.
f035d41b 1718#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, Zip)]
1b1a35ee 1719#[allow(missing_docs)]
f035d41b
XL
1720pub struct EqGoal<I: Interner> {
1721 pub a: GenericArg<I>,
1722 pub b: GenericArg<I>,
1723}
1724
1b1a35ee
XL
1725impl<I: Interner> Copy for EqGoal<I> where I::InternedGenericArg: Copy {}
1726
f035d41b
XL
1727/// Proves that the given type alias **normalizes** to the given
1728/// type. A projection `T::Foo` normalizes to the type `U` if we can
1729/// **match it to an impl** and that impl has a `type Foo = V` where
1730/// `U = V`.
1731#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, Zip)]
1b1a35ee 1732#[allow(missing_docs)]
f035d41b
XL
1733pub struct Normalize<I: Interner> {
1734 pub alias: AliasTy<I>,
1735 pub ty: Ty<I>,
1736}
1737
1b1a35ee
XL
1738impl<I: Interner> Copy for Normalize<I>
1739where
1740 I::InternedSubstitution: Copy,
1741 I::InternedType: Copy,
1742{
1743}
1744
f035d41b
XL
1745/// Proves **equality** between an alias and a type.
1746#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, Zip)]
1b1a35ee 1747#[allow(missing_docs)]
f035d41b
XL
1748pub struct AliasEq<I: Interner> {
1749 pub alias: AliasTy<I>,
1750 pub ty: Ty<I>,
1751}
1752
1b1a35ee
XL
1753impl<I: Interner> Copy for AliasEq<I>
1754where
1755 I::InternedSubstitution: Copy,
1756 I::InternedType: Copy,
1757{
1758}
1759
f035d41b
XL
1760impl<I: Interner> HasInterner for AliasEq<I> {
1761 type Interner = I;
1762}
1763
1764/// Indicates that the `value` is universally quantified over `N`
1765/// parameters of the given kinds, where `N == self.binders.len()`. A
1766/// variable with depth `i < N` refers to the value at
1767/// `self.binders[i]`. Variables with depth `>= N` are free.
1768///
1769/// (IOW, we use deBruijn indices, where binders are introduced in reverse order
1770/// of `self.binders`.)
1771#[derive(Clone, PartialEq, Eq, Hash)]
1772pub struct Binders<T: HasInterner> {
1b1a35ee 1773 /// The binders that quantify over the value.
f035d41b 1774 pub binders: VariableKinds<T::Interner>,
1b1a35ee
XL
1775
1776 /// The value being quantified over.
f035d41b
XL
1777 value: T,
1778}
1779
1b1a35ee
XL
1780impl<T: HasInterner + Copy> Copy for Binders<T> where
1781 <T::Interner as Interner>::InternedVariableKinds: Copy
1782{
1783}
1784
f035d41b
XL
1785impl<T: HasInterner> HasInterner for Binders<T> {
1786 type Interner = T::Interner;
1787}
1788
1789impl<T: HasInterner> Binders<T> {
1b1a35ee 1790 /// Create new binders.
f035d41b
XL
1791 pub fn new(binders: VariableKinds<T::Interner>, value: T) -> Self {
1792 Self { binders, value }
1793 }
1794
1795 /// Wraps the given value in a binder without variables, i.e. `for<>
1796 /// (value)`. Since our deBruijn indices count binders, not variables, this
1797 /// is sometimes useful.
1798 pub fn empty(interner: &T::Interner, value: T) -> Self {
1b1a35ee 1799 let binders = VariableKinds::empty(interner);
f035d41b
XL
1800 Self { binders, value }
1801 }
1802
1803 /// Skips the binder and returns the "bound" value. This is a
1804 /// risky thing to do because it's easy to get confused about
1805 /// De Bruijn indices and the like. `skip_binder` is only valid
1806 /// when you are either extracting data that has nothing to
1807 /// do with bound vars, or you are being very careful about
1808 /// your depth accounting.
1809 ///
1810 /// Some examples where `skip_binder` is reasonable:
1811 ///
1812 /// - extracting the `TraitId` from a TraitRef;
1813 /// - checking if there are any fields in a StructDatum
1814 pub fn skip_binders(&self) -> &T {
1815 &self.value
1816 }
1817
1818 /// Converts `&Binders<T>` to `Binders<&T>`. Produces new `Binders`
1819 /// with cloned quantifiers containing a reference to the original
1820 /// value, leaving the original in place.
1821 pub fn as_ref(&self) -> Binders<&T> {
1822 Binders {
1823 binders: self.binders.clone(),
1824 value: &self.value,
1825 }
1826 }
1827
1b1a35ee 1828 /// Maps the binders by applying a function.
f035d41b
XL
1829 pub fn map<U, OP>(self, op: OP) -> Binders<U>
1830 where
1831 OP: FnOnce(T) -> U,
1832 U: HasInterner<Interner = T::Interner>,
1833 {
1834 let value = op(self.value);
1835 Binders {
1836 binders: self.binders,
1837 value,
1838 }
1839 }
1840
1841 /// Transforms the inner value according to the given function; returns
1842 /// `None` if the function returns `None`.
1843 pub fn filter_map<U, OP>(self, op: OP) -> Option<Binders<U>>
1844 where
1845 OP: FnOnce(T) -> Option<U>,
1846 U: HasInterner<Interner = T::Interner>,
1847 {
1848 let value = op(self.value)?;
1849 Some(Binders {
1850 binders: self.binders,
1851 value,
1852 })
1853 }
1854
1b1a35ee 1855 /// Maps a function taking `Binders<&T>` over `&Binders<T>`.
f035d41b
XL
1856 pub fn map_ref<'a, U, OP>(&'a self, op: OP) -> Binders<U>
1857 where
1858 OP: FnOnce(&'a T) -> U,
1859 U: HasInterner<Interner = T::Interner>,
1860 {
1861 self.as_ref().map(op)
1862 }
1863
1864 /// Creates a `Substitution` containing bound vars such that applying this
1865 /// substitution will not change the value, i.e. `^0.0, ^0.1, ^0.2` and so
1866 /// on.
1867 pub fn identity_substitution(&self, interner: &T::Interner) -> Substitution<T::Interner> {
1b1a35ee 1868 Substitution::from_iter(
f035d41b
XL
1869 interner,
1870 self.binders
1871 .iter(interner)
1872 .enumerate()
1b1a35ee 1873 .map(|p| p.to_generic_arg(interner)),
f035d41b
XL
1874 )
1875 }
1876
1877 /// Creates a fresh binders that contains a single type
1878 /// variable. The result of the closure will be embedded in this
1879 /// binder. Note that you should be careful with what you return
1880 /// from the closure to account for the binder that will be added.
1881 ///
1882 /// XXX FIXME -- this is potentially a pretty footgun-y function.
1883 pub fn with_fresh_type_var(
1884 interner: &T::Interner,
1885 op: impl FnOnce(Ty<T::Interner>) -> T,
1886 ) -> Binders<T> {
1887 // The new variable is at the front and everything afterwards is shifted up by 1
1888 let new_var = TyData::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(interner);
1889 let value = op(new_var);
1b1a35ee 1890 let binders = VariableKinds::from1(interner, VariableKind::Ty(TyKind::General));
f035d41b
XL
1891 Binders { binders, value }
1892 }
1893
1b1a35ee 1894 /// Returns the number of binders.
f035d41b
XL
1895 pub fn len(&self, interner: &T::Interner) -> usize {
1896 self.binders.len(interner)
1897 }
1898}
1899
1900impl<T, I> Binders<Binders<T>>
1901where
1902 T: Fold<I, I> + HasInterner<Interner = I>,
1903 T::Result: HasInterner<Interner = I>,
1904 I: Interner,
1905{
1906 /// This turns two levels of binders (`for<A> for<B>`) into one level (`for<A, B>`).
1907 pub fn fuse_binders(self, interner: &T::Interner) -> Binders<T::Result> {
1908 let num_binders = self.len(interner);
1909 // generate a substitution to shift the indexes of the inner binder:
1b1a35ee 1910 let subst = Substitution::from_iter(
f035d41b
XL
1911 interner,
1912 self.value
1913 .binders
1914 .iter(interner)
1915 .enumerate()
1b1a35ee 1916 .map(|(i, pk)| (i + num_binders, pk).to_generic_arg(interner)),
f035d41b
XL
1917 );
1918 let value = self.value.substitute(interner, &subst);
1b1a35ee 1919 let binders = VariableKinds::from_iter(
f035d41b
XL
1920 interner,
1921 self.binders
1922 .iter(interner)
1923 .chain(self.value.binders.iter(interner))
1924 .cloned(),
1925 );
1926 Binders { binders, value }
1927 }
1928}
1929
1930impl<T: HasInterner> From<Binders<T>> for (VariableKinds<T::Interner>, T) {
1931 fn from(binders: Binders<T>) -> Self {
1932 (binders.binders, binders.value)
1933 }
1934}
1935
1936impl<T, I> Binders<T>
1937where
1938 T: Fold<I, I> + HasInterner<Interner = I>,
1939 I: Interner,
1940{
1941 /// Substitute `parameters` for the variables introduced by these
1942 /// binders. So if the binders represent (e.g.) `<X, Y> { T }` and
1943 /// parameters is the slice `[A, B]`, then returns `[X => A, Y =>
1944 /// B] T`.
1945 pub fn substitute(
1946 &self,
1947 interner: &I,
1948 parameters: &(impl AsParameters<I> + ?Sized),
1949 ) -> T::Result {
1950 let parameters = parameters.as_parameters(interner);
1951 assert_eq!(self.binders.len(interner), parameters.len());
1952 Subst::apply(interner, parameters, &self.value)
1953 }
1954}
1955
1956/// Allows iterating over a Binders<Vec<T>>, for instance.
1957/// Each element will include the same set of parameter bounds.
1958impl<V, U> IntoIterator for Binders<V>
1959where
1960 V: HasInterner + IntoIterator<Item = U>,
1961 U: HasInterner<Interner = V::Interner>,
1962{
1963 type Item = Binders<U>;
1964 type IntoIter = BindersIntoIterator<V>;
1965
1966 fn into_iter(self) -> Self::IntoIter {
1967 BindersIntoIterator {
1968 iter: self.value.into_iter(),
1969 binders: self.binders,
1970 }
1971 }
1972}
1973
1b1a35ee 1974/// `IntoIterator` for binders.
f035d41b
XL
1975pub struct BindersIntoIterator<V: HasInterner + IntoIterator> {
1976 iter: <V as IntoIterator>::IntoIter,
1977 binders: VariableKinds<V::Interner>,
1978}
1979
1980impl<V> Iterator for BindersIntoIterator<V>
1981where
1982 V: HasInterner + IntoIterator,
1983 <V as IntoIterator>::Item: HasInterner<Interner = V::Interner>,
1984{
1985 type Item = Binders<<V as IntoIterator>::Item>;
1986 fn next(&mut self) -> Option<Self::Item> {
1987 self.iter
1988 .next()
1989 .map(|v| Binders::new(self.binders.clone(), v))
1990 }
1991}
1992
1993/// Represents one clause of the form `consequence :- conditions` where
1994/// `conditions = cond_1 && cond_2 && ...` is the conjunction of the individual
1995/// conditions.
1996#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
1997pub struct ProgramClauseImplication<I: Interner> {
1b1a35ee 1998 /// The consequence of the clause, which holds if the conditions holds.
f035d41b 1999 pub consequence: DomainGoal<I>,
1b1a35ee
XL
2000
2001 /// The condition goals that should hold.
f035d41b 2002 pub conditions: Goals<I>,
1b1a35ee
XL
2003
2004 /// The lifetime constraints that should be proven.
2005 pub constraints: Constraints<I>,
2006
2007 /// The relative priority of the implication.
f035d41b
XL
2008 pub priority: ClausePriority,
2009}
2010
1b1a35ee 2011/// Specifies how important an implication is.
f035d41b
XL
2012#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
2013pub enum ClausePriority {
1b1a35ee 2014 /// High priority, the solver should prioritize this.
f035d41b 2015 High,
1b1a35ee
XL
2016
2017 /// Low priority, this implication has lower chance to be relevant to the goal.
f035d41b
XL
2018 Low,
2019}
2020
2021impl std::ops::BitAnd for ClausePriority {
2022 type Output = ClausePriority;
2023 fn bitand(self, rhs: ClausePriority) -> Self::Output {
2024 match (self, rhs) {
2025 (ClausePriority::High, ClausePriority::High) => ClausePriority::High,
2026 _ => ClausePriority::Low,
2027 }
2028 }
2029}
2030
1b1a35ee 2031/// Contains the data for a program clause.
f035d41b
XL
2032#[derive(Clone, PartialEq, Eq, Hash, Fold, HasInterner, Zip)]
2033pub struct ProgramClauseData<I: Interner>(pub Binders<ProgramClauseImplication<I>>);
2034
2035impl<I: Interner> ProgramClauseImplication<I> {
1b1a35ee 2036 /// Change the implication into an application holding a `FromEnv` goal.
f035d41b
XL
2037 pub fn into_from_env_clause(self, interner: &I) -> ProgramClauseImplication<I> {
2038 if self.conditions.is_empty(interner) {
2039 ProgramClauseImplication {
2040 consequence: self.consequence.into_from_env_goal(interner),
2041 conditions: self.conditions.clone(),
1b1a35ee 2042 constraints: self.constraints.clone(),
f035d41b
XL
2043 priority: self.priority,
2044 }
2045 } else {
2046 self
2047 }
2048 }
2049}
2050
2051impl<I: Interner> ProgramClauseData<I> {
1b1a35ee 2052 /// Change the program clause data into a `FromEnv` program clause.
f035d41b
XL
2053 pub fn into_from_env_clause(self, interner: &I) -> ProgramClauseData<I> {
2054 ProgramClauseData(self.0.map(|i| i.into_from_env_clause(interner)))
2055 }
2056
1b1a35ee 2057 /// Intern the program clause data.
f035d41b
XL
2058 pub fn intern(self, interner: &I) -> ProgramClause<I> {
2059 ProgramClause {
2060 interned: interner.intern_program_clause(self),
2061 }
2062 }
2063}
2064
1b1a35ee 2065/// A program clause is a logic expression used to describe a part of the program.
f035d41b
XL
2066#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
2067pub struct ProgramClause<I: Interner> {
2068 interned: I::InternedProgramClause,
2069}
2070
2071impl<I: Interner> ProgramClause<I> {
1b1a35ee 2072 /// Create a new program clause using `ProgramClauseData`.
f035d41b
XL
2073 pub fn new(interner: &I, clause: ProgramClauseData<I>) -> Self {
2074 let interned = interner.intern_program_clause(clause);
2075 Self { interned }
2076 }
2077
1b1a35ee 2078 /// Change the clause into a `FromEnv` clause.
f035d41b
XL
2079 pub fn into_from_env_clause(self, interner: &I) -> ProgramClause<I> {
2080 let program_clause_data = self.data(interner);
2081 let new_clause = program_clause_data.clone().into_from_env_clause(interner);
2082 Self::new(interner, new_clause)
2083 }
2084
1b1a35ee 2085 /// Get the interned program clause.
f035d41b
XL
2086 pub fn interned(&self) -> &I::InternedProgramClause {
2087 &self.interned
2088 }
2089
1b1a35ee 2090 /// Get the program clause data.
f035d41b
XL
2091 pub fn data(&self, interner: &I) -> &ProgramClauseData<I> {
2092 interner.program_clause_data(&self.interned)
2093 }
2094}
2095
f035d41b
XL
2096/// Wraps a "canonicalized item". Items are canonicalized as follows:
2097///
2098/// All unresolved existential variables are "renumbered" according to their
2099/// first appearance; the kind/universe of the variable is recorded in the
2100/// `binders` field.
2101#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2102pub struct Canonical<T: HasInterner> {
1b1a35ee 2103 /// The item that is canonicalized.
f035d41b 2104 pub value: T,
1b1a35ee
XL
2105
2106 /// The kind/universe of the variable.
f035d41b
XL
2107 pub binders: CanonicalVarKinds<T::Interner>,
2108}
2109
2110impl<T: HasInterner> HasInterner for Canonical<T> {
2111 type Interner = T::Interner;
2112}
2113
2114/// A "universe canonical" value. This is a wrapper around a
2115/// `Canonical`, indicating that the universes within have been
2116/// "renumbered" to start from 0 and collapse unimportant
2117/// distinctions.
2118///
2119/// To produce one of these values, use the `u_canonicalize` method.
2120#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2121pub struct UCanonical<T: HasInterner> {
1b1a35ee 2122 /// The wrapped `Canonical`.
f035d41b 2123 pub canonical: Canonical<T>,
1b1a35ee
XL
2124
2125 /// The number of universes that have been collapsed.
f035d41b
XL
2126 pub universes: usize,
2127}
2128
2129impl<T: HasInterner> UCanonical<T> {
1b1a35ee
XL
2130 /// Checks whether the universe canonical value is a trivial
2131 /// substitution (e.g. an identity substitution).
f035d41b
XL
2132 pub fn is_trivial_substitution(
2133 &self,
2134 interner: &T::Interner,
2135 canonical_subst: &Canonical<AnswerSubst<T::Interner>>,
2136 ) -> bool {
2137 let subst = &canonical_subst.value.subst;
2138 assert_eq!(
2139 self.canonical.binders.len(interner),
1b1a35ee 2140 subst.as_slice(interner).len()
f035d41b
XL
2141 );
2142 subst.is_identity_subst(interner)
2143 }
2144
1b1a35ee 2145 /// Creates an identity substitution.
f035d41b
XL
2146 pub fn trivial_substitution(&self, interner: &T::Interner) -> Substitution<T::Interner> {
2147 let binders = &self.canonical.binders;
1b1a35ee 2148 Substitution::from_iter(
f035d41b
XL
2149 interner,
2150 binders
2151 .iter(interner)
2152 .enumerate()
2153 .map(|(index, pk)| {
2154 let bound_var = BoundVar::new(DebruijnIndex::INNERMOST, index);
2155 match &pk.kind {
2156 VariableKind::Ty(_) => {
2157 GenericArgData::Ty(TyData::BoundVar(bound_var).intern(interner))
2158 .intern(interner)
2159 }
2160 VariableKind::Lifetime => GenericArgData::Lifetime(
2161 LifetimeData::BoundVar(bound_var).intern(interner),
2162 )
2163 .intern(interner),
2164 VariableKind::Const(ty) => GenericArgData::Const(
2165 ConstData {
2166 ty: ty.clone(),
2167 value: ConstValue::BoundVar(bound_var),
2168 }
2169 .intern(interner),
2170 )
2171 .intern(interner),
2172 }
2173 })
2174 .collect::<Vec<_>>(),
2175 )
2176 }
2177}
2178
f035d41b
XL
2179#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
2180/// A general goal; this is the full range of questions you can pose to Chalk.
2181pub struct Goal<I: Interner> {
2182 interned: I::InternedGoal,
2183}
2184
2185impl<I: Interner> Goal<I> {
1b1a35ee 2186 /// Create a new goal using `GoalData`.
f035d41b
XL
2187 pub fn new(interner: &I, interned: GoalData<I>) -> Self {
2188 let interned = I::intern_goal(interner, interned);
2189 Self { interned }
2190 }
2191
1b1a35ee 2192 /// Gets the interned goal.
f035d41b
XL
2193 pub fn interned(&self) -> &I::InternedGoal {
2194 &self.interned
2195 }
2196
1b1a35ee 2197 /// Gets the interned goal data.
f035d41b
XL
2198 pub fn data(&self, interner: &I) -> &GoalData<I> {
2199 interner.goal_data(&self.interned)
2200 }
2201
1b1a35ee 2202 /// Create a goal using a `forall` or `exists` quantifier.
f035d41b
XL
2203 pub fn quantify(
2204 self,
2205 interner: &I,
2206 kind: QuantifierKind,
2207 binders: VariableKinds<I>,
2208 ) -> Goal<I> {
2209 GoalData::Quantified(kind, Binders::new(binders, self)).intern(interner)
2210 }
2211
1b1a35ee 2212 /// Takes a goal `G` and turns it into `not { G }`.
f035d41b
XL
2213 pub fn negate(self, interner: &I) -> Self {
2214 GoalData::Not(self).intern(interner)
2215 }
2216
2217 /// Takes a goal `G` and turns it into `compatible { G }`.
2218 pub fn compatible(self, interner: &I) -> Self {
2219 // compatible { G } desugars into: forall<T> { if (Compatible, DownstreamType(T)) { G } }
2220 // This activates the compatible modality rules and introduces an anonymous downstream type
2221 GoalData::Quantified(
2222 QuantifierKind::ForAll,
2223 Binders::with_fresh_type_var(interner, |ty| {
2224 GoalData::Implies(
1b1a35ee 2225 ProgramClauses::from_iter(
f035d41b 2226 interner,
1b1a35ee 2227 vec![DomainGoal::Compatible, DomainGoal::DownstreamType(ty)],
f035d41b
XL
2228 ),
2229 self.shifted_in(interner),
2230 )
2231 .intern(interner)
2232 }),
2233 )
2234 .intern(interner)
2235 }
2236
1b1a35ee 2237 /// Create an implication goal that holds if the predicates are true.
f035d41b
XL
2238 pub fn implied_by(self, interner: &I, predicates: ProgramClauses<I>) -> Goal<I> {
2239 GoalData::Implies(predicates, self).intern(interner)
2240 }
2241
2242 /// True if this goal is "trivially true" -- i.e., no work is
2243 /// required to prove it.
2244 pub fn is_trivially_true(&self, interner: &I) -> bool {
2245 match self.data(interner) {
2246 GoalData::All(goals) => goals.is_empty(interner),
2247 _ => false,
2248 }
2249 }
2250}
2251
2252impl<I> Goal<I>
2253where
2254 I: Interner,
2255{
1b1a35ee 2256 /// Creates a single goal that only holds if a list of goals holds.
f035d41b
XL
2257 pub fn all<II>(interner: &I, iter: II) -> Self
2258 where
2259 II: IntoIterator<Item = Goal<I>>,
2260 {
2261 let mut iter = iter.into_iter();
2262 if let Some(goal0) = iter.next() {
2263 if let Some(goal1) = iter.next() {
2264 // More than one goal to prove
1b1a35ee 2265 let goals = Goals::from_iter(
f035d41b
XL
2266 interner,
2267 Some(goal0).into_iter().chain(Some(goal1)).chain(iter),
2268 );
2269 GoalData::All(goals).intern(interner)
2270 } else {
2271 // One goal to prove
2272 goal0
2273 }
2274 } else {
2275 // No goals to prove, always true
1b1a35ee 2276 GoalData::All(Goals::empty(interner)).intern(interner)
f035d41b
XL
2277 }
2278 }
2279}
2280
2281#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
2282/// A general goal; this is the full range of questions you can pose to Chalk.
2283pub enum GoalData<I: Interner> {
2284 /// Introduces a binding at depth 0, shifting other bindings up
2285 /// (deBruijn index).
2286 Quantified(QuantifierKind, Binders<Goal<I>>),
1b1a35ee
XL
2287
2288 /// A goal that holds given some clauses (like an if-statement).
f035d41b 2289 Implies(ProgramClauses<I>, Goal<I>),
1b1a35ee
XL
2290
2291 /// List of goals that all should hold.
f035d41b 2292 All(Goals<I>),
1b1a35ee
XL
2293
2294 /// Negation: the inner goal should not hold.
f035d41b
XL
2295 Not(Goal<I>),
2296
2297 /// Make two things equal; the rules for doing so are well known to the logic
2298 EqGoal(EqGoal<I>),
2299
2300 /// A "domain goal" indicates some base sort of goal that can be
2301 /// proven via program clauses
2302 DomainGoal(DomainGoal<I>),
2303
2304 /// Indicates something that cannot be proven to be true or false
2305 /// definitively. This can occur with overflow but also with
2306 /// unifications of skolemized variables like `forall<X,Y> { X = Y
2307 /// }`. Of course, that statement is false, as there exist types
2308 /// X, Y where `X = Y` is not true. But we treat it as "cannot
2309 /// prove" so that `forall<X,Y> { not { X = Y } }` also winds up
2310 /// as cannot prove.
1b1a35ee
XL
2311 CannotProve,
2312}
2313
2314impl<I: Interner> Copy for GoalData<I>
2315where
2316 I::InternedType: Copy,
2317 I::InternedLifetime: Copy,
2318 I::InternedGenericArg: Copy,
2319 I::InternedSubstitution: Copy,
2320 I::InternedGoal: Copy,
2321 I::InternedGoals: Copy,
2322 I::InternedProgramClauses: Copy,
2323 I::InternedVariableKinds: Copy,
2324{
f035d41b
XL
2325}
2326
2327impl<I: Interner> GoalData<I> {
1b1a35ee 2328 /// Create an interned goal.
f035d41b
XL
2329 pub fn intern(self, interner: &I) -> Goal<I> {
2330 Goal::new(interner, self)
2331 }
2332}
2333
1b1a35ee 2334/// Kinds of quantifiers in the logic, such as `forall` and `exists`.
f035d41b
XL
2335#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
2336pub enum QuantifierKind {
1b1a35ee
XL
2337 /// Universal quantifier `ForAll`.
2338 ///
2339 /// A formula with the universal quantifier `forall(x). P(x)` is satisfiable
2340 /// if and only if the subformula `P(x)` is true for all possible values for x.
f035d41b 2341 ForAll,
1b1a35ee
XL
2342
2343 /// Existential quantifier `Exists`.
2344 ///
2345 /// A formula with the existential quantifier `exists(x). P(x)` is satisfiable
2346 /// if and only if there exists at least one value for all possible values of x
2347 /// which satisfies the subformula `P(x)`.
2348
2349 /// In the context of chalk, the existential quantifier usually demands the
2350 /// existence of exactly one instance (i.e. type) that satisfies the formula
2351 /// (i.e. type constraints). More than one instance means that the result is ambiguous.
f035d41b
XL
2352 Exists,
2353}
2354
2355/// A constraint on lifetimes.
2356///
2357/// When we search for solutions within the trait system, we essentially ignore
2358/// lifetime constraints, instead gathering them up to return with our solution
2359/// for later checking. This allows for decoupling between type and region
2360/// checking in the compiler.
1b1a35ee 2361#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
f035d41b 2362pub enum Constraint<I: Interner> {
1b1a35ee
XL
2363 /// Outlives constraint `'a: 'b`, indicating that the value of `'a` must be
2364 /// a superset of the value of `'b`.
2365 LifetimeOutlives(Lifetime<I>, Lifetime<I>),
2366
2367 /// Type outlives constraint `T: 'a`, indicating that the type `T` must live
2368 /// at least as long as the value of `'a`.
2369 TypeOutlives(Ty<I>, Lifetime<I>),
f035d41b
XL
2370}
2371
1b1a35ee
XL
2372impl<I: Interner> Copy for Constraint<I>
2373where
2374 I::InternedLifetime: Copy,
2375 I::InternedType: Copy,
2376{
f035d41b
XL
2377}
2378
2379impl<I: Interner> Substitution<I> {
f035d41b
XL
2380 /// A substitution is an **identity substitution** if it looks
2381 /// like this
2382 ///
2383 /// ```text
2384 /// ?0 := ?0
2385 /// ?1 := ?1
2386 /// ?2 := ?2
2387 /// ...
2388 /// ```
2389 ///
2390 /// Basically, each value is mapped to a type or lifetime with its
2391 /// same index.
2392 pub fn is_identity_subst(&self, interner: &I) -> bool {
2393 self.iter(interner).zip(0..).all(|(generic_arg, index)| {
2394 let index_db = BoundVar::new(DebruijnIndex::INNERMOST, index);
2395 match generic_arg.data(interner) {
2396 GenericArgData::Ty(ty) => match ty.data(interner) {
2397 TyData::BoundVar(depth) => index_db == *depth,
2398 _ => false,
2399 },
2400 GenericArgData::Lifetime(lifetime) => match lifetime.data(interner) {
2401 LifetimeData::BoundVar(depth) => index_db == *depth,
2402 _ => false,
2403 },
2404 GenericArgData::Const(constant) => match &constant.data(interner).value {
2405 ConstValue::BoundVar(depth) => index_db == *depth,
2406 _ => false,
2407 },
2408 }
2409 })
2410 }
2411
1b1a35ee 2412 /// Apply the substitution to a value.
f035d41b
XL
2413 pub fn apply<T>(&self, value: &T, interner: &I) -> T::Result
2414 where
2415 T: Fold<I, I>,
2416 {
2417 value
2418 .fold_with(
2419 &mut &SubstFolder {
2420 interner,
2421 subst: self,
2422 },
2423 DebruijnIndex::INNERMOST,
2424 )
2425 .unwrap()
2426 }
2427}
2428
2429struct SubstFolder<'i, I: Interner> {
2430 interner: &'i I,
2431 subst: &'i Substitution<I>,
2432}
2433
2434impl<I: Interner> SubstFolder<'_, I> {
1b1a35ee 2435 /// Index into the list of parameters.
f035d41b
XL
2436 pub fn at(&self, index: usize) -> &GenericArg<I> {
2437 let interner = self.interner;
1b1a35ee 2438 &self.subst.as_slice(interner)[index]
f035d41b
XL
2439 }
2440}
2441
1b1a35ee 2442/// Convert a value to a list of parameters.
f035d41b 2443pub trait AsParameters<I: Interner> {
1b1a35ee 2444 /// Convert the current value to parameters.
f035d41b
XL
2445 fn as_parameters(&self, interner: &I) -> &[GenericArg<I>];
2446}
2447
2448impl<I: Interner> AsParameters<I> for Substitution<I> {
2449 #[allow(unreachable_code, unused_variables)]
2450 fn as_parameters(&self, interner: &I) -> &[GenericArg<I>] {
1b1a35ee 2451 self.as_slice(interner)
f035d41b
XL
2452 }
2453}
2454
2455impl<I: Interner> AsParameters<I> for [GenericArg<I>] {
2456 fn as_parameters(&self, _interner: &I) -> &[GenericArg<I>] {
2457 self
2458 }
2459}
2460
2461impl<I: Interner> AsParameters<I> for [GenericArg<I>; 1] {
2462 fn as_parameters(&self, _interner: &I) -> &[GenericArg<I>] {
2463 self
2464 }
2465}
2466
2467impl<I: Interner> AsParameters<I> for Vec<GenericArg<I>> {
2468 fn as_parameters(&self, _interner: &I) -> &[GenericArg<I>] {
2469 self
2470 }
2471}
2472
2473impl<T, I: Interner> AsParameters<I> for &T
2474where
2475 T: ?Sized + AsParameters<I>,
2476{
2477 fn as_parameters(&self, interner: &I) -> &[GenericArg<I>] {
2478 T::as_parameters(self, interner)
2479 }
2480}
2481
1b1a35ee
XL
2482/// Utility for converting a list of all the binders into scope
2483/// into references to those binders. Simply pair the binders with
2484/// the indices, and invoke `to_generic_arg()` on the `(binder,
2485/// index)` pair. The result will be a reference to a bound
2486/// variable of appropriate kind at the corresponding index.
f035d41b 2487pub trait ToGenericArg<I: Interner> {
1b1a35ee 2488 /// Converts the binders in scope to references to those binders.
f035d41b
XL
2489 fn to_generic_arg(&self, interner: &I) -> GenericArg<I> {
2490 self.to_generic_arg_at_depth(interner, DebruijnIndex::INNERMOST)
2491 }
2492
1b1a35ee 2493 /// Converts the binders at the specified depth to references to those binders.
f035d41b
XL
2494 fn to_generic_arg_at_depth(&self, interner: &I, debruijn: DebruijnIndex) -> GenericArg<I>;
2495}
2496
1b1a35ee 2497impl<'a, I: Interner> ToGenericArg<I> for (usize, &'a VariableKind<I>) {
f035d41b 2498 fn to_generic_arg_at_depth(&self, interner: &I, debruijn: DebruijnIndex) -> GenericArg<I> {
1b1a35ee 2499 let &(index, binder) = self;
f035d41b
XL
2500 let bound_var = BoundVar::new(debruijn, index);
2501 binder.to_bound_variable(interner, bound_var)
2502 }
2503}
2504
2505impl<'i, I: Interner> Folder<'i, I> for &SubstFolder<'i, I> {
2506 fn as_dyn(&mut self) -> &mut dyn Folder<'i, I> {
2507 self
2508 }
2509
2510 fn fold_free_var_ty(
2511 &mut self,
2512 bound_var: BoundVar,
2513 outer_binder: DebruijnIndex,
2514 ) -> Fallible<Ty<I>> {
2515 assert_eq!(bound_var.debruijn, DebruijnIndex::INNERMOST);
2516 let ty = self.at(bound_var.index);
2517 let ty = ty.assert_ty_ref(self.interner());
2518 Ok(ty.shifted_in_from(self.interner(), outer_binder))
2519 }
2520
2521 fn fold_free_var_lifetime(
2522 &mut self,
2523 bound_var: BoundVar,
2524 outer_binder: DebruijnIndex,
2525 ) -> Fallible<Lifetime<I>> {
2526 assert_eq!(bound_var.debruijn, DebruijnIndex::INNERMOST);
2527 let l = self.at(bound_var.index);
2528 let l = l.assert_lifetime_ref(self.interner());
2529 Ok(l.shifted_in_from(self.interner(), outer_binder))
2530 }
2531
2532 fn fold_free_var_const(
2533 &mut self,
2534 _ty: &Ty<I>,
2535 bound_var: BoundVar,
2536 outer_binder: DebruijnIndex,
2537 ) -> Fallible<Const<I>> {
2538 assert_eq!(bound_var.debruijn, DebruijnIndex::INNERMOST);
2539 let c = self.at(bound_var.index);
2540 let c = c.assert_const_ref(self.interner());
2541 Ok(c.shifted_in_from(self.interner(), outer_binder))
2542 }
2543
2544 fn interner(&self) -> &'i I {
2545 self.interner
2546 }
2547
2548 fn target_interner(&self) -> &'i I {
2549 self.interner()
2550 }
2551}
2552
1b1a35ee
XL
2553macro_rules! interned_slice {
2554 ($seq:ident, $data:ident => $elem:ty, $intern:ident => $interned:ident) => {
2555 /// List of interned elements.
2556 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
2557 pub struct $seq<I: Interner> {
2558 interned: I::$interned,
2559 }
2560
2561 impl<I: Interner> $seq<I> {
2562 /// Get the interned elements.
2563 pub fn interned(&self) -> &I::$interned {
2564 &self.interned
2565 }
2566 }
2567
2568 impl<I: Interner> $seq<I> {
2569 /// Tries to create a sequence using an iterator of element-like things.
2570 pub fn from_fallible<E>(
2571 interner: &I,
2572 elements: impl IntoIterator<Item = Result<impl CastTo<$elem>, E>>,
2573 ) -> Result<Self, E> {
2574 Ok(Self {
2575 interned: I::$intern(interner, elements.into_iter().casted(interner))?,
2576 })
2577 }
2578
2579 /// Returns a slice containing the elements.
2580 pub fn as_slice(&self, interner: &I) -> &[$elem] {
2581 Interner::$data(interner, &self.interned)
2582 }
2583
2584 /// Create a sequence from elements
2585 pub fn from_iter(
2586 interner: &I,
2587 elements: impl IntoIterator<Item = impl CastTo<$elem>>,
2588 ) -> Self {
2589 Self::from_fallible(
2590 interner,
2591 elements
2592 .into_iter()
2593 .map(|el| -> Result<$elem, ()> { Ok(el.cast(interner)) }),
2594 )
2595 .unwrap()
2596 }
2597
2598 /// Index into the sequence.
2599 pub fn at(&self, interner: &I, index: usize) -> &$elem {
2600 &self.as_slice(interner)[index]
2601 }
2602
2603 /// Create a sequence from a single element.
2604 pub fn from1(interner: &I, element: impl CastTo<$elem>) -> Self {
2605 Self::from_iter(interner, Some(element))
2606 }
2607
2608 /// Create an empty sequence.
2609 pub fn empty(interner: &I) -> Self {
2610 Self::from_iter(interner, None::<$elem>)
2611 }
2612
2613 /// Check whether this is an empty sequence.
2614 pub fn is_empty(&self, interner: &I) -> bool {
2615 self.as_slice(interner).is_empty()
2616 }
2617
2618 /// Get an iterator over the elements of the sequence.
2619 pub fn iter(&self, interner: &I) -> std::slice::Iter<'_, $elem> {
2620 self.as_slice(interner).iter()
2621 }
2622
2623 /// Get the length of the sequence.
2624 pub fn len(&self, interner: &I) -> usize {
2625 self.as_slice(interner).len()
2626 }
2627 }
2628 };
2629}
2630
2631interned_slice!(
2632 QuantifiedWhereClauses,
2633 quantified_where_clauses_data => QuantifiedWhereClause<I>,
2634 intern_quantified_where_clauses => InternedQuantifiedWhereClauses
2635);
2636
2637interned_slice!(
2638 ProgramClauses,
2639 program_clauses_data => ProgramClause<I>,
2640 intern_program_clauses => InternedProgramClauses
2641);
2642
2643interned_slice!(
2644 VariableKinds,
2645 variable_kinds_data => VariableKind<I>,
2646 intern_generic_arg_kinds => InternedVariableKinds
2647);
2648
2649interned_slice!(
2650 CanonicalVarKinds,
2651 canonical_var_kinds_data => CanonicalVarKind<I>,
2652 intern_canonical_var_kinds => InternedCanonicalVarKinds
2653);
2654
2655interned_slice!(Goals, goals_data => Goal<I>, intern_goals => InternedGoals);
2656
2657interned_slice!(
2658 Constraints,
2659 constraints_data => InEnvironment<Constraint<I>>,
2660 intern_constraints => InternedConstraints
2661);
2662
2663interned_slice!(
2664 Substitution,
2665 substitution_data => GenericArg<I>,
2666 intern_substitution => InternedSubstitution
2667);
2668
f035d41b
XL
2669/// Combines a substitution (`subst`) with a set of region constraints
2670/// (`constraints`). This represents the result of a query; the
2671/// substitution stores the values for the query's unknown variables,
2672/// and the constraints represents any region constraints that must
2673/// additionally be solved.
2674#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit, HasInterner)]
2675pub struct ConstrainedSubst<I: Interner> {
1b1a35ee
XL
2676 /// The substitution that is being constrained.
2677 ///
2678 /// NB: The `is_trivial` routine relies on the fact that `subst` is folded first.
2679 pub subst: Substitution<I>,
2680
2681 /// Region constraints that constrain the substitution.
2682 pub constraints: Constraints<I>,
f035d41b
XL
2683}
2684
1b1a35ee 2685/// The resulting substitution after solving a goal.
f035d41b
XL
2686#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit, HasInterner)]
2687pub struct AnswerSubst<I: Interner> {
1b1a35ee
XL
2688 /// The substitution result.
2689 ///
2690 /// NB: The `is_trivial` routine relies on the fact that `subst` is folded first.
2691 pub subst: Substitution<I>,
2692
2693 /// List of constraints that are part of the answer.
2694 pub constraints: Constraints<I>,
2695
2696 /// Delayed subgoals, used when the solver answered with an (incomplete) `Answer` (instead of a `CompleteAnswer`).
f035d41b
XL
2697 pub delayed_subgoals: Vec<InEnvironment<Goal<I>>>,
2698}