-
Notifications
You must be signed in to change notification settings - Fork 550
Add a (short) chapter on Kind
#282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# Kinds | ||
A `ty::subst::Kind<'tcx>` represents some entity in the type system: a type | ||
(`Ty<'tcx>`), lifetime (`ty::Region<'tcx>`) or constant (`ty::Const<'tcx>`). | ||
`Kind` is used to perform substitutions of generic parameters for concrete | ||
arguments, such as when calling a function with generic parameters explicitly | ||
with type arguments. Substitutions are represented using the | ||
[`Subst` type](#subst) as described below. | ||
|
||
## `Subst` | ||
`ty::subst::Subst<'tcx>` is intuitively simply a slice of `Kind<'tcx>`s, | ||
acting as an ordered list of substitutions from generic parameters to | ||
concrete arguments (such as types, lifetimes and consts). | ||
|
||
For example, given a `HashMap<K, V>` with two type parameters, `K` and `V`, an | ||
instantiation of the parameters, for example `HashMap<i32, u32>`, would be | ||
represented by the substitution `&'tcx [tcx.types.i32, tcx.types.u32]`. | ||
|
||
`Subst` provides various convenience methods to instantiant substitutions | ||
given item definitions, which should generally be used rather than explicitly | ||
constructing such substitution slices. | ||
|
||
## `Kind` | ||
The actual `Kind` struct is optimised for space, storing the type, lifetime or | ||
const as an interned pointer containing a mask identifying its kind (in the | ||
lowest 2 bits). Unless you are working with the `Subst` implementation | ||
specifically, you should generally not have to deal with `Kind` and instead | ||
make use of the safe [`UnpackedKind`](#unpackedkind) abstraction. | ||
|
||
## `UnpackedKind` | ||
As `Kind` itself is not type-safe, the `UnpackedKind` enum provides a more | ||
convenient and safe interface for dealing with kinds. An `UnpackedKind` can | ||
be converted to a raw `Kind` using `Kind::from()` (or simply `.into()` when | ||
the context is clear). As mentioned earlier, substition lists store raw | ||
`Kind`s, so before dealing with them, it is preferable to convert them to | ||
`UnpackedKind`s first. This is done by calling the `.unpack()` method. | ||
|
||
```rust,ignore | ||
// An example of unpacking and packing a kind. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you need imports here in order to make the example compile and pass travis There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you make this example compile and pass without importing the whole compiler? Usually, I just add |
||
fn deal_with_kind<'tcx>(kind: Kind<'tcx>) -> Kind<'tcx> { | ||
// Unpack a raw `Kind` to deal with it safely. | ||
let new_kind: UnpackedKind<'tcx> = match kind.unpack() { | ||
UnpackedKind::Type(ty) => { /* ... */ } | ||
UnpackedKind::Lifetime(lt) => { /* ... */ } | ||
UnpackedKind::Const(ct) => { /* ... */ } | ||
}; | ||
// Pack the `UnpackedKind` to store it in a substitution list. | ||
new_kind.into() | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The lowest 2 bits are the "tag", a (bit) "mask" is what you use to "mask out" bits other than the ones you're interested in (e.g.
let (tag, ptr) = (x & 0b11, x & !0b11);
uses0b11
to get the lowest 2 bits and!0b11
for everything else).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opened #287 to fix.