Skip to content

SystemParam: lifetime may not live long enough #8192

Closed
@mbolt35

Description

@mbolt35

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-BugAn unexpected or incorrect behavior

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions