Description
Bevy version
main Aug 21, 96e396fdd4e3d389c82680b5f8926ef8dbaabd76
What you did
I want to derive SystemParam for a struct which bundles resources but was not fully aware what the struct needs to adhere to.
#[derive(SystemParam)]
pub struct EntityAssets<'w> {
boulder: Res<'w, BoulderAssets>,
imp: Res<'w, ImpAssets>,
smithery: Res<'w, SmitheryAssets>,
storage: Res<'w, StorageAssets>,
}
What you expected to happen
It should compile.
What actually happened
Now it gets complicated. First of all I forget the second lifetime parameter in the struct, which is apparently needed.
Error message hints in the right direction but looks off in the placement hint:
use of undeclared lifetime name `'s`
undeclared lifetime rustcE0261
assets.rs(8, 25): consider introducing lifetime `'s` here: `'s, `
Next try pub struct EntityAssets<'w, 's> {
raised the error message
parameter `'s` is never used
consider removing `'s`, referring to it in a field, or using a marker such as `PhantomData`
which is difficult to understand how to actually use PhantomData in this place.
This issue has the necessary hint how to use it in deriving SystemParam.
Next try:
#[derive(SystemParam)]
pub struct AllAssets<'w, 's> {
#[system_param(ignore)]
_secret: PhantomData<&'s ()>,
boulder: Res<'w, BoulderAssets>,
imp: Res<'w, ImpAssets>,
smithery: Res<'w, SmitheryAssets>,
storage: Res<'w, StorageAssets>,
}
But this will produce an absurde error message since the deriving macro is producing bad code:
mismatched types
expected mutable reference `&mut ResState<boulder::BoulderAssets>`
found mutable reference `&mut ResState<imp::ImpAssets>`rustcE0308
mismatched types
expected mutable reference `&mut ResState<imp::ImpAssets>`
found mutable reference `&mut ResState<smithery::SmitheryAssets>`rustcE0308
mismatched types
expected mutable reference `&mut ResState<smithery::SmitheryAssets>`
found mutable reference `&mut ResState<entities::storage::StorageAssets>`rustcE0308
no field `4` on type `(ResState<boulder::BoulderAssets>, ResState<imp::ImpAssets>, ResState<smithery::SmitheryAssets>, ResState<entities::storage::StorageAssets>)`rustcE0609
The next try produced an actually compiling version:
#[derive(SystemParam)]
pub struct EntityAssets<'w, 's> {
boulder: Res<'w, BoulderAssets>,
imp: Res<'w, ImpAssets>,
smithery: Res<'w, SmitheryAssets>,
storage: Res<'w, StorageAssets>,
#[system_param(ignore)]
_secret: PhantomData<&'s ()>,
}
Additional information
I would suggest to make the second lifetime parameter optional in the processing macro, if possible for the resulting type.
The absurde error message hints to an order dependent processing in the derive macro. The processing of struct fields should be order independent.