Return a Result, containing a Struct, containing a Reference

I have a Struct:

pub struct Message<'a>(&'a [u8]);

and this is the usage of the struct:

impl<'a> FromPyObject<'a> for Message<'_> {
    fn extract(obj: &PyAny) -> PyResult<Self> {
        let messsge = obj
            .downcast_ref::<PyBytes>()
            .expect("Expected param to be an array of bytes");
        Ok(Message(messsge.as_bytes()))
    }
}

and the error I’m getting:

not sure how to specify the lifetime I need?
I will appreciate any advice!
Thanks!

Will the following signature help ?

impl<'a> FromPyObject<'a> for Message<'a> {
    fn extract(obj: &'a PyAny) -> PyResult<Self> {

I am basically wiring up the obj lifetime with Message’s lifetime
parameter.

1 Like

Yes.
In fact that did help immensely.

Thank you very much.
looks like I need to brush up on how lifetimes work.

Lifetimes don’t do anything. :slight_smile: They are only annotations that the compiler can use to prove the code is memory safe.

The suggested solution ties the lifetimes of all references together, which informs the compiler that the reference in the return value is dependent upon 'a defined in the struct. The original code makes the lifetimes independent, allowing the compiler to choose the smallest possible lifetime for obj (which is in opposition to the lifetime required by the function signature).

Ahh I think I understand.
So adding that 'a to the extract function tells the compiler that obj must survive for the 'a lifetime, and since my return object contains a reference to obj it inherits the lifetime, and thus, the compiler now knows the lifetime of the return type, and the error goes away?

1 Like

That is basically correct. The return value doesn’t inherit a lifetime implicitly; the function signature explicitly says which lifetime it must be valid for. Which when desugared is PyResult<Message<'a>>