Skip to content

Commit 13f86ff

Browse files
mark-i-mJohnTitor
andauthored
Add some more info to param_env (#610)
* add some more info to param_env * Remove some trailing spaces Co-authored-by: Yuki Okushi <[email protected]>
1 parent acd3923 commit 13f86ff

File tree

1 file changed

+49
-10
lines changed

1 file changed

+49
-10
lines changed

src/param_env.md

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,67 @@
33
When working with associated and/or or generic items (types, constants,
44
functions/methods) it is often relevant to have more information about the
55
`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
6+
the [`ParamEnv`][pe]. Often this is not enough information to obtain things like the
77
type's `Layout`, but you can do all kinds of other checks on it (e.g. whether a
88
type implements `Copy`) or you can evaluate an associated constant whose value
99
does not depend on anything from the parameter environment.
1010

11+
[pe]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/struct.ParamEnv.html
12+
1113
For example if you have a function
1214

1315
```rust
14-
fn foo<T: Copy>(t: T) {
15-
}
16+
fn foo<T: Copy>(t: T) { ... }
1617
```
1718

1819
the parameter environment for that function is `[T: Copy]`. This means any
1920
evaluation within this function will, when accessing the type `T`, know about
2021
its `Copy` bound via the parameter environment.
2122

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.
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/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
2661

2762
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`.
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/ty/struct.ParamEnv.html#method.and
69+
[pea]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/struct.ParamEnvAnd.html

0 commit comments

Comments
 (0)