- Traditional notation: ∃x: P(x). Read as "there exists x such that P(x) holds".
In Rust, they come up in type checking and trait solving. For example,
```rust,ignore
fn foo<T>()
```
This function claims that the function is well-typed for all types `T`: `∀ T: well_typed(foo)`.
Another example:
```rust,ignore
fn foo<'a>(_: &'a usize)
```
This function claims that for any lifetime `'a` (determined by the
caller), it is well-typed: `∀ 'a: well_typed(foo)`.
Another example:
```rust,ignore
fn foo<F>()
where for<'a> F: Fn(&'a u8)
```
This function claims that it is well-typed for all types `F` such that for all
lifetimes `'a`, `F: Fn(&'a u8)`: `∀ F: ∀ 'a: (F: Fn(&'a u8)) => well_typed(foo)`.
One more example:
```rust,ignore
fn foo(_: dyn Debug)
```
This function claims that there exists some type `T` that implements `Debug`
such that the function is well-typed: `∃ T: (T: Debug) and well_typed(foo)`.
<a id="variance"></a>
## What is a de Bruijn Index?
[De Bruijn indices][wikideb] are a way of representing, using only integers,
which variables are bound in which binders. They were originally invented for
use in lambda calculus evaluation (see [this Wikipedia article][wikideb] for
more). In `rustc`, we use de Bruijn indices to [represent generic types][sub].
Here is a basic example of how de Bruijn indices might be used for closures (we
don't actually do this in `rustc` though!):
```rust,ignore
|x| {
f(x) // de Bruijn index of `x` is 1 because `x` is bound 1 level up
|y| {
g(x, y) // index of `x` is 2 because it is bound 2 levels up
// index of `y` is 1 because it is bound 1 level up
}
}
```
## What are co- and contra-variance?
Check out the subtyping chapter from the
[Rust Nomicon](https://doc.rust-lang.org/nomicon/subtyping.html).
See the [variance](../variance.html) chapter of this guide for more info on how
the type checker handles variance.
<a id="free-vs-bound"></a>
## What is a "free region" or a "free variable"? What about "bound region"?
Let's describe the concepts of free vs bound in terms of program
variables, since that's the thing we're most familiar with.
- Consider this expression, which creates a closure: `|a, b| a + b`.
Here, the `a` and `b` in `a + b` refer to the arguments that the closure will
be given when it is called. We say that the `a` and `b` there are **bound** to
the closure, and that the closure signature `|a, b|` is a **binder** for the
names `a` and `b` (because any references to `a` or `b` within refer to the
variables that it introduces).
- Consider this expression: `a + b`. In this expression, `a` and `b` refer to
local variables that are defined *outside* of the expression. We say that
those variables **appear free** in the expression (i.e., they are **free**,