Having trouble understanding GAT-related lifetime issue

I'm not even totally sure this is exclusively related to GATs, but I haven't found a way to reproduce it w/o them:

trait Slice {
    type S<'a>: Copy
    where
        Self: 'a;
}

struct Foo<'a, L: Slice + 'a> {
    foo: L::S<'a>,
}

impl<'a, L: Slice + 'a> Foo<'a, L> {
    fn foo(&self) -> L::S<'_> {
        self.foo
    }
}

I would expect this code to compile but I'm getting a lifetime error in the body of the foo() function. It still doesn't work even if I annotate the lifetime explicitly:

impl<'a, L: Slice + 'a> Foo<'a, L> {
    fn foo<'b>(&'b self) -> L::S<'b>
    where
        'a: 'b,
    {
        // 'a lives longer than 'b, so why can't it be coerced down to 'b?
        self.foo
    }
}

Same code in a playground.

What am I missing?

Huh, that error is backwards.

The issue is that S<'a> might not be covariant -- it might not be sound to coerce it to a S<'1> (the input lifetime).

You can return an L::S<'a> instead. I included an example of why this is needed.

2 Likes

If you need the covariance, you can make it part of the trait.

2 Likes

Filed a diagnostics report.

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.