Struct chalk_ir::Binders

source ·
pub struct Binders<T: HasInterner> {
    pub binders: VariableKinds<T::Interner>,
    pub(crate) value: T,
}
Expand description

Indicates that the value is universally quantified over N parameters of the given kinds, where N == self.binders.len(). A variable with depth i < N refers to the value at self.binders[i]. Variables with depth >= N are free.

(IOW, we use deBruijn indices, where binders are introduced in reverse order of self.binders.)

Fields§

§binders: VariableKinds<T::Interner>

The binders that quantify over the value.

§value: T

The value being quantified over.

Implementations§

source§

impl<I: Interner> Binders<WhereClause<I>>

source

pub fn into_well_formed_goal(self, interner: I) -> Binders<DomainGoal<I>>

As with WhereClause::into_well_formed_goal, but for a quantified where clause. For example, forall<T> { Implemented(T: Trait)} would map to forall<T> { WellFormed(T: Trait) }.

source

pub fn into_from_env_goal(self, interner: I) -> Binders<DomainGoal<I>>

As with WhereClause::into_from_env_goal, but mapped over any binders. For example, forall<T> { Implemented(T: Trait)} would map to forall<T> { FromEnv(T: Trait) }.

source

pub fn trait_id(&self) -> Option<TraitId<I>>

If the underlying where clause is a TraitRef, returns its trait id.

source§

impl<T: Clone + HasInterner> Binders<&T>

source

pub fn cloned(self) -> Binders<T>

Converts a Binders<&T> to a Binders<T> by cloning T.

source§

impl<T: HasInterner> Binders<T>

source

pub fn new(binders: VariableKinds<T::Interner>, value: T) -> Self

Create new binders.

source

pub fn empty(interner: T::Interner, value: T) -> Self

Wraps the given value in a binder without variables, i.e. for<> (value). Since our deBruijn indices count binders, not variables, this is sometimes useful.

source

pub fn skip_binders(&self) -> &T

Skips the binder and returns the “bound” value. This is a risky thing to do because it’s easy to get confused about De Bruijn indices and the like. skip_binder is only valid when you are either extracting data that has nothing to do with bound vars, or you are being very careful about your depth accounting.

Some examples where skip_binder is reasonable:

  • extracting the TraitId from a TraitRef;
  • checking if there are any fields in a StructDatum
source

pub fn into_value_and_skipped_binders(self) -> (T, VariableKinds<T::Interner>)

Skips the binder and returns the “bound” value as well as the skipped free variables. This is just as risky as skip_binders.

source

pub fn as_ref(&self) -> Binders<&T>

Converts &Binders<T> to Binders<&T>. Produces new Binders with cloned quantifiers containing a reference to the original value, leaving the original in place.

source

pub fn map<U, OP>(self, op: OP) -> Binders<U>
where OP: FnOnce(T) -> U, U: HasInterner<Interner = T::Interner>,

Maps the binders by applying a function.

source

pub fn filter_map<U, OP>(self, op: OP) -> Option<Binders<U>>
where OP: FnOnce(T) -> Option<U>, U: HasInterner<Interner = T::Interner>,

Transforms the inner value according to the given function; returns None if the function returns None.

source

pub fn map_ref<'a, U, OP>(&'a self, op: OP) -> Binders<U>
where OP: FnOnce(&'a T) -> U, U: HasInterner<Interner = T::Interner>,

Maps a function taking Binders<&T> over &Binders<T>.

source

pub fn identity_substitution( &self, interner: T::Interner ) -> Substitution<T::Interner>

Creates a Substitution containing bound vars such that applying this substitution will not change the value, i.e. ^0.0, ^0.1, ^0.2 and so on.

source

pub fn with_fresh_type_var( interner: T::Interner, op: impl FnOnce(Ty<T::Interner>) -> T ) -> Binders<T>

Creates a fresh binders that contains a single type variable. The result of the closure will be embedded in this binder. Note that you should be careful with what you return from the closure to account for the binder that will be added.

XXX FIXME – this is potentially a pretty footgun-y function.

source

pub fn len(&self, interner: T::Interner) -> usize

Returns the number of binders.

source§

impl<T, I> Binders<Binders<T>>
where T: TypeFoldable<I> + HasInterner<Interner = I>, I: Interner,

source

pub fn fuse_binders(self, interner: T::Interner) -> Binders<T>

This turns two levels of binders (for<A> for<B>) into one level (for<A, B>).

source§

impl<T, I> Binders<T>
where T: TypeFoldable<I> + HasInterner<Interner = I>, I: Interner,

source

pub fn substitute( self, interner: I, parameters: &(impl AsParameters<I> + ?Sized) ) -> T

Substitute parameters for the variables introduced by these binders. So if the binders represent (e.g.) <X, Y> { T } and parameters is the slice [A, B], then returns [X => A, Y => B] T.

Trait Implementations§

source§

impl<I: Interner> CastTo<Binders<WhereClause<I>>> for QuantifiedWhereClause<I>

source§

fn cast_to( self, _interner: <QuantifiedWhereClause<I> as HasInterner>::Interner ) -> QuantifiedWhereClause<I>

Cast a value to type T.
source§

impl<I: Interner, T: HasInterner<Interner = I> + CastTo<Goal<I>>> CastTo<Goal<I>> for Binders<T>

source§

fn cast_to(self, interner: I) -> Goal<I>

Cast a value to type T.
source§

impl<I, T> CastTo<ProgramClause<I>> for Binders<T>
where I: Interner, T: HasInterner<Interner = I> + CastTo<DomainGoal<I>>,

source§

fn cast_to(self, interner: I) -> ProgramClause<I>

Cast a value to type T.
source§

impl<T: Clone + HasInterner> Clone for Binders<T>
where T::Interner: Clone,

source§

fn clone(&self) -> Binders<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: HasInterner + Debug> Debug for Binders<T>

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<T: HasInterner> From<Binders<T>> for (VariableKinds<T::Interner>, T)

source§

fn from(binders: Binders<T>) -> Self

Converts to this type from the input type.
source§

impl<T: HasInterner> HasInterner for Binders<T>

§

type Interner = <T as HasInterner>::Interner

The interner associated with the type.
source§

impl<T: Hash + HasInterner> Hash for Binders<T>
where T::Interner: Hash,

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<V, U> IntoIterator for Binders<V>
where V: HasInterner + IntoIterator<Item = U>, U: HasInterner<Interner = V::Interner>,

Allows iterating over a Binders<Vec>, for instance. Each element will include the same set of parameter bounds.

§

type Item = Binders<U>

The type of the elements being iterated over.
§

type IntoIter = BindersIntoIterator<V>

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl<T: PartialEq + HasInterner> PartialEq for Binders<T>
where T::Interner: PartialEq,

source§

fn eq(&self, other: &Binders<T>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<T, I> TypeFoldable<I> for Binders<T>
where T: HasInterner<Interner = I> + TypeFoldable<I>, I: Interner,

source§

fn try_fold_with<E>( self, folder: &mut dyn FallibleTypeFolder<I, Error = E>, outer_binder: DebruijnIndex ) -> Result<Self, E>

Apply the given folder folder to self; binders is the number of binders that are in scope when beginning the folder. Typically binders starts as 0, but is adjusted when we encounter Binders<T> in the IR or other similar constructs.
source§

fn fold_with( self, folder: &mut dyn TypeFolder<I>, outer_binder: DebruijnIndex ) -> Self

A convenient alternative to try_fold_with for use with infallible folders. Do not override this method, to ensure coherence with try_fold_with.
source§

impl<T, I: Interner> TypeVisitable<I> for Binders<T>
where T: HasInterner + TypeVisitable<I>,

source§

fn visit_with<B>( &self, visitor: &mut dyn TypeVisitor<I, BreakTy = B>, outer_binder: DebruijnIndex ) -> ControlFlow<B>

Apply the given visitor visitor to self; binders is the number of binders that are in scope when beginning the visitor. Typically binders starts as 0, but is adjusted when we encounter Binders<T> in the IR or other similar constructs.
source§

impl<I: Interner, T> Zip<I> for Binders<T>
where T: Clone + HasInterner<Interner = I> + Zip<I> + TypeFoldable<I>,

source§

fn zip_with<Z: Zipper<I>>( zipper: &mut Z, variance: Variance, a: &Self, b: &Self ) -> Fallible<()>

Uses the zipper to walk through two values, ensuring that they match.
source§

impl<T: HasInterner + Copy> Copy for Binders<T>

source§

impl<T: Eq + HasInterner> Eq for Binders<T>
where T::Interner: Eq,

source§

impl<T: HasInterner> StructuralPartialEq for Binders<T>

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> Cast for T

source§

fn cast<U>(self, interner: U::Interner) -> U
where Self: CastTo<U>, U: HasInterner,

Cast a value to type U using CastTo.
source§

impl<T, I> CouldMatch<T> for T
where T: Zip<I> + HasInterner<Interner = I> + ?Sized, I: Interner,

source§

fn could_match( &self, interner: I, db: &dyn UnificationDatabase<I>, other: &T ) -> bool

Checks whether self and other could possibly match.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, I> Shift<I> for T
where T: TypeFoldable<I>, I: Interner,

source§

fn shifted_in(self, interner: I) -> T

Shifts this term in one level of binders.
source§

fn shifted_in_from(self, interner: I, source_binder: DebruijnIndex) -> T

Shifts a term valid at outer_binder so that it is valid at the innermost binder. See DebruijnIndex::shifted_in_from for a detailed explanation.
source§

fn shifted_out_to( self, interner: I, target_binder: DebruijnIndex ) -> Result<T, NoSolution>

Shifts a term valid at the innermost binder so that it is valid at outer_binder. See DebruijnIndex::shifted_out_to for a detailed explanation.
source§

fn shifted_out(self, interner: I) -> Result<T, NoSolution>

Shifts this term out one level of binders.
source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T, I> VisitExt<I> for T
where I: Interner, T: TypeVisitable<I>,

source§

fn has_free_vars(&self, interner: I) -> bool

Check whether there are free (non-bound) variables.