I have defined the following trait:

trait Read<T> {
    fn next_row<'c>(&'c mut self) -> Result<std::option::Option<T>>;
}

(obviously 'c would be elided but I just want to be able to refer to it later)

I have implemented this for a struct, ReaderA, to return an owned value:

struct ReaderA {
    data: Vec<Vec<u8>>
}

impl Read<Vec<u8>> for ReaderA {
    fn next_row<'c>(&'c mut self) -> Result<std::option::Option<Vec<u8>>> {
        Ok(self.data.pop())
    }
}

Unsurprisingly, this works perfectly. The problem occurs when I try to implement this for some struct ReaderB to return a borrowed value:

struct ReaderB {
    data: Vec<Vec<u8>>
}

impl Read<&Vec<u8>> for ReaderB {
    fn next_row<'c>(&'c mut self) -> Result<std::option::Option<&'c Vec<u8>>> {
        Ok(self.data.first())
    }
}

This doesn't work. The signature doesn't match the definition because the trait doesn't expect 'c to be included in the return value. What am I doing wrong?

I could potentially add the lifetime as a trait generic parameter, however this feels unnecessary: I don't want to specify some other lifetime, I just want it to share the lifetime of the &mut self borrow (I think). I also would far rather not have to include a lifetime in every implementation of the trait and PhantomData in every struct, even when they don't return a borrowed value. I also don't want to run into something like this, but I don't really understand what I'm doing.

I feel this may be something to do with HRTB, however I can't work out how to get that to work.

I am somewhat lost with lifetimes, so please include as much detail as possible in your answer.

Source: View source