Closed
Description
I've been working on a functional interface for a library which relies on code generation, so I have functions returning functions, however I've hit a roadblock with functions returning closures which return traits (without resorting to dynamic dispatch).
The compiler doesn't allow impl Fn() -> impl Trait
while allowing impl Trait<T = impl Trait>
which seems inconsistent.
Here is my minimal reproduction code:
// This works of course
fn closure() -> impl Fn() -> bool {
let f = || true;
f
}
// Error
// `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
fn future_closure() -> impl Fn() -> impl Future<Output = bool> {
let f = || async { true };
f
}
// Same error
fn future_closure_arg(arg: impl Fn() -> impl Future<Output = bool>) {}
// This works though
fn iter_impl(arg: impl Iterator<Item = impl Future<Output = bool>>) {}
However, seems like wrapping the Fn in another trait fixes the error, so this doesn't appear to be a functionality limitation but more of an oversight:
// This compiles fine
trait Func {
type T;
fn call(&self) -> Self::T;
}
impl<F: Fn() -> R, R> Func for F {
type T = R;
fn call(&self) -> Self::T {
self()
}
}
fn future_trait_closure() -> impl Func<T = impl Future<Output = bool>> {
let f = || async { true };
f
}
Meta
rustc --version --verbose
:
rustc 1.63.0 (4b91a6ea7 2022-08-08)
binary: rustc
commit-hash: 4b91a6ea7258a947e59c6522cd5898e7c0a6a88f
commit-date: 2022-08-08
host: x86_64-unknown-linux-gnu
release: 1.63.0
LLVM version: 14.0.5
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Done