]> git.proxmox.com Git - rustc.git/blob - src/doc/rustc-guide/src/generic_arguments.md
New upstream version 1.41.1+dfsg1
[rustc.git] / src / doc / rustc-guide / src / generic_arguments.md
1 # Generic arguments
2 A `ty::subst::GenericArg<'tcx>` represents some entity in the type system: a type
3 (`Ty<'tcx>`), lifetime (`ty::Region<'tcx>`) or constant (`ty::Const<'tcx>`).
4 `GenericArg` 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.
8
9 ## `Subst`
10 `ty::subst::Subst<'tcx>` is intuitively simply a slice of `GenericArg<'tcx>`s,
11 acting as an ordered list of substitutions from generic parameters to
12 concrete arguments (such as types, lifetimes and consts).
13
14 For example, given a `HashMap<K, V>` with two type parameters, `K` and `V`, an
15 instantiation of the parameters, for example `HashMap<i32, u32>`, would be
16 represented by the substitution `&'tcx [tcx.types.i32, tcx.types.u32]`.
17
18 `Subst` provides various convenience methods to instantiate substitutions
19 given item definitions, which should generally be used rather than explicitly
20 constructing such substitution slices.
21
22 ## `GenericArg`
23 The actual `GenericArg` struct is optimised for space, storing the type, lifetime or
24 const as an interned pointer containing a tag 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 `GenericArg` and instead
27 make use of the safe [`GenericArgKind`](#genericargkind) abstraction.
28
29 ## `GenericArgKind`
30 As `GenericArg` itself is not type-safe, the `GenericArgKind` enum provides a more
31 convenient and safe interface for dealing with generic arguments. An
32 `GenericArgKind` can be converted to a raw `GenericArg` using `GenericArg::from()`
33 (or simply `.into()` when the context is clear). As mentioned earlier, substitution
34 lists store raw `GenericArg`s, so before dealing with them, it is preferable to
35 convert them to `GenericArgKind`s first. This is done by calling the `.unpack()`
36 method.
37
38 ```rust,ignore
39 // An example of unpacking and packing a generic argument.
40 fn deal_with_generic_arg<'tcx>(generic_arg: GenericArg<'tcx>) -> GenericArg<'tcx> {
41 // Unpack a raw `GenericArg` to deal with it safely.
42 let new_generic_arg: GenericArgKind<'tcx> = match generic_arg.unpack() {
43 GenericArgKind::Type(ty) => { /* ... */ }
44 GenericArgKind::Lifetime(lt) => { /* ... */ }
45 GenericArgKind::Const(ct) => { /* ... */ }
46 };
47 // Pack the `GenericArgKind` to store it in a substitution list.
48 new_generic_arg.into()
49 }
50 ```