If I have a function that I haven't yet had time to implement while I'm working on its higher-leve callers, I can stub it out with a panic:
fn foo() -> u64 {
panic!("TODO");
}
However, if I want to do the same for something that returns a future without a concrete result type, it doesn't work, providing a rather surprising error:
// error[E0277]: `!` is not a future
fn foo() -> impl Future {
panic!("TODO");
}
Is there any easy way to stub out a function like this?
Generally, the way panic!()
(or similar macros, e.g. todo!()
) allow you to return any type is that they return !
(the never type), which coerces to any type.
But here the compiler doesn't have a specific type to coerce into, so if !
does not impl the trait, it won't work. Furthermore, !
can't impl every trait, even if std was to add every possible impl - think e.g. Default
. We cannot return anything in default()
, because the never type by definition cannot exist.
Therefore, you need to put something extra there. If you have a type that implements the trait and can put a value of it there (e.g std::future::pending::<()>()
), great; otherwise, if you have a type but not a value of it, you coerce explicitly:
fn foo() -> impl Future {
panic!("TODO") as std::future::Ready<()>
}
(Beware the compiler will warn you about unreachable code, you'll need to #[allow]
that. This is going to change soon, hopefully).
If you have no type, you're out of luck.