1
+ <!-- date-check: may 2024 -->
1
2
# ` TypeFoldable ` and ` TypeFolder `
2
3
3
- In the previous chapter we discussed instantiating binders. This must involves looking at everything inside of a ` Early/Binder `
4
- to find any usages of the bound vars in order to replace them. Binders can wrap an arbitrary rust type ` T ` not just a ` Ty ` so
5
- how do we implement the ` instantiate ` methods on the ` Early/Binder ` types.
4
+ In [ a previous chapter] , we discussed instantiating binders.
5
+ This involves looking at everything inside of a ` Early(Binder) `
6
+ to find any usages of the bound vars in order to replace them.
7
+ Binders can wrap an arbitrary Rust type ` T ` , not just a ` Ty ` .
8
+ So, how do we implement the ` instantiate ` methods on the ` Early/Binder ` types?
6
9
7
10
The answer is a couple of traits:
8
- [ ` TypeFoldable ` ] ( https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFoldable.html )
11
+ [ ` TypeFoldable ` ]
9
12
and
10
- [ ` TypeFolder ` ] ( https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFolder.html ) .
13
+ [ ` TypeFolder ` ] .
11
14
12
15
- ` TypeFoldable ` is implemented by types that embed type information. It allows you to recursively
13
16
process the contents of the ` TypeFoldable ` and do stuff to them.
14
17
- ` TypeFolder ` defines what you want to do with the types you encounter while processing the
15
18
` TypeFoldable ` .
16
19
17
- For example, the ` TypeFolder ` trait has a method
18
- [ ` fold_ty ` ] ( https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFolder.html#method.fold_ty )
19
- that takes a type as input and returns a new type as a result. ` TypeFoldable ` invokes the
20
- ` TypeFolder ` ` fold_foo ` methods on itself, giving the ` TypeFolder ` access to its contents (the
21
- types, regions, etc that are contained within).
20
+ For example, the ` TypeFolder ` trait has a method [ ` fold_ty ` ]
21
+ that takes a type as input and returns a new type as a result.
22
+ ` TypeFoldable ` invokes the ` TypeFolder ` ` fold_foo ` methods on itself,
23
+ giving the ` TypeFolder ` access to its contents (the types, regions, etc that are contained within).
22
24
23
- You can think of it with this analogy to the iterator combinators we have come to love in rust :
25
+ You can think of it with this analogy to the iterator combinators we have come to love in Rust :
24
26
25
27
``` rust,ignore
26
28
vec.iter().map(|e1| foo(e2)).collect()
@@ -33,8 +35,7 @@ So to reiterate:
33
35
- ` TypeFolder ` is a trait that defines a “map” operation.
34
36
- ` TypeFoldable ` is a trait that is implemented by things that embed types.
35
37
36
- In the case of ` subst ` , we can see that it is implemented as a ` TypeFolder ` :
37
- [ ` ArgFolder ` ] ( https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/binder/struct.ArgFolder.html ) .
38
+ In the case of ` subst ` , we can see that it is implemented as a ` TypeFolder ` : [ ` ArgFolder ` ] .
38
39
Looking at its implementation, we see where the actual substitutions are happening.
39
40
40
41
However, you might also notice that the implementation calls this ` super_fold_with ` method. What is
@@ -88,17 +89,22 @@ things. We only want to do something when we reach a type. That means there may
88
89
` TypeFoldable ` types whose implementations basically just forward to their fields’ ` TypeFoldable `
89
90
implementations. Such implementations of ` TypeFoldable ` tend to be pretty tedious to write by hand.
90
91
For this reason, there is a ` derive ` macro that allows you to ` #![derive(TypeFoldable)] ` . It is
91
- defined
92
- [ here] ( https://github.com/rust-lang/rust/blob/master/compiler/rustc_macros/src/type_foldable.rs ) .
93
-
94
- ** ` subst ` ** In the case of substitutions the [ actual
95
- folder] ( https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L440-L451 )
96
- is going to be doing the indexing we’ve already mentioned. There we define a ` Folder ` and call
97
- ` fold_with ` on the ` TypeFoldable ` to process yourself. Then
98
- [ fold_ty] ( https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L512-L536 )
99
- the method that process each type it looks for a ` ty::Param ` and for those it replaces it for
100
- something from the list of substitutions, otherwise recursively process the type. To replace it,
101
- calls
102
- [ ty_for_param] ( https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L552-L587 )
92
+ defined [ here] .
93
+
94
+ ** ` subst ` ** In the case of substitutions the [ actual folder]
95
+ is going to be doing the indexing we’ve already mentioned.
96
+ There we define a ` Folder ` and call ` fold_with ` on the ` TypeFoldable ` to process yourself.
97
+ Then [ fold_ty] the method that process each type it looks for a ` ty::Param ` and for those
98
+ it replaces it for something from the list of substitutions, otherwise recursively process the type.
99
+ To replace it, calls [ ty_for_param]
103
100
and all that does is index into the list of substitutions with the index of the ` Param ` .
104
101
102
+ [ a previous chapter ] : ty_module/instantiating_binders.md
103
+ [ `TypeFoldable` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFoldable.html
104
+ [ `TypeFolder` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFolder.html
105
+ [ `fold_ty` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/trait.TypeFolder.html#method.fold_ty
106
+ [ `ArgFolder` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/binder/struct.ArgFolder.html
107
+ [ here ] : https://github.com/rust-lang/rust/blob/master/compiler/rustc_macros/src/type_foldable.rs
108
+ [ actual folder ] : https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L440-L451
109
+ [ fold_ty ] : https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L512-L536
110
+ [ ty_for_param ] : https://github.com/rust-lang/rust/blob/75ff3110ac6d8a0259023b83fd20d7ab295f8dd6/src/librustc_middle/ty/subst.rs#L552-L587
0 commit comments