I am trying to implement a trait with a generic associated type for a struct with a generic type. I'm using nightly version 1.47.0-nightly (2020-07-20 f9a3086363f214f2b56b)
.
I have structs S1
and S2
, a trait with a GAT, and an implementation:
#![allow(incomplete_features)]
#![feature(generic_associated_types)]
use core::marker::PhantomData;
struct S1<T>(PhantomData<T>);
struct S2<'a, T: 'a>(PhantomData<(T, &'a ())>);
trait MyTrait {
type A<'a>;
}
impl MyTrait for S1<f64> {
type A<'a> = S2<'a, f64>;
}
This works, but I want to implement the trait for a generic T
:
impl<T> MyTrait for S1<T> {
type A<'a> = S2<'a, T>;
}
I now need to indicate that T
lives as long as 'a
, as is required by the definition of S2
:
error[E0309]: the parameter type `T` may not live long enough
--> src/lib.rs:14:5
|
13 | impl<T> MyTrait for S1<T> {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
14 | type A<'a> = S2<'a, T>;
| ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
How can this be done?
I found Generic associated type may not live long enough, but it might be outdated as it claims that the code is not yet implemented. But then, why does complex code like this compile (and work as expected)?
T
is fixed for the entire implementation, and that includes its lifetime. However, the lifetime'a
can vary at the point it is used. If you need the lifetime ofT
to be longer than'a
then this has to be true for all possible lifetimes. Without changing something else in that implementation, the only lifetime thatT
can have is therefore'static
:That is,
T
cannot contain any references apart from references to static variables.Please also bear in mind that GATs are not yet stabilised and the feature is likely still incomplete. It's at the stage where you can play around with it to get a feel for what it can do, but not ready for the real world yet.