Without the '_ this fails to compile, but I do not understand why. It complains with this error:
11 | pub fn convert<'a, T: 'static>(f: &'a dyn Foo) {
| -- - `f` is a reference that is only valid in the function body
| |
| lifetime `'a` defined here
12 | f.get::<T>().unwrap();
| ^^^^^^^^^^^^
| |
| `f` escapes the function body here
| argument requires that `'a` must outlive `'static`
But get takes a reference, so what is being moved? Does someone know what is going on?
Every dyn Trait has a lifetime parameter (dyn Trait + 'dyn) which has its own special elision rules when entirely omitted. The rules are context sensitive.
So you tried to call <dyn Foo + 'static>::get(f) but you only had a dyn Foo + 'dyn. The error pointed to the reference because those lifetimes have to be the same.
With the change
impl dyn Foo + '_ { // <----- here
dyn Foo + 'dyn has the get method for every 'dyn, and not just dyn Foo + 'static.
One thing that I am not sure about is, why does it talk about the reference escaping? Is it because I am trying to 'extend' the lifetime to 'static without being allowed to?
Yeah, something like that. The error would make more sense to me if get directly required a &'static dyn Foo, because methods with 'static bounds often have them so they can do things like send the value to another thread (which might run "forever").
The error is a little off here IMO because get takes a &'any_lifetime (dyn Foo + 'static), and it's only the function signature of convert that implicitly required the reference lifetime be 'static. A better compiler error would point out that the actual mismatch was with the elided trait object lifetime.
Alright, well the reason I ran into this was because of <dyn std::error::Error>::downcast_ref, so I feel this might not be able to be solved like this...
The only thing I can see is that Any requires 'static on itself, whereas Error only needs 'static for T in downcast_ref?
The 'static bound on the trait makes the default trait object lifetime for dyn Any be 'static everywhere [1], so the signature of convert2 is already akin to the diff above.
that I have tried; running more exhaustive tests is actually high on my todo list âŠī¸
oh my god. You are saving me here hahaha, I was afraid that it would be impossible to use in my situation. I'll see if it appeases the compiler. Thank you again!