summaryrefslogtreecommitdiffstats
path: root/vendor/chalk-solve-0.87.0/src/rust_ir.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/chalk-solve-0.87.0/src/rust_ir.rs')
-rw-r--r--vendor/chalk-solve-0.87.0/src/rust_ir.rs752
1 files changed, 752 insertions, 0 deletions
diff --git a/vendor/chalk-solve-0.87.0/src/rust_ir.rs b/vendor/chalk-solve-0.87.0/src/rust_ir.rs
new file mode 100644
index 000000000..935a29032
--- /dev/null
+++ b/vendor/chalk-solve-0.87.0/src/rust_ir.rs
@@ -0,0 +1,752 @@
+//! Contains the definition for the "Rust IR" -- this is basically a "lowered"
+//! version of the AST, roughly corresponding to [the HIR] in the Rust
+//! compiler.
+
+use chalk_derive::{HasInterner, TypeFoldable, TypeVisitable};
+use chalk_ir::cast::Cast;
+use chalk_ir::fold::shift::Shift;
+use chalk_ir::interner::Interner;
+use chalk_ir::{
+ try_break, visit::TypeVisitable, AdtId, AliasEq, AliasTy, AssocTypeId, Binders, DebruijnIndex,
+ FnDefId, GenericArg, ImplId, OpaqueTyId, ProjectionTy, QuantifiedWhereClause, Substitution,
+ ToGenericArg, TraitId, TraitRef, Ty, TyKind, VariableKind, WhereClause, WithKind,
+};
+use std::iter;
+use std::ops::ControlFlow;
+
+/// Identifier for an "associated type value" found in some impl.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct AssociatedTyValueId<I: Interner>(pub I::DefId);
+
+chalk_ir::id_visit!(AssociatedTyValueId);
+chalk_ir::id_fold!(AssociatedTyValueId);
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeVisitable)]
+pub struct ImplDatum<I: Interner> {
+ pub polarity: Polarity,
+ pub binders: Binders<ImplDatumBound<I>>,
+ pub impl_type: ImplType,
+ pub associated_ty_value_ids: Vec<AssociatedTyValueId<I>>,
+}
+
+impl<I: Interner> ImplDatum<I> {
+ pub fn is_positive(&self) -> bool {
+ self.polarity.is_positive()
+ }
+
+ pub fn trait_id(&self) -> TraitId<I> {
+ self.binders.skip_binders().trait_ref.trait_id
+ }
+
+ pub fn self_type_adt_id(&self, interner: I) -> Option<AdtId<I>> {
+ match self
+ .binders
+ .skip_binders()
+ .trait_ref
+ .self_type_parameter(interner)
+ .kind(interner)
+ {
+ TyKind::Adt(id, _) => Some(*id),
+ _ => None,
+ }
+ }
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, HasInterner, TypeFoldable, TypeVisitable)]
+pub struct ImplDatumBound<I: Interner> {
+ pub trait_ref: TraitRef<I>,
+ pub where_clauses: Vec<QuantifiedWhereClause<I>>,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+pub enum ImplType {
+ Local,
+ External,
+}
+
+chalk_ir::const_visit!(ImplType);
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct DefaultImplDatum<I: Interner> {
+ pub binders: Binders<DefaultImplDatumBound<I>>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, HasInterner)]
+pub struct DefaultImplDatumBound<I: Interner> {
+ pub trait_ref: TraitRef<I>,
+ pub accessible_tys: Vec<Ty<I>>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeVisitable)]
+pub struct AdtDatum<I: Interner> {
+ pub binders: Binders<AdtDatumBound<I>>,
+ pub id: AdtId<I>,
+ pub flags: AdtFlags,
+ pub kind: AdtKind,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
+pub enum AdtKind {
+ Struct,
+ Enum,
+ Union,
+}
+
+chalk_ir::const_visit!(AdtKind);
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner, TypeVisitable)]
+pub struct AdtDatumBound<I: Interner> {
+ pub variants: Vec<AdtVariantDatum<I>>,
+ pub where_clauses: Vec<QuantifiedWhereClause<I>>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner, TypeVisitable)]
+pub struct AdtVariantDatum<I: Interner> {
+ pub fields: Vec<Ty<I>>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct AdtFlags {
+ pub upstream: bool,
+ pub fundamental: bool,
+ pub phantom_data: bool,
+}
+
+chalk_ir::const_visit!(AdtFlags);
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct AdtRepr<I: Interner> {
+ pub c: bool,
+ pub packed: bool,
+ pub int: Option<chalk_ir::Ty<I>>,
+}
+
+/// Information about the size and alignment of an ADT.
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct AdtSizeAlign {
+ one_zst: bool,
+}
+
+impl AdtSizeAlign {
+ pub fn from_one_zst(one_zst: bool) -> AdtSizeAlign {
+ AdtSizeAlign { one_zst }
+ }
+
+ pub fn one_zst(&self) -> bool {
+ self.one_zst
+ }
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+/// A rust intermediate represention (rust_ir) of a function definition/declaration.
+/// For example, in the following rust code:
+///
+/// ```ignore
+/// fn foo<T>() -> i32 where T: Eq;
+/// ```
+///
+/// This would represent the declaration of `foo`.
+///
+/// Note this is distinct from a function pointer, which points to
+/// a function with a given type signature, whereas this represents
+/// a specific function definition.
+pub struct FnDefDatum<I: Interner> {
+ pub id: FnDefId<I>,
+ pub sig: chalk_ir::FnSig<I>,
+ pub binders: Binders<FnDefDatumBound<I>>,
+}
+
+/// Avoids visiting `I::FnAbi`
+impl<I: Interner> TypeVisitable<I> for FnDefDatum<I> {
+ fn visit_with<B>(
+ &self,
+ visitor: &mut dyn chalk_ir::visit::TypeVisitor<I, BreakTy = B>,
+ outer_binder: DebruijnIndex,
+ ) -> ControlFlow<B> {
+ try_break!(self.id.visit_with(visitor, outer_binder));
+ self.binders.visit_with(visitor, outer_binder)
+ }
+}
+
+/// Represents the inputs and outputs on a `FnDefDatum`. This is split
+/// from the where clauses, since these can contain bound lifetimes.
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner, TypeVisitable)]
+pub struct FnDefInputsAndOutputDatum<I: Interner> {
+ /// Types of the function's arguments
+ /// ```ignore
+ /// fn foo<T>(bar: i32, baz: T);
+ /// ^^^ ^
+ /// ```
+ ///
+ pub argument_types: Vec<Ty<I>>,
+ /// Return type of the function
+ /// ```ignore
+ /// fn foo<T>() -> i32;
+ /// ^^^
+ /// ```
+ pub return_type: Ty<I>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner, TypeVisitable)]
+/// Represents the bounds on a `FnDefDatum`, including
+/// the function definition's type signature and where clauses.
+pub struct FnDefDatumBound<I: Interner> {
+ /// Inputs and outputs defined on a function
+ /// These are needed for late-bound regions in rustc. For example the
+ /// lifetime `'a` in
+ /// ```ignore
+ /// fn foo<'a, T>(&'a T);
+ /// ^^
+ /// ```
+ /// Rustc doesn't pass in late-bound the regions in substs, but the inputs
+ /// and outputs may use them. `where_clauses` don't need an extra set of
+ /// `Binders`, since any lifetimes found in where clauses are not late-bound.
+ ///
+ /// For more information, see [this rustc-dev-guide chapter](https://rustc-dev-guide.rust-lang.org/early-late-bound.html).
+ pub inputs_and_output: Binders<FnDefInputsAndOutputDatum<I>>,
+
+ /// Where clauses defined on the function
+ /// ```ignore
+ /// fn foo<T>() where T: Eq;
+ /// ^^^^^^^^^^^
+ /// ```
+ pub where_clauses: Vec<QuantifiedWhereClause<I>>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+// FIXME: unignore the doctest below when GATs hit stable.
+/// A rust intermediate representation (rust_ir) of a Trait Definition. For
+/// example, given the following rust code:
+///
+/// ```ignore
+/// use std::fmt::Debug;
+///
+/// trait Foo<T>
+/// where
+/// T: Debug,
+/// {
+/// type Bar<U>;
+/// }
+/// ```
+///
+/// This would represent the `trait Foo` declaration. Note that the details of
+/// the trait members (e.g., the associated type declaration (`type Bar<U>`) are
+/// not contained in this type, and are represented separately (e.g., in
+/// [`AssociatedTyDatum`]).
+///
+/// Not to be confused with the rust_ir for a Trait Implementation, which is
+/// represented by [`ImplDatum`]
+///
+/// [`ImplDatum`]: struct.ImplDatum.html
+/// [`AssociatedTyDatum`]: struct.AssociatedTyDatum.html
+#[derive(TypeVisitable)]
+pub struct TraitDatum<I: Interner> {
+ pub id: TraitId<I>,
+
+ pub binders: Binders<TraitDatumBound<I>>,
+
+ /// "Flags" indicate special kinds of traits, like auto traits.
+ /// In Rust syntax these are represented in different ways, but in
+ /// chalk we add annotations like `#[auto]`.
+ pub flags: TraitFlags,
+
+ pub associated_ty_ids: Vec<AssocTypeId<I>>,
+
+ /// If this is a well-known trait, which one? If `None`, this is a regular,
+ /// user-defined trait.
+ pub well_known: Option<WellKnownTrait>,
+}
+
+/// A list of the traits that are "well known" to chalk, which means that
+/// the chalk-solve crate has special, hard-coded impls for them.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
+pub enum WellKnownTrait {
+ Sized,
+ Copy,
+ Clone,
+ Drop,
+ /// The trait `FnOnce<Args>` - the generic argument `Args` is always a tuple
+ /// corresponding to the arguments of a function implementing this trait.
+ /// E.g. `fn(u8, bool): FnOnce<(u8, bool)>`
+ FnOnce,
+ FnMut,
+ Fn,
+ Unsize,
+ Unpin,
+ CoerceUnsized,
+ DiscriminantKind,
+ Generator,
+ DispatchFromDyn,
+ Tuple,
+}
+
+chalk_ir::const_visit!(WellKnownTrait);
+
+impl<I: Interner> TraitDatum<I> {
+ pub fn is_auto_trait(&self) -> bool {
+ self.flags.auto
+ }
+
+ pub fn is_non_enumerable_trait(&self) -> bool {
+ self.flags.non_enumerable
+ }
+
+ pub fn is_coinductive_trait(&self) -> bool {
+ self.flags.coinductive
+ }
+
+ /// Gives access to the where clauses of the trait, quantified over the type parameters of the trait:
+ ///
+ /// ```ignore
+ /// trait Foo<T> where T: Debug { }
+ /// ^^^^^^^^^^^^^^
+ /// ```
+ pub fn where_clauses(&self) -> Binders<&Vec<QuantifiedWhereClause<I>>> {
+ self.binders.as_ref().map(|td| &td.where_clauses)
+ }
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, HasInterner, TypeVisitable)]
+pub struct TraitDatumBound<I: Interner> {
+ /// Where clauses defined on the trait:
+ ///
+ /// ```ignore
+ /// trait Foo<T> where T: Debug { }
+ /// ^^^^^^^^^^^^^^
+ /// ```
+ pub where_clauses: Vec<QuantifiedWhereClause<I>>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct TraitFlags {
+ /// An "auto trait" is one that is "automatically implemented" for every
+ /// struct, so long as no explicit impl is given.
+ ///
+ /// Examples are `Send` and `Sync`.
+ pub auto: bool,
+
+ pub marker: bool,
+
+ /// Indicate that a trait is defined upstream (in a dependency), used during
+ /// coherence checking.
+ pub upstream: bool,
+
+ /// A fundamental trait is a trait where adding an impl for an existing type
+ /// is considered a breaking change. Examples of fundamental traits are the
+ /// closure traits like `Fn` and `FnMut`.
+ ///
+ /// As of this writing (2020-03-27), fundamental traits are declared by the
+ /// unstable `#[fundamental]` attribute in rustc, and hence cannot appear
+ /// outside of the standard library.
+ pub fundamental: bool,
+
+ /// Indicates that chalk cannot list all of the implementations of the given
+ /// trait, likely because it is a publicly exported trait in a library.
+ ///
+ /// Currently (2020-03-27) rustc and rust-analyzer mark all traits as
+ /// non_enumerable, and in the future it may become the only option.
+ pub non_enumerable: bool,
+
+ pub coinductive: bool,
+}
+
+chalk_ir::const_visit!(TraitFlags);
+
+/// An inline bound, e.g. `: Foo<K>` in `impl<K, T: Foo<K>> SomeType<T>`.
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
+pub enum InlineBound<I: Interner> {
+ TraitBound(TraitBound<I>),
+ AliasEqBound(AliasEqBound<I>),
+}
+
+#[allow(type_alias_bounds)]
+pub type QuantifiedInlineBound<I: Interner> = Binders<InlineBound<I>>;
+
+pub trait IntoWhereClauses<I: Interner> {
+ type Output;
+
+ fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<Self::Output>;
+}
+
+impl<I: Interner> IntoWhereClauses<I> for InlineBound<I> {
+ type Output = WhereClause<I>;
+
+ /// Applies the `InlineBound` to `self_ty` and lowers to a
+ /// [`chalk_ir::DomainGoal`].
+ ///
+ /// Because an `InlineBound` does not know anything about what it's binding,
+ /// you must provide that type as `self_ty`.
+ fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<WhereClause<I>> {
+ match self {
+ InlineBound::TraitBound(b) => b.into_where_clauses(interner, self_ty),
+ InlineBound::AliasEqBound(b) => b.into_where_clauses(interner, self_ty),
+ }
+ }
+}
+
+impl<I: Interner> IntoWhereClauses<I> for QuantifiedInlineBound<I> {
+ type Output = QuantifiedWhereClause<I>;
+
+ fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<QuantifiedWhereClause<I>> {
+ let self_ty = self_ty.shifted_in(interner);
+ self.map_ref(|b| b.into_where_clauses(interner, self_ty))
+ .into_iter()
+ .collect()
+ }
+}
+
+/// Represents a trait bound on e.g. a type or type parameter.
+/// Does not know anything about what it's binding.
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
+pub struct TraitBound<I: Interner> {
+ pub trait_id: TraitId<I>,
+ pub args_no_self: Vec<GenericArg<I>>,
+}
+
+impl<I: Interner> TraitBound<I> {
+ fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<WhereClause<I>> {
+ let trait_ref = self.as_trait_ref(interner, self_ty);
+ vec![WhereClause::Implemented(trait_ref)]
+ }
+
+ pub fn as_trait_ref(&self, interner: I, self_ty: Ty<I>) -> TraitRef<I> {
+ TraitRef {
+ trait_id: self.trait_id,
+ substitution: Substitution::from_iter(
+ interner,
+ iter::once(self_ty.cast(interner)).chain(self.args_no_self.iter().cloned()),
+ ),
+ }
+ }
+}
+
+/// Represents an alias equality bound on e.g. a type or type parameter.
+/// Does not know anything about what it's binding.
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
+pub struct AliasEqBound<I: Interner> {
+ pub trait_bound: TraitBound<I>,
+ pub associated_ty_id: AssocTypeId<I>,
+ /// Does not include trait parameters.
+ pub parameters: Vec<GenericArg<I>>,
+ pub value: Ty<I>,
+}
+
+impl<I: Interner> AliasEqBound<I> {
+ fn into_where_clauses(&self, interner: I, self_ty: Ty<I>) -> Vec<WhereClause<I>> {
+ let trait_ref = self.trait_bound.as_trait_ref(interner, self_ty);
+
+ let substitution = Substitution::from_iter(
+ interner,
+ self.parameters
+ .iter()
+ .cloned()
+ .chain(trait_ref.substitution.iter(interner).cloned()),
+ );
+
+ vec![
+ WhereClause::Implemented(trait_ref),
+ WhereClause::AliasEq(AliasEq {
+ alias: AliasTy::Projection(ProjectionTy {
+ associated_ty_id: self.associated_ty_id,
+ substitution,
+ }),
+ ty: self.value.clone(),
+ }),
+ ]
+ }
+}
+
+pub trait Anonymize<I: Interner> {
+ /// Utility function that converts from a list of generic arguments
+ /// which *have* associated data (`WithKind<I, T>`) to a list of
+ /// "anonymous" generic parameters that just preserves their
+ /// kinds (`VariableKind<I>`). Often convenient in lowering.
+ fn anonymize(&self) -> Vec<VariableKind<I>>;
+}
+
+impl<I: Interner, T> Anonymize<I> for [WithKind<I, T>] {
+ fn anonymize(&self) -> Vec<VariableKind<I>> {
+ self.iter().map(|pk| pk.kind.clone()).collect()
+ }
+}
+
+/// Represents an associated type declaration found inside of a trait:
+///
+/// ```notrust
+/// trait Foo<P1..Pn> { // P0 is Self
+/// type Bar<Pn..Pm>: [bounds]
+/// where
+/// [where_clauses];
+/// }
+/// ```
+///
+/// The meaning of each of these parts:
+///
+/// * The *parameters* `P0...Pm` are all in scope for this associated type.
+/// * The *bounds* `bounds` are things that the impl must prove to be true.
+/// * The *where clauses* `where_clauses` are things that the impl can *assume* to be true
+/// (but which projectors must prove).
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct AssociatedTyDatum<I: Interner> {
+ /// The trait this associated type is defined in.
+ pub trait_id: TraitId<I>,
+
+ /// The ID of this associated type
+ pub id: AssocTypeId<I>,
+
+ /// Name of this associated type.
+ pub name: I::Identifier,
+
+ /// These binders represent the `P0...Pm` variables. The binders
+ /// are in the order `[Pn..Pm; P0..Pn]`. That is, the variables
+ /// from `Bar` come first (corresponding to the de bruijn concept
+ /// that "inner" binders are lower indices, although within a
+ /// given binder we do not have an ordering).
+ pub binders: Binders<AssociatedTyDatumBound<I>>,
+}
+
+// Manual implementation to avoid I::Identifier type.
+impl<I: Interner> TypeVisitable<I> for AssociatedTyDatum<I> {
+ fn visit_with<B>(
+ &self,
+ visitor: &mut dyn chalk_ir::visit::TypeVisitor<I, BreakTy = B>,
+ outer_binder: DebruijnIndex,
+ ) -> ControlFlow<B> {
+ try_break!(self.trait_id.visit_with(visitor, outer_binder));
+ try_break!(self.id.visit_with(visitor, outer_binder));
+ self.binders.visit_with(visitor, outer_binder)
+ }
+}
+
+/// Encodes the parts of `AssociatedTyDatum` where the parameters
+/// `P0..Pm` are in scope (`bounds` and `where_clauses`).
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
+pub struct AssociatedTyDatumBound<I: Interner> {
+ /// Bounds on the associated type itself.
+ ///
+ /// These must be proven by the implementer, for all possible parameters that
+ /// would result in a well-formed projection.
+ pub bounds: Vec<QuantifiedInlineBound<I>>,
+
+ /// Where clauses that must hold for the projection to be well-formed.
+ pub where_clauses: Vec<QuantifiedWhereClause<I>>,
+}
+
+impl<I: Interner> AssociatedTyDatum<I> {
+ /// Returns the associated ty's bounds applied to the projection type, e.g.:
+ ///
+ /// ```notrust
+ /// Implemented(<?0 as Foo>::Item<?1>: Sized)
+ /// ```
+ ///
+ /// these quantified where clauses are in the scope of the
+ /// `binders` field.
+ pub fn bounds_on_self(&self, interner: I) -> Vec<QuantifiedWhereClause<I>> {
+ let (binders, assoc_ty_datum) = self.binders.as_ref().into();
+ // Create a list `P0...Pn` of references to the binders in
+ // scope for this associated type:
+ let substitution = Substitution::from_iter(
+ interner,
+ binders
+ .iter(interner)
+ .enumerate()
+ .map(|p| p.to_generic_arg(interner)),
+ );
+
+ // The self type will be `<P0 as Foo<P1..Pn>>::Item<Pn..Pm>` etc
+ let self_ty = TyKind::Alias(AliasTy::Projection(ProjectionTy {
+ associated_ty_id: self.id,
+ substitution,
+ }))
+ .intern(interner);
+
+ // Now use that as the self type for the bounds, transforming
+ // something like `type Bar<Pn..Pm>: Debug` into
+ //
+ // ```
+ // <P0 as Foo<P1..Pn>>::Item<Pn..Pm>: Debug
+ // ```
+ assoc_ty_datum
+ .bounds
+ .iter()
+ .flat_map(|b| b.into_where_clauses(interner, self_ty.clone()))
+ .collect()
+ }
+}
+
+/// Represents the *value* of an associated type that is assigned
+/// from within some impl.
+///
+/// ```ignore
+/// impl Iterator for Foo {
+/// type Item = XXX; // <-- represents this line!
+/// }
+/// ```
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
+pub struct AssociatedTyValue<I: Interner> {
+ /// Impl in which this associated type value is found. You might
+ /// need to look at this to find the generic parameters defined on
+ /// the impl, for example.
+ ///
+ /// ```ignore
+ /// impl Iterator for Foo { // <-- refers to this impl
+ /// type Item = XXX; // <-- (where this is self)
+ /// }
+ /// ```
+ pub impl_id: ImplId<I>,
+
+ /// Associated type being defined.
+ ///
+ /// ```ignore
+ /// impl Iterator for Foo {
+ /// type Item = XXX; // <-- (where this is self)
+ /// }
+ /// ...
+ /// trait Iterator {
+ /// type Item; // <-- refers to this declaration here!
+ /// }
+ /// ```
+ pub associated_ty_id: AssocTypeId<I>,
+
+ /// Additional binders declared on the associated type itself,
+ /// beyond those from the impl. This would be empty for normal
+ /// associated types, but non-empty for generic associated types.
+ ///
+ /// ```ignore
+ /// impl<T> Iterable for Vec<T> {
+ /// type Iter<'a> = vec::Iter<'a, T>;
+ /// // ^^^^ refers to these generics here
+ /// }
+ /// ```
+ pub value: Binders<AssociatedTyValueBound<I>>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)]
+pub struct AssociatedTyValueBound<I: Interner> {
+ /// Type that we normalize to. The X in `type Foo<'a> = X`.
+ pub ty: Ty<I>,
+}
+
+/// Represents the bounds for an `impl Trait` type.
+///
+/// ```ignore
+/// opaque type T: A + B = HiddenTy;
+/// ```
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
+pub struct OpaqueTyDatum<I: Interner> {
+ /// The placeholder `!T` that corresponds to the opaque type `T`.
+ pub opaque_ty_id: OpaqueTyId<I>,
+
+ /// The type bound to when revealed.
+ pub bound: Binders<OpaqueTyDatumBound<I>>,
+}
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner, TypeVisitable)]
+pub struct OpaqueTyDatumBound<I: Interner> {
+ /// Trait bounds for the opaque type. These are bounds that the hidden type must meet.
+ pub bounds: Binders<Vec<QuantifiedWhereClause<I>>>,
+ /// Where clauses that inform well-formedness conditions for the opaque type.
+ /// These are conditions on the generic parameters of the opaque type which must be true
+ /// for a reference to the opaque type to be well-formed.
+ pub where_clauses: Binders<Vec<QuantifiedWhereClause<I>>>,
+}
+
+// The movability of a generator: whether a generator contains self-references,
+// causing it to be !Unpin
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub enum Movability {
+ Static,
+ Movable,
+}
+chalk_ir::copy_fold!(Movability);
+
+/// Represents a generator type.
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner)]
+pub struct GeneratorDatum<I: Interner> {
+ // Can the generator be moved (is Unpin or not)
+ pub movability: Movability,
+ /// All of the nested types for this generator. The `Binder`
+ /// represents the types and lifetimes that this generator is generic over -
+ /// this behaves in the same way as `AdtDatum.binders`
+ pub input_output: Binders<GeneratorInputOutputDatum<I>>,
+}
+
+/// The nested types for a generator. This always appears inside a `GeneratorDatum`
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner)]
+pub struct GeneratorInputOutputDatum<I: Interner> {
+ /// The generator resume type - a value of this type
+ /// is supplied by the caller when resuming the generator.
+ /// Currently, this plays no rule in goal resolution.
+ pub resume_type: Ty<I>,
+ /// The generator yield type - a value of this type
+ /// is supplied by the generator during a yield.
+ /// Currently, this plays no role in goal resolution.
+ pub yield_type: Ty<I>,
+ /// The generator return type - a value of this type
+ /// is supplied by the generator when it returns.
+ /// Currently, this plays no role in goal resolution
+ pub return_type: Ty<I>,
+ /// The upvars stored by the generator. These represent
+ /// types captured from the generator's environment,
+ /// and are stored across all yields. These types (along with the witness types)
+ /// are considered 'constituent types' for the purposes of determining auto trait
+ /// implementations - that its, a generator impls an auto trait A
+ /// iff all of its constituent types implement A.
+ pub upvars: Vec<Ty<I>>,
+}
+
+/// The generator witness data. Each `GeneratorId` has both a `GeneratorDatum`
+/// and a `GeneratorWitnessDatum` - these represent two distinct types in Rust.
+/// `GeneratorWitnessDatum` is logically 'inside' a generator - this only
+/// matters when we treat the witness type as a 'constituent type for the
+/// purposes of determining auto trait implementations.
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner)]
+pub struct GeneratorWitnessDatum<I: Interner> {
+ /// This binder is identical to the `input_output` binder in `GeneratorWitness` -
+ /// it binds the types and lifetimes that the generator is generic over.
+ /// There is an additional binder inside `GeneratorWitnessExistential`, which
+ /// is treated specially.
+ pub inner_types: Binders<GeneratorWitnessExistential<I>>,
+}
+
+/// The generator witness types, together with existentially bound lifetimes.
+/// Each 'witness type' represents a type stored inside the generator across
+/// a yield. When a generator type is constructed, the precise region relationships
+/// found in the generator body are erased. As a result, we are left with existential
+/// lifetimes - each type is parameterized over *some* lifetimes, but we do not
+/// know their precise values.
+///
+/// Unlike the binder in `GeneratorWitnessDatum`, this `Binder` never gets substituted
+/// via an `Ty`. Instead, we handle this `Binders` specially when determining
+/// auto trait impls. See `push_auto_trait_impls_generator_witness` for more details.
+#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner)]
+pub struct GeneratorWitnessExistential<I: Interner> {
+ pub types: Binders<Vec<Ty<I>>>,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
+pub enum Polarity {
+ Positive,
+ Negative,
+}
+
+chalk_ir::const_visit!(Polarity);
+
+impl Polarity {
+ pub fn is_positive(&self) -> bool {
+ match *self {
+ Polarity::Positive => true,
+ Polarity::Negative => false,
+ }
+ }
+}
+
+/// Indicates the "most permissive" Fn-like trait that the closure implements.
+/// If the closure kind for a closure is FnMut, for example, then the closure
+/// implements FnMut and FnOnce.
+#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
+pub enum ClosureKind {
+ Fn,
+ FnMut,
+ FnOnce,
+}