The code fails to compile:
fn main() {
trait Tr<'a, 'b> {}
impl<'a> Tr<'a, 'static> for &'a i32 {}
fn a<'a>(n: &'a i32) -> Box<dyn Tr + 'a> {
Box::new(n)
}
}
reporting:
error: lifetime may not live long enough
--> src/main.rs:161:9
|
160 | fn a<'a>(n: &'a i32) -> Box<dyn Tr + 'a> {
| -- lifetime `'a` defined here
161 | Box::new(n)
| ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: could not compile `rust-test` due to previous error
I wander why it is necessary for 'a : 'static.
To my understanding, Tr<'a, 'static> means some type, say T, must satisfies both 'a : 'T and 'static : 'T, effectively 'a : T is enough because 'static : 'a for any 'a.
dyn Tr borrows T, so T outlives dyn Tr is required, Box<dyn Tr + 'a> is enough for soundness.
I do know the rule of Lifetime elision - The Rust Reference
If the trait object is used as a type argument of a generic type then the containing type is first used to try to infer a bound.
- If there is a unique bound from the containing type then that is the default
- If there is more than one bound from the containing type then an explicit bound must be specified
If neither of those rules apply, then the bounds on the trait are used:
- If the trait is defined with a single lifetime bound then that bound is used.
- If
'static
is used for any lifetime bound then'static
is used.- If the trait has no lifetime bounds, then the lifetime is inferred in expressions and is
'static
outside of expressions.
And the above code hits If 'static is used for any lifetime bound then 'static is used.
In fact, to verify the rule is why the code was written.
Well, I still don't know why the rule is reasonable,