Skip to content

Commit 30b54ad

Browse files
authored
Merge pull request rust-lang#2379 from rust-lang/tshepang-which-chapter
clean TypeFold* chapter
2 parents b805dcb + f1d1ebc commit 30b54ad

File tree

1 file changed

+31
-25
lines changed

1 file changed

+31
-25
lines changed

src/doc/rustc-dev-guide/src/ty-fold.md

+31-25
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
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

710
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`]
912
and
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
2628
vec.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`].
3839
Looking at its implementation, we see where the actual substitutions are happening.
3940

4041
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
8889
`TypeFoldable` types whose implementations basically just forward to their fields’ `TypeFoldable`
8990
implementations. Such implementations of `TypeFoldable` tend to be pretty tedious to write by hand.
9091
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]
103100
and 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

Comments
 (0)