From 9875582ab8d61f1662058a904454284e19b31bfe Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 5 Apr 2018 11:49:38 +0100 Subject: [PATCH 1/3] Add preliminary chapter on kinds --- src/SUMMARY.md | 1 + src/kinds.md | 31 +++++++++++++++++++++++++++++++ src/ty.md | 6 ++++-- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/kinds.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 091860e9a..b27114f1e 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -38,6 +38,7 @@ - [The HIR (High-level IR)](./hir.md) - [Lowering AST to HIR](./lowering.md) - [The `ty` module: representing types](./ty.md) +- [Kinds](./kinds.md) - [Type inference](./type-inference.md) - [Trait solving (old-style)](./traits/resolution.md) - [Higher-ranked trait bounds](./traits/hrtb.md) diff --git a/src/kinds.md b/src/kinds.md new file mode 100644 index 000000000..d811423a8 --- /dev/null +++ b/src/kinds.md @@ -0,0 +1,31 @@ +# Kinds +A `ty::subst::Kind<'tcx>` represents some entity in the type system: currently +either a type (`Ty<'tcx>`) or a lifetime (`ty::Region<'tcx>`), though in the +future this will also include constants (`ty::Const<'tcx>`) to facilitate the +use of const generics. `Kind` is used for type and lifetime substitution (from +abstract type and lifetime parameters to concrete types and lifetimes). + +## `UnpackedKind` +As `Kind` itself is not type-safe (see [`Kind`](#kind)), the `UnpackedKind` enum +provides a more convenient and safe interface for dealing with kinds. To +convert from an `UnpackedKind` to a `Kind`, you can call `Kind::from` (or +`.into`). It should not be necessary to convert a `Kind` to an `UnpackedKind`: +instead, you should prefer to deal with `UnpackedKind`, converting it only when +passing it to `Subst` methods. + +## `Kind` +The actual `Kind` struct is optimised for space, storing the type or lifetime +as an interned pointer containing a mask identifying its kind (in the lowest +2 bits). + +## `Subst` +`ty::subst::Subst<'tcx>` is simply defined as a slice of `Kind<'tcx>`s +and acts as an ordered list of substitutions from kind parameters (i.e. +type and lifetime parameters) to kinds. + +For example, given a `HashMap` with two type parameters, `K` and `V`, an +instantiation of the parameters, for example `HashMap`, would be +represented by the substitution `&'tcx [tcx.types.i32, tcx.types.u32]`. + +`Subst` provides various convenience methods to instantiant substitutions +given item definitions. diff --git a/src/ty.md b/src/ty.md index fea9afbeb..d9979bc0b 100644 --- a/src/ty.md +++ b/src/ty.md @@ -141,8 +141,8 @@ In addition to types, there are a number of other arena-allocated data structures that you can allocate, and which are found in this module. Here are a few examples: -- `Substs`, allocated with `mk_substs` – this will intern a slice of types, - often used to specify the values to be substituted for generics +- [`Substs`][subst], allocated with `mk_substs` – this will intern a slice of + types, often used to specify the values to be substituted for generics (e.g. `HashMap` would be represented as a slice `&'tcx [tcx.types.i32, tcx.types.u32]`). - `TraitRef`, typically passed by value – a **trait reference** @@ -153,6 +153,8 @@ module. Here are a few examples: - `Predicate` defines something the trait system has to prove (see `traits` module). +[subst]: ./kinds.html#subst + ### Import conventions Although there is no hard and fast rule, the `ty` module tends to be used like From bb1971f7a361441944bd6aeaf8ff8b0b13ed7609 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 16 Feb 2019 14:38:15 +0000 Subject: [PATCH 2/3] Add more information and an example to Kind chapter --- src/kinds.md | 62 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/src/kinds.md b/src/kinds.md index d811423a8..bd483c868 100644 --- a/src/kinds.md +++ b/src/kinds.md @@ -1,31 +1,49 @@ # Kinds -A `ty::subst::Kind<'tcx>` represents some entity in the type system: currently -either a type (`Ty<'tcx>`) or a lifetime (`ty::Region<'tcx>`), though in the -future this will also include constants (`ty::Const<'tcx>`) to facilitate the -use of const generics. `Kind` is used for type and lifetime substitution (from -abstract type and lifetime parameters to concrete types and lifetimes). - -## `UnpackedKind` -As `Kind` itself is not type-safe (see [`Kind`](#kind)), the `UnpackedKind` enum -provides a more convenient and safe interface for dealing with kinds. To -convert from an `UnpackedKind` to a `Kind`, you can call `Kind::from` (or -`.into`). It should not be necessary to convert a `Kind` to an `UnpackedKind`: -instead, you should prefer to deal with `UnpackedKind`, converting it only when -passing it to `Subst` methods. - -## `Kind` -The actual `Kind` struct is optimised for space, storing the type or lifetime -as an interned pointer containing a mask identifying its kind (in the lowest -2 bits). +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 simply defined as a slice of `Kind<'tcx>`s -and acts as an ordered list of substitutions from kind parameters (i.e. -type and lifetime parameters) to kinds. +`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` with two type parameters, `K` and `V`, an instantiation of the parameters, for example `HashMap`, would be represented by the substitution `&'tcx [tcx.types.i32, tcx.types.u32]`. `Subst` provides various convenience methods to instantiant substitutions -given item definitions. +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 +// An example of unpacking and packing a kind. +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() +} +``` From 9416b65b4cba348afd531e459383f6abb9785092 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 18 Feb 2019 22:57:57 +0000 Subject: [PATCH 3/3] Ignore Rust snippet --- src/kinds.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kinds.md b/src/kinds.md index bd483c868..d5e218c31 100644 --- a/src/kinds.md +++ b/src/kinds.md @@ -34,7 +34,7 @@ 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 +```rust,ignore // An example of unpacking and packing a kind. fn deal_with_kind<'tcx>(kind: Kind<'tcx>) -> Kind<'tcx> { // Unpack a raw `Kind` to deal with it safely.