#![feature(generic_associated_types)]
trait Foo<'ctx, 'env> {
type X: Send + Sync + 'env
where
'env: 'ctx;
}
fn foo<'ctx, 'env: 'ctx, T: Foo<'ctx, 'env>>(x: T::X) -> impl Send + 'env + 'ctx {
async move {
let x = x; // x has type T::X which is Send + Sync
std::future::ready(()).await; // remove this line then it compiles ok.
}
}
I think it's a bug and filed a issue. But got no reply for really long time.
Also, I've found an even clearer example of this issue with 'static:
#![feature(generators)]
#![feature(generic_associated_types)]
pub trait Trait<'a> {
type Type: Send
where
'a: 'static;
}
pub fn foo<T: Trait<'static>>(x: <T as Trait<'static>>::Type) {
fn assert_send<T: Send + ?Sized>(_: &T) {}
assert_send(&x);
let _gen = || {
let _x = x;
yield
};
//assert_send(&_gen);
// error[E0478]: lifetime bound not satisfied
// note: but lifetime parameter must outlive the static lifetime
}
The partial note in the error message could point to something weird happening between the generator type (created only in the MIR) and the associated diagnostics.
Even simpler example, which I think should be the same issue.
#![feature(generators)]
use std::marker::PhantomData;
pub struct T<'a>(PhantomData<*mut &'a ()>);
unsafe impl Send for T<'static> {}
pub fn foo(x: T<'static>) {
fn assert_send<T: Send + ?Sized>(_: &T) {}
assert_send(&x);
let _gen = move || {
let _x = x;
yield
};
assert_send(&_gen);
// error: implementation of `Send` is not general enough
// note: `T<'0>` must implement `Send`, for any lifetime `'0`...
// note: ...but `Send` is actually implemented for the type `T<'static>`
}