1
- # Fold and the Folder trait
1
+ # TypeFoldable and the TypeFolder trait
2
2
3
- The [ ` Fold ` ] trait permits one to traverse a type or other term in the
3
+ The [ ` TypeFoldable ` ] trait permits one to traverse a type or other term in the
4
4
chalk-ir and make a copy of it, possibly making small substitutions or
5
5
alterations along the way. Folding also allows copying a term from one
6
6
interner to another.
7
7
8
- [ `Fold ` ] : https://rust-lang.github.io/chalk/chalk_ir/fold/trait.Fold .html
8
+ [ `TypeFoldable ` ] : https://rust-lang.github.io/chalk/chalk_ir/fold/trait.TypeFoldable .html
9
9
10
- To use the [ ` Fold ` ] trait, one invokes the [ ` Fold ::fold_with` ] method, supplying some
10
+ To use the [ ` TypeFoldable ` ] trait, one invokes the [ ` TypeFoldable ::fold_with` ] method, supplying some
11
11
"folder" as well as the number of "in scope binders" for that term (typically ` 0 `
12
12
to start):
13
13
14
14
``` rust,ignore
15
15
let output_ty = input_ty.fold_with(&mut folder, 0);
16
16
```
17
17
18
- [ `Fold ::fold_with` ] : https://rust-lang.github.io/chalk/chalk_ir/fold/trait.Fold .html#tymethod.fold_with
18
+ [ `TypeFoldable ::fold_with` ] : https://rust-lang.github.io/chalk/chalk_ir/fold/trait.TypeFoldable .html#tymethod.fold_with
19
19
20
- The folder is some instance of the [ ` Folder ` ] trait. This trait
20
+ The folder is some instance of the [ ` TypeFolder ` ] trait. This trait
21
21
defines a few key callbacks that allow you to substitute different
22
22
values as the fold proceeds. For example, when a type is folded, the
23
23
folder can substitute a new type in its place.
24
24
25
- [ `Folder ` ] : https://rust-lang.github.io/chalk/chalk_ir/fold/trait.Folder .html
25
+ [ `TypeFolder ` ] : https://rust-lang.github.io/chalk/chalk_ir/fold/trait.TypeFolder .html
26
26
27
27
## Uses for folders
28
28
29
- A common use for ` Fold ` is to permit a substitution -- that is,
29
+ A common use for ` TypeFoldable ` is to permit a substitution -- that is,
30
30
replacing generic type parameters with their values.
31
31
32
- ## From Fold to Folder to SuperFold and back again
32
+ ## From TypeFoldable to TypeFolder to TypeSuperFoldable and back again
33
33
34
34
The overall flow of folding is like this.
35
35
36
- 1 . [ ` Fold ::fold_with` ] is invoked on the outermost term. It recursively
36
+ 1 . [ ` TypeFoldable ::fold_with` ] is invoked on the outermost term. It recursively
37
37
walks the term.
38
38
2 . For those sorts of terms (types, lifetimes, goals, program clauses) that have
39
- callbacks in the [ ` Folder ` ] trait, invoking [ ` Fold ::fold_with` ] will in turn
40
- invoke the corresponding method on the [ ` Folder ` ] trait, such as ` Folder ::fold_ty` .
41
- 3 . The default implementation of ` Folder ::fold_ty` , in turn, invokes
42
- ` SuperFold ::super_fold_with` . This will recursively fold the
39
+ callbacks in the [ ` TypeFolder ` ] trait, invoking [ ` TypeFoldable ::fold_with` ] will in turn
40
+ invoke the corresponding method on the [ ` TypeFolder ` ] trait, such as ` TypeFolder ::fold_ty` .
41
+ 3 . The default implementation of ` TypeFolder ::fold_ty` , in turn, invokes
42
+ ` TypeSuperFoldable ::super_fold_with` . This will recursively fold the
43
43
contents of the type. In some cases, the ` super_fold_with `
44
- implementation invokes more specialized methods on [ ` Folder ` ] , such
45
- as [ ` Folder ::fold_free_var_ty` ] , which makes it easier to write
44
+ implementation invokes more specialized methods on [ ` TypeFolder ` ] , such
45
+ as [ ` TypeFolder ::fold_free_var_ty` ] , which makes it easier to write
46
46
folders that just intercept * certain* types.
47
47
48
- [ `Folder ::fold_free_var_ty` ] : https://rust-lang.github.io/chalk/chalk_ir/fold/trait.Folder .html#method.fold_free_var_ty
48
+ [ `TypeFolder ::fold_free_var_ty` ] : https://rust-lang.github.io/chalk/chalk_ir/fold/trait.TypeFolder .html#method.fold_free_var_ty
49
49
50
50
Thus, as a user, you can customize folding by:
51
51
52
- * Defining your own ` Folder ` type
52
+ * Defining your own ` TypeFolder ` type
53
53
* Implementing the appropriate methods to "intercept" types/lifetimes/etc at the right level of
54
54
detail
55
55
* In those methods, if you find a case where you would prefer not to
56
- substitute a new value, then invoke ` SuperFold ::super_fold_with` to
56
+ substitute a new value, then invoke ` TypeSuperFoldable ::super_fold_with` to
57
57
return to the default behavior.
58
58
59
59
## The ` binders ` argument
60
60
61
- Each callback in the [ ` Folder ` ] trait takes a ` binders ` argument. This indicates
61
+ Each callback in the [ ` TypeFolder ` ] trait takes a ` binders ` argument. This indicates
62
62
the number of binders that we have traversed during folding, which is relevant for De Bruijn indices.
63
63
So e.g. a bound variable with depth 1, if invoked with a ` binders ` value of 1, indicates something that was bound to something external to the fold.
64
64
@@ -70,32 +70,32 @@ Foo<'a>: for<'b> Bar<'b>
70
70
71
71
In this case, ` Foo<'a> ` gets visited with depth 0 and ` Bar<'b> ` gets visited with depth 1.
72
72
73
- ## The ` Fold ::Result` associated type
73
+ ## The ` TypeFoldable ::Result` associated type
74
74
75
- The ` Fold ` trait defines a [ ` Result ` ] associated type, indicating the
75
+ The ` TypeFoldable ` trait defines a [ ` Result ` ] associated type, indicating the
76
76
type that will result from folding.
77
77
78
- [ `Result` ] : https://rust-lang.github.io/chalk/chalk_ir/fold/trait.Fold .html#associatedtype.Result
78
+ [ `Result` ] : https://rust-lang.github.io/chalk/chalk_ir/fold/trait.TypeFoldable .html#associatedtype.Result
79
79
80
- ## When to implement the Fold and SuperFold traits
80
+ ## When to implement the TypeFoldable and TypeSuperFoldable traits
81
81
82
82
Any piece of IR that represents a kind of "term" (e.g., a type, part
83
- of a type, or a goal, etc) in the logic should implement ` Fold ` . We
84
- also implement ` Fold ` for common collection types like ` Vec ` as well
83
+ of a type, or a goal, etc) in the logic should implement ` TypeFoldable ` . We
84
+ also implement ` TypeFoldable ` for common collection types like ` Vec ` as well
85
85
as tuples, references, etc.
86
86
87
- The ` SuperFold ` trait should only be implemented for those types that
88
- have a callback defined on the ` Folder ` trait (e.g., types and
87
+ The ` TypeSuperFoldable ` trait should only be implemented for those types that
88
+ have a callback defined on the ` TypeFolder ` trait (e.g., types and
89
89
lifetimes).
90
90
91
91
## Derives
92
92
93
- Using the ` chalk-derive ` crate, you can auto-derive the ` Fold ` trait.
94
- There isn't presently a derive for ` SuperFold ` since it is very rare
95
- to require it. The derive for ` Fold ` is a bit cludgy and requires:
93
+ Using the ` chalk-derive ` crate, you can auto-derive the ` TypeFoldable ` trait.
94
+ There isn't presently a derive for ` TypeSuperFoldable ` since it is very rare
95
+ to require it. The derive for ` TypeFoldable ` is a bit cludgy and requires:
96
96
97
- * You must import ` Fold ` into scope.
98
- * The type you are deriving ` Fold ` on must have either:
97
+ * You must import ` TypeFoldable ` into scope.
98
+ * The type you are deriving ` TypeFoldable ` on must have either:
99
99
* A type parameter that has a ` Interner ` bound, like ` I: Interner `
100
100
* A type parameter that has a ` HasInterner ` bound, like ` I: HasInterner `
101
101
* The ` has_interner(XXX) ` attribute.
0 commit comments