Open
Description
I'd like to write the following code:
use std::future::Future;
struct Foo<A>(A);
impl<A> Foo<A> {
fn bar<Q, R: Default>(&mut self, q: Q) -> impl Future<Output = R> {
let _ = q;
async move {
R::default()
}
}
fn baz(&mut self, x: &str) -> impl Future<Output = usize> {
self.bar(x)
}
}
In particular, I would like to have the impl Trait
returned by baz
not be tied to the lifetime of its &str
argument. Since impl Trait
captures the lifetimes of all generic arguments (as per RFC 1951), I can't write the code this way though. So instead, I tried
#![feature(type_alias_impl_trait)]
use std::future::Future;
struct Foo<A>(A);
type BarFut<A, R> = impl Future<Output = R>;
impl<A> Foo<A> {
fn bar<Q, R: Default>(&mut self, q: Q) -> BarFut<A, R> {
let _ = q;
async move {
R::default()
}
}
fn baz(&mut self, x: &str) -> impl Future<Output = usize> {
self.bar(x)
}
}
However, with this, I get the error:
error: type parameter `Q` is part of concrete type but not used in parameter list for the `impl Trait` type alias
This seems odd, since Q
is (intentionally) not used in the async
block. I can work around this by adding an async fn
and calling that instead of using async move
, but that seems like an odd hack:
async fn make_r_fut<R: Default>() -> R {
R::default()
}
// ...
fn bar<Q, R: Default>(&mut self, q: Q) -> BarFut<A, R> {
let _ = q;
make_r_fut()
}
// ...
Is it intentional that the async
block "captures" Q
here, even though it never contains a Q
?