I've got a trait which looks something like this:
pub trait Command {
fn execute<W: World>(&self, world: &mut W);
}
pub trait World {
...
}
Note: The
World
trait can't be made object safe.
Where the Command
should be able to work with anything that implements World
(kinda like std::iter::FromIterator
and it's iter
argument).
Now seeing as this trait only has a single method I'd like to implement it for closures so users don't need to write a bunch of boilerplate structs just to implement a simple Command
.
The naive implementation won't work because of unconstrained type parameters and reusing the W
type variable.
impl<F, W> Command for F
where
F: Fn(&mut W),
{
fn execute<W: World>(&self, target: &mut W) { self(target); }
}
errors with the following:
error[E0403]: the name `W` is already used for a generic parameter in this item's generic parameters
--> src/commands/mod.rs:11:16
|
6 | impl<F, W> Command for F
| - first use of `W`
...
11 | fn execute<W: World>(&self, target: &mut W) { self(target); }
| ^ already used
error[E0207]: the type parameter `W` is not constrained by the impl trait, self type, or predicates
--> src/commands/mod.rs:6:9
|
6 | impl<F, W> Command for F
| ^ unconstrained type parameter
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0207, E0403.
For more information about an error, try `rustc --explain E0207`.
error: could not compile `arcs`.
So I tried something akin to the for<'a>
syntax used with higher-ranked lifetimes.
impl<F> Command for F
where
F: for<P: World> Fn(&mut P),
{
fn execute<W: World>(&self, target: &mut W) { self(target); }
}
But considering HRTBs are only implemented for lifetimes the compiler (rightfully) complains...
error: only lifetime parameters can be used in this context
--> src/commands/mod.rs:8:12
|
8 | F: for<P: World> Fn(&mut P),
|
Can anyone think of a formulation which would let me implement Command
for a closure type?