Hi,
I'd like to accept an optional parameter, which I will create if None
is passed.
The problem is, the function that generates this value returns an "impl Trait" value which contains generic methods – which seems to prevent the creation of trait objects.
I'm wondering now what I can do to store such a value in a struct.
The following code demonstrates the problem:
use agnostik::{Agnostik, AgnostikExecutor};
fn main() {
let store1 = setup1(None);
}
struct Store1 {
executor: Box<dyn AgnostikExecutor>,
}
fn setup1(executor: Option<impl AgnostikExecutor>) -> Store1 {
let executor = Box::new(executor.unwrap_or_else(|| Agnostik::bastion()));
Store1 {executor}
}
And this is the error I get:
Compiling rust v0.1.0 (/home/dh/projects/play/rust)
error[E0038]: the trait `agnostik::AgnostikExecutor` cannot be made into an object
--> src/bin/agnostik_executor.rs:9:5
|
9 | executor: Box<dyn AgnostikExecutor>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `agnostik::AgnostikExecutor` cannot be made into an object
|
::: /home/dh/.cargo/registry/src/github.com-1ecc6299db9ec823/agnostik-0.1.5/src/lib.rs:165:8
|
165 | fn spawn<F>(&self, future: F) -> JoinHandle<F::Output>
| ----- the trait cannot be made into an object because method `spawn` has generic type parameters
...
171 | fn spawn_blocking<F, T>(&self, task: F) -> JoinHandle<T>
| -------------- the trait cannot be made into an object because method `spawn_blocking` has generic type parameters
...
177 | fn block_on<F>(&self, future: F) -> F::Output
| -------- the trait cannot be made into an object because method `block_on` has generic type parameters
error: aborting due to previous error
For more information about this error, try `rustc --explain E0038`.
error: could not compile `rust`.
To learn more, run the command again with --verbose.
I tried two other approaches, which both failed:
A generic struct:
use agnostik::{Agnostik, AgnostikExecutor};
fn main() {
let store2 = setup2(None);
}
struct Store2<E: AgnostikExecutor> {
executor: E,
}
fn setup2<E: AgnostikExecutor>(executor: Option<E>) -> Store2<E> {
let executor = executor.unwrap_or_else(|| Agnostik::bastion());
Store2 {executor}
}
Which failes with "expected type parameter E
, found opaque type" in setup2
(full error message).
I also tried to use "impl AgnostikExecutor" as the type of the field of the struct:
struct Store3 {
executor: impl AgnostikExecutor,
}
But, unfortunately, impl Trait
isn't allowed there...
So my question is how do I store an "impl Trait" value that isn't object safe because the trait contains generic methods?