Open
Description
I tried this code (playground):
use std::future::Future;
fn hrc<
R,
F: for<'a> AsyncClosure<'a, (), R>
+ for<'a> Fn(&'a ()) -> <F as AsyncClosure<'a, (), R>>::Fut,
>(
f: F,
) -> F {
f
}
fn main() {
hrc(|x| async { });
}
trait AsyncClosure<'a, I, R>: Fn(&'a I) -> Self::Fut
where
I: 'a,
{
type Fut: Future<Output = R> + Send + 'a;
}
impl<'a, I, R, Fut, F> AsyncClosure<'a, I, R> for F
where
I: 'a,
F: Fn(&'a I) -> Fut,
Fut: Future<Output = R> + Send + 'a,
{
type Fut = Fut;
}
Trying to compile it produces the following error:
error[[E0644]](https://doc.rust-lang.org/stable/error-index.html#E0644): closure/generator type that references itself
--> src/main.rs:14:9
|
14 | hrc(|x| async { });
| ^^^^^^^^^^^^^ cyclic type of infinite size
|
= note: closures cannot capture themselves or take themselves as argument;
this error may be the result of a recent compiler bug-fix,
see issue #46062 <https://github.com/rust-lang/rust/issues/46062>
for more information
I’m not sure if it should compile, but the diagnostic is misleading either way: this closure doesn’t have infinite size (in fact, it’s zero-sized), doesn’t capture itself (it captures nothing) and doesn’t take itself as argument (it only takes ()
).
I don’t see a reason why it shouldn’t compile though, since all the types are known without evaluating the recursive bound on hrc()
.
Meta
This bug is reproducible on playground on stable, beta and nightly (1.61.0, 1.62.0-beta3 and 1.63.0-nightly (2022-06-02 e714405) respectively)
Links
- Tracking issue for closure types that reference themselves #46062 is mentioned in the error description
- The code is trying to work around HRTBs: "implementation is not general enough", but it is #70263 for async closures