Repository navigation
Description
Bevy version
v0.10.0
What you did
Upgrading a bevy 0.9 project to the latest and greatest. I have a few #[derive(SystemParam)] implementations that were working great with 0.9, but now give me an error: lifetime may not live long enough which appears to all occur within the SystemParam attribute itself. Here's the struct definition in question:
/// TileEntities is a helper system parameter that provides pulling
/// component references directly from the tile positions.
#[allow(clippy::complexity)]
#[derive(SystemParam)]
pub struct TileEntities<'w, 's, T: EntityRef + Component>
where <T as EntityRef>::ComponentType: Component,
{
references: ParamSet<'w, 's, (
Query<'w, 's, &'static mut T>,
Query<'w, 's, &'static T>)>,
component: ParamSet<'w, 's, (
Query<'w, 's, &'static mut T::ComponentType>,
Query<'w, 's, &'static T::ComponentType>)>,
map: TileQuery<'w, 's, SimulationLayer>,
}The TileQuery itself is also a SystemParam:
#[derive(SystemParam)]
pub struct TileQuery<'w, 's, T: Component + Layer> {
map: Query<'w, 's, &'static TileStorage, With<T>>,
world_manager: Res<'w, WorldManager>,
tile_mapper: TileMapper<'w>,
}
/// TileMapper can be included in systems and used to map tile positions back into world
/// coordinates and other tile related conversions.
#[derive(SystemParam)]
pub struct TileMapper<'w> {
config: Res<'w, MapConfig>
}The EntityRef trait is defined as:
/// EntityRef is a trait used to reference a single entity from multiple tiles
pub trait EntityRef {
/// The `ComponentType` refers to the internal type of component the `Entity`
/// refers to. This is especially useful information to have for building
/// generic bevy `Query` parameters for systems.
type ComponentType;
/// This method returns the `UVec2` tile position of the entity set.
fn tile(&self) -> UVec2;
/// This method returns the `Entity` identifier.
fn get(&self) -> Entity;
}What went wrong
I'm getting 4 nearly identical errors all pointing to the #[derive(SystemParam)].
Here's the first error, followed by the 3 differences
error: lifetime may not live long enough
--> src\tiles\tile_entities.rs:155:10
|
155 | #[derive(SystemParam)]
| ^^^^^^^^^^^
| |
| lifetime `'w` defined here
| lifetime `'w2` defined here
| associated function was supposed to return data with lifetime `'w2` but it is returning data with lifetime `'w`
|
= help: consider adding the following bound: `'w: 'w2`
= note: requirement occurs because of the type `tile_entities::TileEntities<'_, '_, T>`, which makes the generic argument `'_` invariant
= note: the struct `tile_entities::TileEntities<'w, 's, T>` is invariant over the parameter `'w`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
= note: this error originates in the derive macro `SystemParam` (in Nightly builds, run with -Z macro-backtrace for more info)
Second:
...
155 | #[derive(SystemParam)]
| ^^^^^^^^^^^
| |
| lifetime `'s` defined here
| lifetime `'s2` defined here
| associated function was supposed to return data with lifetime `'s2` but it is returning data with lifetime `'s`
|
= help: consider adding the following bound: `'s: 's2`
...
Third:
...
155 | #[derive(SystemParam)]
| ^^^^^^^^^^^
| |
| lifetime `'s2` defined here
| lifetime `'s` defined here
| associated function was supposed to return data with lifetime `'s` but it is returning data with lifetime `'s2`
|
= help: consider adding the following bound: `'s2: 's`
...
Fourth:
...
155 | #[derive(SystemParam)]
| ^^^^^^^^^^^
| |
| lifetime `'w2` defined here
| lifetime `'w` defined here
| associated function was supposed to return data with lifetime `'w` but it is returning data with lifetime `'w2`
|
= help: consider adding the following bound: `'w2: 'w`
...
Additional information
I will work to see if I can get a reproducible case with less dependencies than the current project I am working in. Apologies if this is unclear in anyway. Will be happy to assist anyway possible!
Thanks for an incredible open source project
Activity
alice-i-cecile commentedon Mar 24, 2023
What happens if you change those lifetimes to 'static?
mbolt35 commentedon Mar 24, 2023
@alice-i-cecile Just to be clear, do you mean a 'static constraint on 'w and 's? Or do you mean dropping the 'w and 's in my type and replacing with 'static? (I'm assuming there could be a difference there do to the way the param parses the struct body)
Will give this a shot ASAP! Thanks for the response
joseph-gio commentedon Mar 24, 2023
Ah, seems like this issue pops up when a
SystemParamhas invariant lifetimes. This used to work, but it must have regressed during the 0.9-0.10 cycle (likely my fault) since none of our tests use invariant lifetimes.Here's a minimum reproducible example:
Seems like this will be fixed by #8030.
mbolt35 commentedon Mar 25, 2023
@alice-i-cecile Adding the
'staticconstraint on 'w and 's did seem to solve 2 of the errors, but looks as if now it's expecting a lifetime to outlive static:and
@JoJoJet Thanks for chiming in here, do you have any insight on when we might expect #8030 ? Possible there will be a patch release, or are we talking 0.11?
joseph-gio commentedon Mar 25, 2023
#8030 has a breaking change, so in order for the fix to land in a patch release I'd have to make a new PR with just that fix and nothing else. I can look into that later but I'm not sure how that would work out.
As a temporary workaround, try changing just the lifetimes inside of the ParamSet to
'static:Meaning if you have a struct like this:
ParamSet<'w, 's, Query<'w, 's, ...>>Change it to this:
ParamSet<'w, 's, Query<'static, 'static, ...>>Changing the lifetimes in this specific way seems to make it compile.
mbolt35 commentedon Mar 25, 2023
@JoJoJet Thank you, that works. Appreciate the help 👍
joseph-gio commentedon Mar 25, 2023
Happy I could help :)
Make `#[system_param(ignore)]` and `#[world_query(ignore)]` unnecessa…
Make `#[system_param(ignore)]` and `#[world_query(ignore)]` unnecessa…
Make `#[system_param(ignore)]` and `#[world_query(ignore)]` unnecessa…
Make `#[system_param(ignore)]` and `#[world_query(ignore)]` unnecessa…