1+ <!-- date-check: may 2024 -->
12# ` TypeFoldable ` and ` TypeFolder `
23
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?
69
710The 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 ` ]
912and
10- [ ` TypeFolder ` ] ( https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/fold/trait.TypeFolder.html ) .
13+ [ ` TypeFolder ` ] .
1114
1215- ` TypeFoldable ` is implemented by types that embed type information. It allows you to recursively
1316 process the contents of the ` TypeFoldable ` and do stuff to them.
1417- ` TypeFolder ` defines what you want to do with the types you encounter while processing the
1518 ` TypeFoldable ` .
1619
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).
2224
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 :
2426
2527``` rust,ignore
2628vec.iter().map(|e1| foo(e2)).collect()
@@ -33,8 +35,7 @@ So to reiterate:
3335- ` TypeFolder ` is a trait that defines a “map” operation.
3436- ` TypeFoldable ` is a trait that is implemented by things that embed types.
3537
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 ` ] .
3839Looking at its implementation, we see where the actual substitutions are happening.
3940
4041However, 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
8889` TypeFoldable ` types whose implementations basically just forward to their fields’ ` TypeFoldable `
8990implementations. Such implementations of ` TypeFoldable ` tend to be pretty tedious to write by hand.
9091For 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]
103100and all that does is index into the list of substitutions with the index of the ` Param ` .
104101
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