In the following code, I have a struct RandomTable
that can store a Vec
of some generic type T
. Previously I was using this code without issue, but the issue arose when I made the struct generic in T
(as shown below).
#[derive(Clone, Copy)]
pub struct RandomEntry<T> {
pub spawner: T,
}
#[derive(Clone)]
pub struct RandomTable<T> {
pub entries: Vec<RandomEntry<T>>,
}
impl<T> RandomTable<T> {
pub fn new() -> Self {
RandomTable {
entries: Vec::new(),
}
}
pub fn add(mut self, spawn: T) -> RandomTable<T> {
self.entries.push(
RandomEntry {
spawner: spawn
}
);
RandomTable {
entries: self.entries,
}
}
}
// pub type SimpleSpawner = fn(&mut World, Position) -> Entity;
pub type SimpleSpawner = fn(u8) -> u8;
fn double(ii: u8) -> u8 {
ii * ii
}
fn triple(ii: u8) -> u8 {
ii * ii * ii
}
pub fn tmp_foo(map_depth: i32) -> RandomTable<SimpleSpawner> {
RandomTable::new()
.add(double)
.add(double) // even adding the same thing twice causes an issue
//.add(fireball_scroll, 30)
}
When I try to compile this, I get an interesting error:
error[E0308]: mismatched types
--> src/main.rs:44:5
|
43 | pub fn tmp_foo(map_depth: i32) -> RandomTable<SimpleSpawner> {
| -------------------------- expected `RandomTable<fn(u8) -> u8>` because of return type
44 | / RandomTable::new()
45 | | .add(double)
46 | | .add(double) // even adding the same thing twice causes an issue
| |____________________^ expected `RandomTable<fn(u8) -> u8>`, found `RandomTable<fn(u8) -> u8 {double}>`
|
= note: expected struct `RandomTable<fn(_) -> _>`
found struct `RandomTable<fn(_) -> _ {double}>`
= note: when the arguments and return types match, functions can be coerced to function pointers
What is the reason for the error? I suspect it is something to do with Rust not being able to abstract a function's type in some way, but I don't understand the error. Is there a way to avoid this, without resorting to boxed types?