From 64d98f8ee037282c35007b64c2649055c56af1db Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:03 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- vendor/chalk-solve-0.87.0/src/rust_ir.rs | 752 +++++++++++++++++++++++++++++++ 1 file changed, 752 insertions(+) create mode 100644 vendor/chalk-solve-0.87.0/src/rust_ir.rs (limited to 'vendor/chalk-solve-0.87.0/src/rust_ir.rs') 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(pub I::DefId); + +chalk_ir::id_visit!(AssociatedTyValueId); +chalk_ir::id_fold!(AssociatedTyValueId); + +#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeVisitable)] +pub struct ImplDatum { + pub polarity: Polarity, + pub binders: Binders>, + pub impl_type: ImplType, + pub associated_ty_value_ids: Vec>, +} + +impl ImplDatum { + pub fn is_positive(&self) -> bool { + self.polarity.is_positive() + } + + pub fn trait_id(&self) -> TraitId { + self.binders.skip_binders().trait_ref.trait_id + } + + pub fn self_type_adt_id(&self, interner: I) -> Option> { + 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 { + pub trait_ref: TraitRef, + pub where_clauses: Vec>, +} + +#[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 { + pub binders: Binders>, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, HasInterner)] +pub struct DefaultImplDatumBound { + pub trait_ref: TraitRef, + pub accessible_tys: Vec>, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeVisitable)] +pub struct AdtDatum { + pub binders: Binders>, + pub id: AdtId, + 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 { + pub variants: Vec>, + pub where_clauses: Vec>, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner, TypeVisitable)] +pub struct AdtVariantDatum { + pub fields: Vec>, +} + +#[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 { + pub c: bool, + pub packed: bool, + pub int: Option>, +} + +/// 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() -> 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 { + pub id: FnDefId, + pub sig: chalk_ir::FnSig, + pub binders: Binders>, +} + +/// Avoids visiting `I::FnAbi` +impl TypeVisitable for FnDefDatum { + fn visit_with( + &self, + visitor: &mut dyn chalk_ir::visit::TypeVisitor, + outer_binder: DebruijnIndex, + ) -> ControlFlow { + 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 { + /// Types of the function's arguments + /// ```ignore + /// fn foo(bar: i32, baz: T); + /// ^^^ ^ + /// ``` + /// + pub argument_types: Vec>, + /// Return type of the function + /// ```ignore + /// fn foo() -> i32; + /// ^^^ + /// ``` + pub return_type: Ty, +} + +#[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 { + /// 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>, + + /// Where clauses defined on the function + /// ```ignore + /// fn foo() where T: Eq; + /// ^^^^^^^^^^^ + /// ``` + pub where_clauses: Vec>, +} + +#[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 +/// where +/// T: Debug, +/// { +/// type Bar; +/// } +/// ``` +/// +/// This would represent the `trait Foo` declaration. Note that the details of +/// the trait members (e.g., the associated type declaration (`type Bar`) 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 { + pub id: TraitId, + + pub binders: Binders>, + + /// "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>, + + /// If this is a well-known trait, which one? If `None`, this is a regular, + /// user-defined trait. + pub well_known: Option, +} + +/// 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` - 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 TraitDatum { + 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 where T: Debug { } + /// ^^^^^^^^^^^^^^ + /// ``` + pub fn where_clauses(&self) -> Binders<&Vec>> { + self.binders.as_ref().map(|td| &td.where_clauses) + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, HasInterner, TypeVisitable)] +pub struct TraitDatumBound { + /// Where clauses defined on the trait: + /// + /// ```ignore + /// trait Foo where T: Debug { } + /// ^^^^^^^^^^^^^^ + /// ``` + pub where_clauses: Vec>, +} + +#[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` in `impl> SomeType`. +#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)] +pub enum InlineBound { + TraitBound(TraitBound), + AliasEqBound(AliasEqBound), +} + +#[allow(type_alias_bounds)] +pub type QuantifiedInlineBound = Binders>; + +pub trait IntoWhereClauses { + type Output; + + fn into_where_clauses(&self, interner: I, self_ty: Ty) -> Vec; +} + +impl IntoWhereClauses for InlineBound { + type Output = WhereClause; + + /// 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) -> Vec> { + match self { + InlineBound::TraitBound(b) => b.into_where_clauses(interner, self_ty), + InlineBound::AliasEqBound(b) => b.into_where_clauses(interner, self_ty), + } + } +} + +impl IntoWhereClauses for QuantifiedInlineBound { + type Output = QuantifiedWhereClause; + + fn into_where_clauses(&self, interner: I, self_ty: Ty) -> Vec> { + 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 { + pub trait_id: TraitId, + pub args_no_self: Vec>, +} + +impl TraitBound { + fn into_where_clauses(&self, interner: I, self_ty: Ty) -> Vec> { + 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) -> TraitRef { + 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 { + pub trait_bound: TraitBound, + pub associated_ty_id: AssocTypeId, + /// Does not include trait parameters. + pub parameters: Vec>, + pub value: Ty, +} + +impl AliasEqBound { + fn into_where_clauses(&self, interner: I, self_ty: Ty) -> Vec> { + 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 { + /// Utility function that converts from a list of generic arguments + /// which *have* associated data (`WithKind`) to a list of + /// "anonymous" generic parameters that just preserves their + /// kinds (`VariableKind`). Often convenient in lowering. + fn anonymize(&self) -> Vec>; +} + +impl Anonymize for [WithKind] { + fn anonymize(&self) -> Vec> { + self.iter().map(|pk| pk.kind.clone()).collect() + } +} + +/// Represents an associated type declaration found inside of a trait: +/// +/// ```notrust +/// trait Foo { // P0 is Self +/// type Bar: [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 { + /// The trait this associated type is defined in. + pub trait_id: TraitId, + + /// The ID of this associated type + pub id: AssocTypeId, + + /// 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>, +} + +// Manual implementation to avoid I::Identifier type. +impl TypeVisitable for AssociatedTyDatum { + fn visit_with( + &self, + visitor: &mut dyn chalk_ir::visit::TypeVisitor, + outer_binder: DebruijnIndex, + ) -> ControlFlow { + 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 { + /// 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>, + + /// Where clauses that must hold for the projection to be well-formed. + pub where_clauses: Vec>, +} + +impl AssociatedTyDatum { + /// Returns the associated ty's bounds applied to the projection type, e.g.: + /// + /// ```notrust + /// Implemented(::Item: Sized) + /// ``` + /// + /// these quantified where clauses are in the scope of the + /// `binders` field. + pub fn bounds_on_self(&self, interner: I) -> Vec> { + 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 `>::Item` 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: Debug` into + // + // ``` + // >::Item: 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 { + /// 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, + + /// 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, + + /// 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 Iterable for Vec { + /// type Iter<'a> = vec::Iter<'a, T>; + /// // ^^^^ refers to these generics here + /// } + /// ``` + pub value: Binders>, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable, HasInterner)] +pub struct AssociatedTyValueBound { + /// Type that we normalize to. The X in `type Foo<'a> = X`. + pub ty: Ty, +} + +/// 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 { + /// The placeholder `!T` that corresponds to the opaque type `T`. + pub opaque_ty_id: OpaqueTyId, + + /// The type bound to when revealed. + pub bound: Binders>, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner, TypeVisitable)] +pub struct OpaqueTyDatumBound { + /// Trait bounds for the opaque type. These are bounds that the hidden type must meet. + pub bounds: Binders>>, + /// 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>>, +} + +// 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 { + // 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>, +} + +/// The nested types for a generator. This always appears inside a `GeneratorDatum` +#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, HasInterner)] +pub struct GeneratorInputOutputDatum { + /// 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, + /// 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, + /// 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, + /// 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>, +} + +/// 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 { + /// 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>, +} + +/// 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 { + pub types: Binders>>, +} + +#[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, +} -- cgit v1.2.3