summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_error_codes/src/error_codes/E0794.md
blob: c8f73de95a214c74ba609cd1e6ce427bd6be5efe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
A lifetime parameter of a function definition is called *late-bound* if it both:

1. appears in an argument type
2. does not appear in a generic type constraint

You cannot specify lifetime arguments for late-bound lifetime parameters.

Erroneous code example:

```compile_fail,E0794
fn foo<'a>(x: &'a str) -> &'a str { x }
let _ = foo::<'static>;
```

The type of a concrete instance of a generic function is universally quantified
over late-bound lifetime parameters. This is because we want the function to
work for any lifetime substituted for the late-bound lifetime parameter, no
matter where the function is called. Consequently, it doesn't make sense to
specify arguments for late-bound lifetime parameters, since they are not
resolved until the function's call site(s).

To fix the issue, remove the specified lifetime:

```
fn foo<'a>(x: &'a str) -> &'a str { x }
let _ = foo;
```

### Additional information

Lifetime parameters that are not late-bound are called *early-bound*.
Confusion may arise from the fact that late-bound and early-bound
lifetime parameters are declared the same way in function definitions.
When referring to a function pointer type, universal quantification over
late-bound lifetime parameters can be made explicit:

```
trait BarTrait<'a> {}

struct Bar<'a> {
    s: &'a str
}

impl<'a> BarTrait<'a> for Bar<'a> {}

fn bar<'a, 'b, T>(x: &'a str, _t: T) -> &'a str
where T: BarTrait<'b>
{
    x
}

let bar_fn: for<'a> fn(&'a str, Bar<'static>) -> &'a str = bar; // OK
let bar_fn2 = bar::<'static, Bar>; // Not allowed
let bar_fn3 = bar::<Bar>; // OK
```

In the definition of `bar`, the lifetime parameter `'a` is late-bound, while
`'b` is early-bound. This is reflected in the type annotation for `bar_fn`,
where `'a` is universally quantified and `'b` is substituted by a specific
lifetime. It is not allowed to explicitly specify early-bound lifetime
arguments when late-bound lifetime parameters are present (as for `bar_fn2`,
see [issue #42868](https://github.com/rust-lang/rust/issues/42868)), although
the types that are constrained by early-bound parameters can be specified (as
for `bar_fn3`).