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 too personally) but might be contentious

@ecoskey ecoskey force-pushed the feature/param_reborrow branch from 6bc764e to e268b51 Compare December 14, 2025 02:43
@chescock
Copy link
Contributor

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

Oh, wow, that's subtle! ... Oh, I see, and you have a conditional impl ReborrowSystemParam for ParamSet where the inner parameters are 'static, so a custom system param that does use 'static will still impl ReborrowSystemParam. Nice!

I'd personally still lean towards combining the traits. The cost of requiring 'static instead of 'w there is pretty low, since it's an unusual case and it already requires a named lifetime. So I'd count it as less expensive than having to add a new trait. But I can see the arguments either way, and I'll be happy to approve a PR with this approach (once the blocker PR is merged)!

@ecoskey ecoskey force-pushed the feature/param_reborrow branch from e268b51 to 5c6ff23 Compare December 16, 2025 01:44
@ecoskey ecoskey force-pushed the feature/param_reborrow branch from 5c6ff23 to 34af904 Compare December 17, 2025 00:25
@ecoskey ecoskey changed the title Add subtrait for reborrowing SystemParam types Add method for reborrowing SystemParam types Dec 17, 2025
@ecoskey
Copy link
Contributor Author

ecoskey commented Dec 28, 2025

closing these for now, will wrap into a later PR if perf looks good

@ecoskey ecoskey closed this Dec 28, 2025
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