I tried to make ‘long’ greater than ‘longest’. This obviously should be reported as an error, but it was not reported. Why?
fn test_lifetime<'long, 'longer, 'longest>(a: &'long str, b: &'longer str, c: &'longest str) where
'long: 'longest
{
println!("{}, {}, {}", a, b, c);
}
fn main() {
let longest = String::from("longest");
{
let longer = String::from("longer");
{
let long = String::from("long");
test_lifetime(long.as_str(), longer.as_str(), longest.as_str());
}
}
}
>Solution :
This is not an error for two reasons:
- The lifetimes
'long,'longerand'longestrefer to the borrows, not the values in the variableslong,longerandlongest; - Rust will try to find lifetimes that satisfy certain constraints. This means that if it compiles, it is possible to find lifetimes that do satisfy these constraints.
So, in this case, a possible set of lifetimes that satisfies all the constraints is simply:
fn main() {
let longest = String::from("longest");
{
let longer = String::from("longer");
{
let long = String::from("long");
// ------\
test_lifetime( // |
long.as_str(), // |
longer.as_str(), // |-- 'long = 'longer = 'longest
longest.as_str() // |
); // |
// ------/
}
}
}
Indeed, longest.as_str() just creates a &str that has to live less than longest, but it can be as short as the one created by long.as_str(). This is also compatible with your constraints, since 'a: 'a for all 'a (subtyping is reflexive).