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– foldsBoundVarinstances that appear free in the term being folded (useDefaultFreeVarFolderto ignore/forbid these altogether)InferenceFolder– folds existentialInferenceVarinstances that appear in the term being folded (useDefaultInferenceFolderto ignore/forbid these altogether)PlaceholderFolder– folds universalPlaceholderinstances that appear in the term being folded (useDefaultPlaceholderFolderto 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§
sourcefn as_dyn(&mut self) -> &mut dyn TypeFolder<I>
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).
Provided Methods§
sourcefn fold_ty(&mut self, ty: Ty<I>, outer_binder: DebruijnIndex) -> Ty<I>
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.
sourcefn fold_lifetime(
&mut self,
lifetime: Lifetime<I>,
outer_binder: DebruijnIndex,
) -> Lifetime<I>
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.
sourcefn fold_const(
&mut self,
constant: Const<I>,
outer_binder: DebruijnIndex,
) -> Const<I>
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.
sourcefn fold_program_clause(
&mut self,
clause: ProgramClause<I>,
outer_binder: DebruijnIndex,
) -> ProgramClause<I>
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.
sourcefn fold_goal(&mut self, goal: Goal<I>, outer_binder: DebruijnIndex) -> Goal<I>
fn fold_goal(&mut self, goal: Goal<I>, outer_binder: DebruijnIndex) -> Goal<I>
Invoked for every goal. By default, recursively folds the goals contents.
sourcefn forbid_free_vars(&self) -> bool
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.
sourcefn fold_free_var_ty(
&mut self,
bound_var: BoundVar,
outer_binder: DebruijnIndex,
) -> Ty<I>
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:
depthis the depth of theTyKind::BoundVar; this has been adjusted to account for binders in scope.bindersis the number of binders in scope.
This should return a type suitable for a context with
binders in scope.
sourcefn fold_free_var_lifetime(
&mut self,
bound_var: BoundVar,
outer_binder: DebruijnIndex,
) -> Lifetime<I>
fn fold_free_var_lifetime( &mut self, bound_var: BoundVar, outer_binder: DebruijnIndex, ) -> Lifetime<I>
As fold_free_var_ty, but for lifetimes.
sourcefn fold_free_var_const(
&mut self,
ty: Ty<I>,
bound_var: BoundVar,
outer_binder: DebruijnIndex,
) -> Const<I>
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.
sourcefn forbid_free_placeholders(&self) -> bool
fn forbid_free_placeholders(&self) -> bool
If overridden to return true, we will panic when a free placeholder type/lifetime/const is encountered.
sourcefn fold_free_placeholder_ty(
&mut self,
universe: PlaceholderIndex,
outer_binder: DebruijnIndex,
) -> Ty<I>
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.
universeis the universe of theTypeName::ForAllthat was foundbindersis the number of binders in scope
sourcefn fold_free_placeholder_lifetime(
&mut self,
universe: PlaceholderIndex,
outer_binder: DebruijnIndex,
) -> Lifetime<I>
fn fold_free_placeholder_lifetime( &mut self, universe: PlaceholderIndex, outer_binder: DebruijnIndex, ) -> Lifetime<I>
As with fold_free_placeholder_ty, but for lifetimes.
sourcefn fold_free_placeholder_const(
&mut self,
ty: Ty<I>,
universe: PlaceholderIndex,
outer_binder: DebruijnIndex,
) -> Const<I>
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.
sourcefn forbid_inference_vars(&self) -> bool
fn forbid_inference_vars(&self) -> bool
If overridden to return true, inference variables will trigger panics when folded. Used when inference variables are unexpected.
sourcefn fold_inference_ty(
&mut self,
var: InferenceVar,
kind: TyVariableKind,
outer_binder: DebruijnIndex,
) -> Ty<I>
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.
universeis the universe of theTypeName::ForAllthat was foundbindersis the number of binders in scope
sourcefn fold_inference_lifetime(
&mut self,
var: InferenceVar,
outer_binder: DebruijnIndex,
) -> Lifetime<I>
fn fold_inference_lifetime( &mut self, var: InferenceVar, outer_binder: DebruijnIndex, ) -> Lifetime<I>
As with fold_inference_ty, but for lifetimes.
sourcefn fold_inference_const(
&mut self,
ty: Ty<I>,
var: InferenceVar,
outer_binder: DebruijnIndex,
) -> Const<I>
fn fold_inference_const( &mut self, ty: Ty<I>, var: InferenceVar, outer_binder: DebruijnIndex, ) -> Const<I>
As with fold_inference_ty, but for constants.