Assume having a typical example of GAT, referencing iterator:
#![feature(generic_associated_types)]
use std::ops::Deref;
trait MyIterator {
type Item<'a>
where
Self: 'a;
fn next(&mut self) -> Self::Item<'_>;
}
For example, I can implement this for Box<T>.
// This is OK
impl<U> MyIterator for Box<U> {
type Item<'a> = &'a U
where
Self: 'a;
fn next(&mut self) -> Self::Item<'_> {
<Box<T> as Deref>::deref(self)
}
}
But not when I generalize it with Deref trait:
// error[E0309]: the parameter type `U` may not live long enough
impl<T, U> MyIterator for T
where
T: Deref<Target = U>,
{
type Item<'a> = &'a U
where
Self: 'a;
fn next(&mut self) -> Self::Item<'_> {
<T as Deref>::deref(self)
}
}
In my understanding, in the Box<T> case compiler somehow knows that the type U is owned by Box<U> so U is assured to live longer than Box<U>. So if Box<U>: 'a then the compiler can say U: 'a.
But this logic is not working for the Deref<Target=U> case even though Deref has deref(&self) -> &Self::Target method, which is implying that for any lifetime T: 'a then U: 'a.
How can I tell the compiler that the latter case is actually safe?