]> git.proxmox.com Git - rustc.git/blame - 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
CommitLineData
a1dfa0c6
XL
1# Parameter Environment
2
6a06907d 3When working with associated and/or generic items (types, constants,
a1dfa0c6
XL
4functions/methods) it is often relevant to have more information about the
5`Self` or generic parameters. Trait bounds and similar information is encoded in
ba9703b0 6the [`ParamEnv`][pe]. Often this is not enough information to obtain things like the
a1dfa0c6
XL
7type's `Layout`, but you can do all kinds of other checks on it (e.g. whether a
8type implements `Copy`) or you can evaluate an associated constant whose value
9does not depend on anything from the parameter environment.
10
ba9703b0
XL
11[pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.ParamEnv.html
12
a1dfa0c6
XL
13For example if you have a function
14
15```rust
ba9703b0 16fn foo<T: Copy>(t: T) { ... }
a1dfa0c6
XL
17```
18
19the parameter environment for that function is `[T: Copy]`. This means any
20evaluation within this function will, when accessing the type `T`, know about
21its `Copy` bound via the parameter environment.
22
ba9703b0
XL
23You can get the parameter environment for a `def_id` using the
24[`param_env`][query] query. However, this `ParamEnv` can be too generic for
25your use case. Using the `ParamEnv` from the surrounding context can allow you
26to evaluate more things. For example, suppose we had something the following:
27
6a06907d 28[query]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ty_utils/ty/fn.param_env.html
ba9703b0
XL
29
30```rust
31trait Foo {
32 type Assoc;
33}
34
35trait Bar { }
36
37trait Baz {
38 fn stuff() -> bool;
39}
40
41fn foo<T>(t: T)
42where
43 T: Foo,
44 <T as Foo>::Assoc: Bar
45{
46 bar::<T::Assoc>()
47}
48
49fn bar<T: Baz>() {
50 if T::stuff() { mep() } else { mop() }
51}
52```
53
54We 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
56is a contrived example that makes no sense in our existing analyses, but we may
57run into similar cases when doing analyses with associated constants on generic
58traits or traits with assoc types.
59
60## Bundling
a1dfa0c6
XL
61
62Another great thing about `ParamEnv` is that you can use it to bundle the thing
ba9703b0
XL
63depending on generic parameters (e.g. a `Ty`) by calling the [`and`][and]
64method. This will produce a [`ParamEnvAnd<Ty>`][pea], making clear that you
65should probably not be using the inner value without taking care to also use
66the [`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