Understanding Rust Error E0311: Unsatisfied Outlives Bounds
Introduction to Rust Error E0311
Rust Error E0311 occurs when there is an unsatisfied outlives bound involving an elided region and a generic type parameter or associated type. In this article, we'll examine the origins of this error, analyze the provided erroneous code example, explain the reasons behind the error, and demonstrate how to fix it.
Analyzing the Erroneous Code Example
Consider the following erroneous code example:
#![allow(unused)]
fn main() {
fn no_restriction<T>(x: &()) -> &() {
with_restriction::<T>(x)
}
fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
x
}
}
Why this Code Doesn't Compile
First, let's understand the lifetime bounds that the compiler automatically adds. We'll then dive into lifetime elision in detail. The compiler elides the lifetime of x and the return type to some arbitrary lifetime 'anon in no_restriction(). The only information available to the compiler is that 'anon is valid for the duration of the function. When calling with_restriction(), the compiler requires the completely unrelated type parameter T to outlive 'anon because of the T: 'a bound in with_restriction(). This causes an error because T is not required to outlive 'anon in no_restriction().
Possible Solution
This error can be resolved by explicitly naming the elided lifetime for x and then explicitly requiring that the generic parameter T outlives that lifetime. By implementing this fix, the corrected code will look like this:
#![allow(unused)]
fn main() {
fn no_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
with_restriction::<T>(x)
}
fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
x
}
}
In this corrected version, we've explicitly specified the lifetime 'a for both the argument and return type of the function no_restriction() and the generic parameter T is explicitly marked to outlive the lifetime 'a.