Box<dyn Animal<'a>> -> Box<Cat<'a>>


pub struct Cat<'a> {
    x: &'a u32,
}

pub trait Animal<'a> {
    fn into_any(self: Box<Self>) -> Box<dyn Any + 'a>;
}

impl<'a> Animal<'a> for Cat<'a> {
    fn into_any(self: Box<Self>) -> Box<dyn Any + 'a> {
        self
    }
}

fn conv<'a>(x: Box<dyn Animal<'a>>) -> Box<Cat<'a>> {
    x.into_any().downcast::<Cat<'a>>().unwrap()
}

Is there a way to make this code work? Without changing 'a to 'static ? If we drop the lifetime specifiers, everything appears to be fine. I can not figure out how to make it work with the lifetime specifiers.

Downcasting with non-'static lifetimes is very tricky because lifetimes do not exist at runtime and you could use the wrong lifetime when downcasting. There are some cases where this could work though, namely covariant lifetimes. Check out the better-any crate for this.

1 Like

no, it's not possible, Any trait is defined like this:

pub trait Any: 'static {
    fn type_id(&self) -> TypeId;
}

what are you trying to achieve? it make no sense to box a type with non 'static lifetime anyway.

2 Likes

Sure it does, and it's perfectly valid to do so. Off the top of my head, I remember boxing AST nodes in a parser I wrote, because the nodes were taking too much stack space and crashing the program in debug builds.

3 Likes

Something like https://docs.rs/better_any might work for you here.

1 Like

A common rick for decreasing crate dependency / increasing crate parallelism during compilation time (at the cost of a dynamic dispatch at runtime) is passing around Rc/Box<dyn Animal> instead of passing around a Cat (and downcast-ing it later).

Due to external crate, I'm suddenly in a situation where I want to apply this trick to a Cat<'a> instead of a Cat.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.