Skip to content

Conversation

@ecoskey
Copy link
Contributor

@ecoskey ecoskey commented Dec 4, 2025

Objective

  • Allow reborrowing for SystemParam types. The end goal here is to work towards a fast System::scope api, to run a system many times with different inputs with low overhead

Blocked on: #22025

Next steps:

  • This diff would be smaller with a proc-macro for internal implementations: impl_reborrow_system_param!(...). I decided not to at least at first, though it wouldn't be too hard.
  • Could also combine with ReborrowQueryData in theory, but it might be controversial:
trait EcsBorrow {
    type Item<'w, 's>;
}

trait EcsReborrow {
    pub fn reborrow(...)
}

trait SystemParam: EcsBorrow {}
trait QueryData: EcsBorrow {}
  • Add System::scope

Solution

  • Add a optional ReborrowSystemParam subtrait, almost identical to ReborrowQueryData

  • While most system params should implement this trait, there's a few exceptions like ParamSet types with invariant lifetimes, which we can't shorten AFAICT. Maybe if we changed ParamSet::Item to shorten the inner lifetime as well?

/// A [`SystemParam`] whose lifetime can be shortened via
/// [`reborrow`](ReborrowSystemParam::reborrow)-ing. This should be implemented
/// for most system params, except in the case of non-covariant lifetimes.
pub trait ReborrowSystemParam: SystemParam {
    /// Returns a `SystemParam` item with a smaller lifetime.
    fn reborrow<'wlong: 'short, 'slong: 'short, 'short>(
        item: &'short mut Self::Item<'wlong, 'slong>,
    ) -> Self::Item<'short, 'short>;
}

@ecoskey ecoskey added C-Feature A new feature, making something new possible A-ECS Entities, components, systems, and events S-Blocked This cannot move forward until something else changes D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes labels Dec 4, 2025
@ecoskey ecoskey force-pushed the feature/param_reborrow branch 3 times, most recently from b5f2187 to 6bc764e Compare December 9, 2025 02:11
@chescock
Copy link
Contributor

While most system params should implement this trait, there's a few exceptions like ParamSet types with invariant lifetimes, which we can't shorten AFAICT.

I would have expected ParamSet to be reborrowable. It's invariant in T, but covariant in 'w and 's, right? What kind of error do you get? You'll have to system_meta.clone(), but that's no worse than what get_param already does.

As with QueryData, I'd vote for putting this on the main trait if we can to reduce the total number of traits.

@ecoskey
Copy link
Contributor Author

ecoskey commented Dec 12, 2025

I would have expected ParamSet to be reborrowable. It's invariant in T, but covariant in 'w and 's, right? What kind of error do you get? You'll have to system_meta.clone(), but that's no worse than what get_param already does.

It's a pretty rare exception. In custom system params a user could write my_param: ParamSet<'w, 's, Query<'w, 's, ()>> or similar, which makes 'w and 's invariant. It'd documented in an old issue and there's a regression test for it somewhere. We could remove that test and force users to write the inner lifetimes as 'static (I'd prefer that personally too) but might be contentious

@ecoskey ecoskey force-pushed the feature/param_reborrow branch from 6bc764e to e268b51 Compare December 14, 2025 02:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes S-Blocked This cannot move forward until something else changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants