Lifetime error with Any conversion

Here is a fairly accurate example of what I'm running into at the moment Playground:

use std::any::Any;

trait BarT {}

struct Bar {}
impl BarT for Bar {}

struct Foo<T: BarT> {
    bar: T
}

impl <T: BarT> Foo<T> {
    fn as_any(&mut self) -> &mut dyn Any {
        self
    }
    
    fn as_specific_foo(&mut self) -> &mut Foo<Bar> {
        self.as_any().downcast_mut::<Foo<Bar>>().unwrap()
    }
}

fn main() {
    let foo = Foo{bar: Bar{}};
}

Any tips on fixing the lifetime error? I don't think I can actually follow the compiler's advice of marking it 'static..

The compiler wants:

impl <T: BarT + 'static> Foo<T> {

which means the type T is not allowed to contain temporary references inside. This is necessary, because otherwise Any casts would create loopholes in borrow checking and safety.

You don't need to make reference to Any static. Just "content" of Any must be owned or otherwise non-temporary.

1 Like

oh - and that actually is okay here since Foo owns T?

Yes, and Bar{} doesn't hold any references, so it meets 'static requirement.

1 Like

so back to basics - 'static doesn't just mean "reference alive for the lifetime of the program", but also "owned values" ?

Sort-of. Lifetimes apply only to references, so if something doesn't have any references, it can pretend to satisfy any lifetime.

1 Like

You can slightly modify "reference alive for the lifetime of the program" to "values that can stay alive for the lifetime of the program", and you get the correct interpretation.

2 Likes

Though in this snippet:

T isn't actually alive for the lifetime of the program?

Keyword "can". There's nothing stopping Foo from keeping the value of type T alive for the entire program, which is the key detail. The fact that your Foo is dropped at the end of main and thus not actually alive for that long is not important — you could have leaked the memory instead and it would still compile.

1 Like

ahhh, thanks!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.