Reputation: 65
I am using the genawaiter crate for generator functions to implement
single-threaded "multitasking".
I have this code to create a new Thread, and pass a generator to it, but I am struggling
to find how to represent the impl Future
type that gen!()
returns.
use genawaiter::rc::{gen, Gen};
use genawaiter::yield_;
struct Thread {
function: genawaiter::rc::Gen<(), Option<Sprite>, /*What can go here?*/>,
}
struct Sprite {/*fields here*/}
fn main() {
let thread1 = Thread {
function: gen!({
let object: Option<&mut Sprite> = yield_!(());
// do stuff with `object`
println!("Hi");
}),
};
}
The type that the gen!()
macro returns is.
genawaiter::rc::Gen<(),Option<Sprite>,impl Future<Output = ()>>
If I try to set this as the type of the function
field, I get this error message:
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in path
--> src/main.rs:20:55
|
20 | function: genawaiter::rc::Gen<(), Option<Sprite>, impl Future<Output = ()>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0562`.
error: could not compile `testing` due to previous error
struct EmptyFuture{}
impl Future for EmptyFuture {
type Output = ();
fn poll(
self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Self::Output> {
std::task::Poll::Ready(())
}
}
If I try putting this EmptyFuture
struct in the function
field, it also does
not work, and I get this error message:
error[E0308]: mismatched types
--> src/main.rs:27:19
|
27 | function: gen!({
| ___________________^____-
| |___________________|
| ||
28 | || let object: Option<Sprite> = yield_!(());
29 | || println!("Hi");
30 | || }),
| ||_________-^ expected struct `EmptyFuture`, found opaque type
| |_________|
| the found `async` block
|
::: /home/calvin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:72:43
|
72 | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
| ------------------------------- the found opaque type
|
= note: expected struct `genawaiter::rc::Gen<_, _, EmptyFuture>`
found struct `genawaiter::rc::Gen<_, _, impl Future<Output = ()>>`
= note: this error originates in the macro `gen` (in Nightly builds, run with -Z macro-backtrace for more info)
The only semi-relavant thing I could find on stackoverflow was this, but that is about a function /returning/ an opaque type.
How can I represent the opaque type in my struct? Also, does it make a difference
whether it is an empty type (impl Future<Output = ()>
) or some other struct(impl Future<Output = SomeStruct>
)?
Edit:
I tried Box<dyn Future<Output = ()>>
, and got this error:
error[E0277]: `(dyn Future<Output = ()> + 'static)` cannot be unpinned
--> src/target/mod.rs:325:15
|
325 | function: genawaiter::rc::Gen<(), Option<Sprite>, Box<dyn Future<Output = ()>>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unpin` is not implemented for `(dyn Future<Output = ()> + 'static)`
|
= note: consider using `Box::pin`
= note: required because of the requirements on the impl of `Future` for `Box<(dyn Future<Output = ()> + 'static)>`
note: required by a bound in `genawaiter::rc::Gen`
--> /home/calvin/.cargo/registry/src/github.com-1ecc6299db9ec823/genawaiter-0.99.1/src/rc/generator.rs:11:25
|
11 | pub struct Gen<Y, R, F: Future> {
| ^^^^^^ required by this bound in `genawaiter::rc::Gen`
For more information about this error, try `rustc --explain E0277`.
I followed the compiler suggestion and changed it to
Pin<Box<dyn Future<Output = ()>>>
, but now I am getting a
similar error as before:
error[E0308]: mismatched types
--> src/main.rs:28:19
|
28 | function: gen!({
| ___________________^____-
| |___________________|
| ||
29 | || let object: Option<Sprite> = yield_!(());
30 | || println!("Hi");
31 | || }),
| ||_________-^ expected struct `Pin`, found opaque type
| |_________|
| the found `async` block
|
::: /home/calvin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:72:43
|
72 | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
| ------------------------------- the found opaque type
|
= note: expected struct `genawaiter::rc::Gen<_, _, Pin<Box<(dyn Future<Output = ()> + 'static)>>>`
found struct `genawaiter::rc::Gen<_, _, impl Future<Output = ()>>`
= note: this error originates in the macro `gen` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0308`.
Upvotes: 4
Views: 810
Reputation: 6061
You could try boxing trait object. That is use Box<dyn Future<Output = ()>>
. This will cost you an allocation per created future, but it's the simplest solution. And practically the only one if you don't (or can't) name a type.
Upvotes: 2