]> git.proxmox.com Git - rustc.git/blob - src/doc/rustc-dev-guide/src/param_env.md
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / src / doc / rustc-dev-guide / src / param_env.md
1 # Parameter Environment
2
3 When working with associated and/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`][pe]. 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 [pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html
12
13 For example if you have a function
14
15 ```rust
16 fn foo<T: Copy>(t: T) { ... }
17 ```
18
19 the parameter environment for that function is `[T: Copy]`. This means any
20 evaluation within this function will, when accessing the type `T`, know about
21 its `Copy` bound via the parameter environment.
22
23 You can get the parameter environment for a `def_id` using the
24 [`param_env`][query] query. However, this `ParamEnv` can be too generic for
25 your use case. Using the `ParamEnv` from the surrounding context can allow you
26 to evaluate more things. For example, suppose we had something the following:
27
28 [query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ty_utils/ty/fn.param_env.html
29
30 ```rust
31 trait Foo {
32 type Assoc;
33 }
34
35 trait Bar { }
36
37 trait Baz {
38 fn stuff() -> bool;
39 }
40
41 fn foo<T>(t: T)
42 where
43 T: Foo,
44 <T as Foo>::Assoc: Bar
45 {
46 bar::<T::Assoc>()
47 }
48
49 fn bar<T: Baz>() {
50 if T::stuff() { mep() } else { mop() }
51 }
52 ```
53
54 We may know some things inside `bar` that we wouldn't know if we just fetched
55 `bar`'s param env because of the `<T as Foo>::Assoc: Bar` bound in `foo`. This
56 is a contrived example that makes no sense in our existing analyses, but we may
57 run into similar cases when doing analyses with associated constants on generic
58 traits or traits with assoc types.
59
60 ## Bundling
61
62 Another great thing about `ParamEnv` is that you can use it to bundle the thing
63 depending on generic parameters (e.g. a `Ty`) by calling the [`and`][and]
64 method. This will produce a [`ParamEnvAnd<Ty>`][pea], making clear that you
65 should probably not be using the inner value without taking care to also use
66 the [`ParamEnv`][pe].
67
68 [and]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html#method.and
69 [pea]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnvAnd.html