diff --git a/src/SUMMARY.md b/src/SUMMARY.md index b65ba4c7..fc866f7b 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -43,7 +43,7 @@ - [Debugging](./hir-debugging.md) - [Closure expansion](./closure.md) - [The `ty` module: representing types](./ty.md) - - [Kinds](./kinds.md) + - [Generic arguments](./generic_arguments.md) - [Type inference](./type-inference.md) - [Trait solving (old-style)](./traits/resolution.md) - [Higher-ranked trait bounds](./traits/hrtb.md) diff --git a/src/generic_arguments.md b/src/generic_arguments.md new file mode 100644 index 00000000..c9911acf --- /dev/null +++ b/src/generic_arguments.md @@ -0,0 +1,50 @@ +# Generic arguments +A `ty::subst::GenericArg<'tcx>` represents some entity in the type system: a type +(`Ty<'tcx>`), lifetime (`ty::Region<'tcx>`) or constant (`ty::Const<'tcx>`). +`GenericArg` 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 `GenericArg<'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 instantiate substitutions +given item definitions, which should generally be used rather than explicitly +constructing such substitution slices. + +## `GenericArg` +The actual `GenericArg` struct is optimised for space, storing the type, lifetime or +const as an interned pointer containing a tag 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 `GenericArg` and instead +make use of the safe [`GenericArgKind`](#genericargkind) abstraction. + +## `GenericArgKind` +As `GenericArg` itself is not type-safe, the `GenericArgKind` enum provides a more +convenient and safe interface for dealing with generic arguments. An +`GenericArgKind` can be converted to a raw `GenericArg` using `GenericArg::from()` +(or simply `.into()` when the context is clear). As mentioned earlier, substitution +lists store raw `GenericArg`s, so before dealing with them, it is preferable to +convert them to `GenericArgKind`s first. This is done by calling the `.unpack()` +method. + +```rust,ignore +// An example of unpacking and packing a generic argument. +fn deal_with_generic_arg<'tcx>(generic_arg: GenericArg<'tcx>) -> GenericArg<'tcx> { + // Unpack a raw `GenericArg` to deal with it safely. + let new_generic_arg: GenericArgKind<'tcx> = match generic_arg.unpack() { + GenericArgKind::Type(ty) => { /* ... */ } + GenericArgKind::Lifetime(lt) => { /* ... */ } + GenericArgKind::Const(ct) => { /* ... */ } + }; + // Pack the `GenericArgKind` to store it in a substitution list. + new_generic_arg.into() +} +``` diff --git a/src/kinds.md b/src/kinds.md deleted file mode 100644 index 194d2ee2..00000000 --- a/src/kinds.md +++ /dev/null @@ -1,49 +0,0 @@ -# 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` 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 instantiate 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 tag 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, substitution 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. -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() -} -``` diff --git a/src/ty.md b/src/ty.md index 811f473c..6a1cf444 100644 --- a/src/ty.md +++ b/src/ty.md @@ -109,7 +109,7 @@ module. Here are a few examples: - `Predicate` defines something the trait system has to prove (see `traits` module). -[subst]: ./kinds.html#subst +[subst]: ./generic_arguments.html#subst ### Import conventions