Possible lifetime bug?

Is this valid?

struct Test<'a> {
    a: PhantomData<&'a usize>,
    x: usize,
}

trait DoIt<A> {
    fn do_it(&self) -> A;
}

impl<'a> DoIt<&'a usize> for Test<'a> where Self: 'a {
    fn do_it(&self) -> &'a usize {
        return &self.x;
    }
}

I get the compiler error: "cannot infer an appropriate lifetime ..."

I've got a workaround for my problem, but seems like the code should be acceptable.

The borrow of self could be arbitrarily short (shorter than 'a), and you can't extend that borrow to be longer when returning a borrow of the field.

It would compile with &'a self, but this may not meet your needs (lifetimes on traits are a yellow flag).

It would compile if you returned a usize instead.

Yeah, but on the impl line I have where Self: 'a

Also this compiles fine, but it is not quite what I am after:

struct Test<'a> {
    x: &'a usize,
}

trait DoIt<A> {
    fn do_it(&self) -> A;
}

impl<'a> DoIt<&'a usize> for Test<'a> where Self: 'a {
    fn do_it(&self) -> &'a usize {
        return &self.x;
    }
}

That means Self is valid for 'a. It doesn't mean the borrow (&self) will be 'a -- it could still be shorter. References can't last longer than what they point to, but shorter is fine.

1 Like

Understood. Thank you!

This does the trick for me too:

struct Test<'a> {
    a: PhantomData<&'a usize>,
    x: usize,
}

trait DoIt<A> {
    fn do_it(self) -> A;
}

impl<'a> DoIt<&'a usize> for &'a Test<'a> {
    fn do_it(self) -> &'a usize {
        return &self.x;
    }
}

(Removing the reference from the trait)

To elaborate further, the Self: 'a means that the struct does not contain any fields with a lifetime shorter than 'a.

3 Likes

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.