0

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?

bbarker
  • 11,636
  • 9
  • 38
  • 62

0 Answers0