Fascinating! I was actually able to compile the library itself without GATs being enabled:
pub trait HandlerFnLifetime<'yielder, T, ImplicitBounds: Sealed = Bounds<Yielder<'yielder, T>>> {
type Fut: Future<Output = ()> + 'yielder;
}
/// [`Future`] generator that can be converted to [`Stream`].
///
/// [`Stream`]: futures_util::stream::Stream
pub trait HandlerFn<'scope, T: 'scope>: for<'yielder> HandlerFnLifetime<'yielder, T> {
/// Create new [`Future`] with the provided [`Yielder`] as a [`Stream`] item source.
///
/// `'yielder` lifetime is defined inside of library internals,
/// thus you are not allowed to use it to access outer scope elements.
///
/// However, for those cases [`HandlerFn`] provides you with `'scope` lifetime,
/// which is required to outlive `'yielder`.
///
/// [`Stream`]: futures_util::stream::Stream
fn call<'yielder>(self, yielder: Yielder<'yielder, T>) -> <Self as HandlerFnLifetime<'yielder, T>>::Fut
where
'scope: 'yielder;
}
However, when I tried to port an example to use HandlerFnLifetime
, I've got an error that looks
suspiciously similar to #70263:
struct StreamState<'a> {
val: &'a str
}
impl<'yielder, 'scope: 'yielder, T: 'scope> HandlerFnLifetime<'yielder, T> for StreamState<'scope> {
type Fut = impl Future<Output = ()> + 'yielder;
}
impl<'scope> HandlerFn<'scope, &'scope str> for StreamState<'scope> {
fn call<'yielder>(self, mut yielder: Yielder<'yielder, &'scope str>) -> <Self as HandlerFnLifetime<'yielder, &'scope str>>::Fut
where
'scope: 'yielder
{
async move {
yielder.yield_item(self.val).await;
}
}
}
error: implementation of `HandlerFnLifetime` is not general enough
--> src/lib.rs:21:14
|
19 | impl<'scope> HandlerFn<'scope, &'scope str> for StreamState<'scope> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `HandlerFnLifetime` is not general enough
|
= note: `HandlerFnLifetime<'0, &'scope str>` would have to be implemented for the type `StreamState<'scope>`, for any lifetime `'0`...
= note: ...but `HandlerFnLifetime<'_, &'scope str>` is actually implemented for the type `StreamState<'1>`, for some specific lifetime `'1`
I tried adding the 'scope
lifetime itself to HandlerFnLifetime
(just to try it out), however, that didn't help:
pub trait HandlerFnLifetime<'yielder, 'scope: 'yielder, T: 'scope, ImplicitBounds: Sealed = Bounds<Yielder<'yielder, T>>> {
type Fut: Future<Output = ()> + 'yielder;
}
/// [`Future`] generator that can be converted to [`Stream`].
///
/// [`Stream`]: futures_util::stream::Stream
pub trait HandlerFn<'scope, T: 'scope>: for<'yielder> HandlerFnLifetime<'yielder, 'scope, T> {
/// Create new [`Future`] with the provided [`Yielder`] as a [`Stream`] item source.
///
/// `'yielder` lifetime is defined inside of library internals,
/// thus you are not allowed to use it to access outer scope elements.
///
/// However, for those cases [`HandlerFn`] provides you with `'scope` lifetime,
/// which is required to outlive `'yielder`.
///
/// [`Stream`]: futures_util::stream::Stream
fn call<'yielder>(self, yielder: Yielder<'yielder, T>) -> <Self as HandlerFnLifetime<'yielder, 'scope, T>>::Fut
where
'scope: 'yielder;
}
impl<'yielder, 'scope: 'yielder, T: 'scope> HandlerFnLifetime<'yielder, 'scope, T> for StreamState<'scope> {
type Fut = impl Future<Output = ()> + 'yielder;
}
impl<'scope> HandlerFn<'scope, &'scope str> for StreamState<'scope> {
fn call<'yielder>(self, mut yielder: Yielder<'yielder, &'scope str>) -> <Self as HandlerFnLifetime<'yielder, 'scope, &'scope str>>::Fut
where
'scope: 'yielder
{
async move {
yielder.yield_item(self.val).await;
}
}
}
error: implementation of `HandlerFnLifetime` is not general enough
--> src/lib.rs:21:14
|
19 | impl<'scope> HandlerFn<'scope, &'scope str> for StreamState<'scope> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `HandlerFnLifetime` is not general enough
|
= note: `HandlerFnLifetime<'0, 'scope, &'scope str>` would have to be implemented for the type `StreamState<'scope>`, for any lifetime `'0`...
= note: ...but `HandlerFnLifetime<'_, '1, &'scope str>` is actually implemented for the type `StreamState<'1>`, for some specific lifetime `'1`