|
1 | 1 | # Kinds
|
2 |
| -A `ty::subst::Kind<'tcx>` represents some entity in the type system: currently |
3 |
| -either a type (`Ty<'tcx>`) or a lifetime (`ty::Region<'tcx>`), though in the |
4 |
| -future this will also include constants (`ty::Const<'tcx>`) to facilitate the |
5 |
| -use of const generics. `Kind` is used for type and lifetime substitution (from |
6 |
| -abstract type and lifetime parameters to concrete types and lifetimes). |
7 |
| - |
8 |
| -## `UnpackedKind` |
9 |
| -As `Kind` itself is not type-safe (see [`Kind`](#kind)), the `UnpackedKind` enum |
10 |
| -provides a more convenient and safe interface for dealing with kinds. To |
11 |
| -convert from an `UnpackedKind` to a `Kind`, you can call `Kind::from` (or |
12 |
| -`.into`). It should not be necessary to convert a `Kind` to an `UnpackedKind`: |
13 |
| -instead, you should prefer to deal with `UnpackedKind`, converting it only when |
14 |
| -passing it to `Subst` methods. |
15 |
| - |
16 |
| -## `Kind` |
17 |
| -The actual `Kind` struct is optimised for space, storing the type or lifetime |
18 |
| -as an interned pointer containing a mask identifying its kind (in the lowest |
19 |
| -2 bits). |
| 2 | +A `ty::subst::Kind<'tcx>` represents some entity in the type system: a type |
| 3 | +(`Ty<'tcx>`), lifetime (`ty::Region<'tcx>`) or constant (`ty::Const<'tcx>`). |
| 4 | +`Kind` is used to perform substitutions of generic parameters for concrete |
| 5 | +arguments, such as when calling a function with generic parameters explicitly |
| 6 | +with type arguments. Substitutions are represented using the |
| 7 | +[`Subst` type](#subst) as described below. |
20 | 8 |
|
21 | 9 | ## `Subst`
|
22 |
| -`ty::subst::Subst<'tcx>` is simply defined as a slice of `Kind<'tcx>`s |
23 |
| -and acts as an ordered list of substitutions from kind parameters (i.e. |
24 |
| -type and lifetime parameters) to kinds. |
| 10 | +`ty::subst::Subst<'tcx>` is intuitively simply a slice of `Kind<'tcx>`s, |
| 11 | +acting as an ordered list of substitutions from generic parameters to |
| 12 | +concrete arguments (such as types, lifetimes and consts). |
25 | 13 |
|
26 | 14 | For example, given a `HashMap<K, V>` with two type parameters, `K` and `V`, an
|
27 | 15 | instantiation of the parameters, for example `HashMap<i32, u32>`, would be
|
28 | 16 | represented by the substitution `&'tcx [tcx.types.i32, tcx.types.u32]`.
|
29 | 17 |
|
30 | 18 | `Subst` provides various convenience methods to instantiant substitutions
|
31 |
| -given item definitions. |
| 19 | +given item definitions, which should generally be used rather than explicitly |
| 20 | +constructing such substitution slices. |
| 21 | + |
| 22 | +## `Kind` |
| 23 | +The actual `Kind` struct is optimised for space, storing the type, lifetime or |
| 24 | +const as an interned pointer containing a mask identifying its kind (in the |
| 25 | +lowest 2 bits). Unless you are working with the `Subst` implementation |
| 26 | +specifically, you should generally not have to deal with `Kind` and instead |
| 27 | +make use of the safe [`UnpackedKind`](#unpackedkind) abstraction. |
| 28 | + |
| 29 | +## `UnpackedKind` |
| 30 | +As `Kind` itself is not type-safe, the `UnpackedKind` enum provides a more |
| 31 | +convenient and safe interface for dealing with kinds. An `UnpackedKind` can |
| 32 | +be converted to a raw `Kind` using `Kind::from()` (or simply `.into()` when |
| 33 | +the context is clear). As mentioned earlier, substition lists store raw |
| 34 | +`Kind`s, so before dealing with them, it is preferable to convert them to |
| 35 | +`UnpackedKind`s first. This is done by calling the `.unpack()` method. |
| 36 | + |
| 37 | +```rust |
| 38 | +// An example of unpacking and packing a kind. |
| 39 | +fn deal_with_kind<'tcx>(kind: Kind<'tcx>) -> Kind<'tcx> { |
| 40 | + // Unpack a raw `Kind` to deal with it safely. |
| 41 | + let new_kind: UnpackedKind<'tcx> = match kind.unpack() { |
| 42 | + UnpackedKind::Type(ty) => { /* ... */ } |
| 43 | + UnpackedKind::Lifetime(lt) => { /* ... */ } |
| 44 | + UnpackedKind::Const(ct) => { /* ... */ } |
| 45 | + }; |
| 46 | + // Pack the `UnpackedKind` to store it in a substitution list. |
| 47 | + new_kind.into() |
| 48 | +} |
| 49 | +``` |
0 commit comments