In theory the below code should work however inside the run function at the if let statement when trying to downcast a box holding a system trait object into a box holding a function trait object it fails. And I swear I had a similar implementation running earlier.
Please always include the full compiler error when asking for help. It saves tons of time for the person reading and trying to answer. The full error is the one output by cargo in the terminal, not the partial errors sometimes shown by IDEs. Thanks.
and with this come two questions. Firstly, as far as my knowledge goes theres no way to implement trait bounds on declerative macros correct? And secondly, when I call the macro as I'll demonstrate in a second you pass in a tuple of systems but unlike directly calling the add systems function you need to specify the functions as function pointers. Why is that?
fn main() {
app! {
(greeting as fn(), farewell as fn())
}
}
Nevermind its just the way rusts type inference works if I change this line let mut systems: Vec<_> = Vec::new(); to let mut systems: Vec<fn()> = Vec::new(); it works.
fn main() {
let mut v = vec![];
v.push(greeting); // L3
v.push(farewell); // L4
}
...because each function has it's own unique function item type (similar to how closures have unique types). So on L3, there's nothing to make the compiler think you didn't want v to be a Vec<${function item type of greeting}>.
Whereas here:
let v = vec![greeting, farewell];
// Expands to approximately
let v = <[_]>::into_vec(Box::new([greeting, farewell]));
having both function items in an array means they must be the same type, and due to this the compiler decides to coerce them to function pointers. (Probably this is a special case for function items.)
Sorry it took me so long to get back to you @quinedot I've been messing around with the code for a few hours learning how to make macros. But thats besides the point, what I meant when saying this was the functions I pass to the macro like so:
any other solution at least that I've tried that does result in the error I want or at least an error closer to what I want does so inside the macro rules block. One such solution being:
the trait bound `for<'a> fn(&'a str): temp::System` is not satisfied
the trait `temp::System` is implemented for fn pointer `fn()`
required for the cast from `Box<for<'a> fn(&'a str)>` to `Box<(dyn temp::System + 'static)>`
on this line
systems.push(Box::new($system));
so my question to you and anybody else who is willing to help is there something right in front of me that I'm missing? Whats the solution or is there even one?
So today really was just not my day @quinedot because the macro and compiler time errors have been working correctly from the start. Below is the working implementation if your curious.
Filename: src/lib.rs
which is the exactly the same if I change the main function to not use the macro and instead use the associated constructor function and corresponding method calls
Filename: src/main.rs