Trait chalk_ir::fold::TypeFolder

source ·
pub trait TypeFolder<I: Interner>: FallibleTypeFolder<I, Error = Infallible> {
Show 19 methods // Required methods fn as_dyn(&mut self) -> &mut dyn TypeFolder<I>; fn interner(&self) -> I; // Provided methods fn fold_ty(&mut self, ty: Ty<I>, outer_binder: DebruijnIndex) -> Ty<I> { ... } fn fold_lifetime( &mut self, lifetime: Lifetime<I>, outer_binder: DebruijnIndex ) -> Lifetime<I> { ... } fn fold_const( &mut self, constant: Const<I>, outer_binder: DebruijnIndex ) -> Const<I> { ... } fn fold_program_clause( &mut self, clause: ProgramClause<I>, outer_binder: DebruijnIndex ) -> ProgramClause<I> { ... } fn fold_goal( &mut self, goal: Goal<I>, outer_binder: DebruijnIndex ) -> Goal<I> { ... } fn forbid_free_vars(&self) -> bool { ... } fn fold_free_var_ty( &mut self, bound_var: BoundVar, outer_binder: DebruijnIndex ) -> Ty<I> { ... } fn fold_free_var_lifetime( &mut self, bound_var: BoundVar, outer_binder: DebruijnIndex ) -> Lifetime<I> { ... } fn fold_free_var_const( &mut self, ty: Ty<I>, bound_var: BoundVar, outer_binder: DebruijnIndex ) -> Const<I> { ... } fn forbid_free_placeholders(&self) -> bool { ... } fn fold_free_placeholder_ty( &mut self, universe: PlaceholderIndex, outer_binder: DebruijnIndex ) -> Ty<I> { ... } fn fold_free_placeholder_lifetime( &mut self, universe: PlaceholderIndex, outer_binder: DebruijnIndex ) -> Lifetime<I> { ... } fn fold_free_placeholder_const( &mut self, ty: Ty<I>, universe: PlaceholderIndex, outer_binder: DebruijnIndex ) -> Const<I> { ... } fn forbid_inference_vars(&self) -> bool { ... } fn fold_inference_ty( &mut self, var: InferenceVar, kind: TyVariableKind, outer_binder: DebruijnIndex ) -> Ty<I> { ... } fn fold_inference_lifetime( &mut self, var: InferenceVar, outer_binder: DebruijnIndex ) -> Lifetime<I> { ... } fn fold_inference_const( &mut self, ty: Ty<I>, var: InferenceVar, outer_binder: DebruijnIndex ) -> Const<I> { ... }
}
Expand description

A “folder” is a transformer that can be used to make a copy of some term – that is, some bit of IR, such as a Goal – with certain changes applied. The idea is that it contains methods that let you swap types/lifetimes for new types/lifetimes; meanwhile, each bit of IR implements the TypeFoldable trait which, given a TypeFolder, will reconstruct itself, invoking the folder’s methods to transform each of the types/lifetimes embedded within.

Folds performed by TypeFolder cannot fail. If folds might fail, consider implementing FallibleTypeFolder instead (which is a fallible, but otherwise equivalent, trait).

Usage patterns

Substituting for free variables

Most of the time, though, we are not interested in adjust arbitrary types/lifetimes, but rather just free variables (even more often, just free existential variables) that appear within the term.

For this reason, the TypeFolder trait extends two other traits that contain methods that are invoked when just those particular

In particular, folders can intercept references to free variables (either existentially or universally quantified) and replace them with other types/lifetimes as appropriate.

To create a folder F, one never implements TypeFolder directly, but instead implements one of each of these three sub-traits:

  • FreeVarFolder – folds BoundVar instances that appear free in the term being folded (use DefaultFreeVarFolder to ignore/forbid these altogether)
  • InferenceFolder – folds existential InferenceVar instances that appear in the term being folded (use DefaultInferenceFolder to ignore/forbid these altogether)
  • PlaceholderFolder – folds universal Placeholder instances that appear in the term being folded (use DefaultPlaceholderFolder to ignore/forbid these altogether)

To apply a folder, use the TypeFoldable::fold_with method, like so

let x = x.fold_with(&mut folder, 0);

Required Methods§

source

fn as_dyn(&mut self) -> &mut dyn TypeFolder<I>

Creates a dyn value from this folder. Unfortunately, this must be added manually to each impl of TypeFolder; it permits the default implements below to create a &mut dyn TypeFolder from Self without knowing what Self is (by invoking this method). Effectively, this limits impls of TypeFolder to types for which we are able to create a dyn value (i.e., not [T] types).

source

fn interner(&self) -> I

Gets the interner that is being folded from.

Provided Methods§

source

fn fold_ty(&mut self, ty: Ty<I>, outer_binder: DebruijnIndex) -> Ty<I>

Top-level callback: invoked for each Ty<I> that is encountered when folding. By default, invokes super_fold_with, which will in turn invoke the more specialized folding methods below, like fold_free_var_ty.

source

fn fold_lifetime( &mut self, lifetime: Lifetime<I>, outer_binder: DebruijnIndex ) -> Lifetime<I>

Top-level callback: invoked for each Lifetime<I> that is encountered when folding. By default, invokes super_fold_with, which will in turn invoke the more specialized folding methods below, like fold_free_var_lifetime.

source

fn fold_const( &mut self, constant: Const<I>, outer_binder: DebruijnIndex ) -> Const<I>

Top-level callback: invoked for each Const<I> that is encountered when folding. By default, invokes super_fold_with, which will in turn invoke the more specialized folding methods below, like fold_free_var_const.

source

fn fold_program_clause( &mut self, clause: ProgramClause<I>, outer_binder: DebruijnIndex ) -> ProgramClause<I>

Invoked for every program clause. By default, recursively folds the goals contents.

source

fn fold_goal(&mut self, goal: Goal<I>, outer_binder: DebruijnIndex) -> Goal<I>

Invoked for every goal. By default, recursively folds the goals contents.

source

fn forbid_free_vars(&self) -> bool

If overridden to return true, then folding will panic if a free variable is encountered. This should be done if free type/lifetime variables are not expected.

source

fn fold_free_var_ty( &mut self, bound_var: BoundVar, outer_binder: DebruijnIndex ) -> Ty<I>

Invoked for TyKind::BoundVar instances that are not bound within the type being folded over:

  • depth is the depth of the TyKind::BoundVar; this has been adjusted to account for binders in scope.
  • binders is the number of binders in scope.

This should return a type suitable for a context with binders in scope.

source

fn fold_free_var_lifetime( &mut self, bound_var: BoundVar, outer_binder: DebruijnIndex ) -> Lifetime<I>

As fold_free_var_ty, but for lifetimes.

source

fn fold_free_var_const( &mut self, ty: Ty<I>, bound_var: BoundVar, outer_binder: DebruijnIndex ) -> Const<I>

As fold_free_var_ty, but for constants.

source

fn forbid_free_placeholders(&self) -> bool

If overridden to return true, we will panic when a free placeholder type/lifetime/const is encountered.

source

fn fold_free_placeholder_ty( &mut self, universe: PlaceholderIndex, outer_binder: DebruijnIndex ) -> Ty<I>

Invoked for each occurrence of a placeholder type; these are used when we instantiate binders universally. Returns a type to use instead, which should be suitably shifted to account for binders.

  • universe is the universe of the TypeName::ForAll that was found
  • binders is the number of binders in scope
source

fn fold_free_placeholder_lifetime( &mut self, universe: PlaceholderIndex, outer_binder: DebruijnIndex ) -> Lifetime<I>

As with fold_free_placeholder_ty, but for lifetimes.

source

fn fold_free_placeholder_const( &mut self, ty: Ty<I>, universe: PlaceholderIndex, outer_binder: DebruijnIndex ) -> Const<I>

As with fold_free_placeholder_ty, but for constants.

source

fn forbid_inference_vars(&self) -> bool

If overridden to return true, inference variables will trigger panics when folded. Used when inference variables are unexpected.

source

fn fold_inference_ty( &mut self, var: InferenceVar, kind: TyVariableKind, outer_binder: DebruijnIndex ) -> Ty<I>

Invoked for each occurrence of a inference type; these are used when we instantiate binders universally. Returns a type to use instead, which should be suitably shifted to account for binders.

  • universe is the universe of the TypeName::ForAll that was found
  • binders is the number of binders in scope
source

fn fold_inference_lifetime( &mut self, var: InferenceVar, outer_binder: DebruijnIndex ) -> Lifetime<I>

As with fold_inference_ty, but for lifetimes.

source

fn fold_inference_const( &mut self, ty: Ty<I>, var: InferenceVar, outer_binder: DebruijnIndex ) -> Const<I>

As with fold_inference_ty, but for constants.

Implementors§

source§

impl<'i, I: Interner, A: AsParameters<I>> TypeFolder<I> for SubstFolder<'i, I, A>

source§

impl<I: Interner> TypeFolder<I> for Shifter<I>

source§

impl<I: Interner> TypeFolder<I> for Subst<'_, I>