Skip to content

Commit 99d47b8

Browse files
varkormark-i-m
authored andcommitted
Add more information and an example to Kind chapter
1 parent 7cc2afa commit 99d47b8

File tree

1 file changed

+40
-22
lines changed

1 file changed

+40
-22
lines changed

src/kinds.md

+40-22
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,49 @@
11
# 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.
208

219
## `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).
2513

2614
For example, given a `HashMap<K, V>` with two type parameters, `K` and `V`, an
2715
instantiation of the parameters, for example `HashMap<i32, u32>`, would be
2816
represented by the substitution `&'tcx [tcx.types.i32, tcx.types.u32]`.
2917

3018
`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

Comments
 (0)