]>
Commit | Line | Data |
---|---|---|
a1dfa0c6 XL |
1 | # Parameter Environment |
2 | ||
3 | When working with associated and/or or generic items (types, constants, | |
4 | functions/methods) it is often relevant to have more information about the | |
5 | `Self` or generic parameters. Trait bounds and similar information is encoded in | |
6 | the `ParamEnv`. Often this is not enough information to obtain things like the | |
7 | type's `Layout`, but you can do all kinds of other checks on it (e.g. whether a | |
8 | type implements `Copy`) or you can evaluate an associated constant whose value | |
9 | does not depend on anything from the parameter environment. | |
10 | ||
11 | For example if you have a function | |
12 | ||
13 | ```rust | |
14 | fn foo<T: Copy>(t: T) { | |
15 | } | |
16 | ``` | |
17 | ||
18 | the parameter environment for that function is `[T: Copy]`. This means any | |
19 | evaluation within this function will, when accessing the type `T`, know about | |
20 | its `Copy` bound via the parameter environment. | |
21 | ||
22 | Although you can obtain a valid `ParamEnv` for any item via | |
23 | `tcx.param_env(def_id)`, this `ParamEnv` can be too generic for your use case. | |
24 | Using the `ParamEnv` from the surrounding context can allow you to evaluate more | |
25 | things. | |
26 | ||
27 | Another great thing about `ParamEnv` is that you can use it to bundle the thing | |
28 | depending on generic parameters (e.g. a `Ty`) by calling `param_env.and(ty)`. | |
29 | This will produce a `ParamEnvAnd<Ty>`, making clear that you should probably not | |
30 | be using the inner value without taking care to also use the `ParamEnv`. |