| 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 instantiated 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 instantiated with 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`). |