Rust errors / Ownership and borrowing
Rust compiler error · checked with rustc 1.99.0
Rust error E0794: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
What it meansA lifetime parameter of a function definition is called *late-bound* if it both:
What rustc prints
error[E0794]: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present --> main.rs:4:15 | 4 | let _ = foo::<'static>; | ^^^^^^^ | note: the late bound lifetime parameter is introduced here --> main.rs:3:8 | 3 | fn foo<'a>(x: &'a str) -> &'a str { x } | ^^
Real output of rustc 1.99.0 compiling the official example below (2021 edition). Your names and line numbers will differ; the first line is the part to match.
The compiler team's explanation
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:
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), although the types that are constrained by early-bound parameters can be specified (as for bar_fn3).
From rustc --explain E0794 (1.99.0), part of the Rust project, MIT or Apache-2.0. Official page.
Related errors
- E0382borrow of moved value
- E0499cannot borrow as mutable more than once at a time
- E0502cannot borrow as mutable because it is also borrowed as immutable
- E0106missing lifetime specifier
- E0747type provided when a lifetime was expected
- E0764mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed
- E0803cannot infer an appropriate lifetime for lifetime parameter '_ in generic type due to conflicting requirements
Up next
Often hit nextE0382: borrow of moved valueA related error from the same family.Read it next →Did this answer your question?