Skip to main content

bevy_ecs/system/
system_param.rs

1#![expect(
2    unsafe_op_in_unsafe_fn,
3    reason = "See #11590. To be removed once all applicable unsafe code has an unsafe block with a safety comment."
4)]
5
6pub use crate::change_detection::{NonSend, NonSendMut, Res, ResMut};
7use crate::{
8    archetype::Archetypes,
9    bundle::Bundles,
10    change_detection::{ComponentTicksMut, ComponentTicksRef, Tick},
11    component::{ComponentId, Components, Mutable},
12    entity::{Entities, EntityAllocator},
13    query::{
14        Access, FilteredAccess, FilteredAccessSet, IterQueryData, QueryData, QueryFilter,
15        QuerySingleError, QueryState, ReadOnlyQueryData,
16    },
17    resource::{Resource, IS_RESOURCE},
18    system::{Query, Single, SystemMeta},
19    world::{
20        unsafe_world_cell::UnsafeWorldCell, DeferredWorld, FilteredResources, FilteredResourcesMut,
21        FromWorld, World,
22    },
23};
24use alloc::{borrow::Cow, boxed::Box, vec::Vec};
25pub use bevy_ecs_macros::SystemParam;
26use bevy_platform::cell::SyncCell;
27use bevy_ptr::UnsafeCellDeref;
28use bevy_utils::prelude::DebugName;
29use core::{
30    any::Any,
31    fmt::{Debug, Display},
32    marker::PhantomData,
33    ops::{Deref, DerefMut},
34};
35use thiserror::Error;
36
37use super::Populated;
38use variadics_please::{all_tuples, all_tuples_enumerated};
39
40/// A parameter that can be used in a [`System`](super::System).
41///
42/// # Derive
43///
44/// This trait can be derived with the [`derive@super::SystemParam`] macro.
45/// This macro only works if each field on the derived struct implements [`SystemParam`].
46/// Note: There are additional requirements on the field types.
47/// See the *Generic `SystemParam`s* section for details and workarounds of the probable
48/// cause if this derive causes an error to be emitted.
49///
50/// Derived `SystemParam` structs may have two lifetimes: `'w` for data stored in the [`World`],
51/// and `'s` for data stored in the parameter's state.
52///
53/// The following list shows the most common [`SystemParam`]s and which lifetime they require
54///
55/// ```
56/// # use bevy_ecs::prelude::*;
57/// # #[derive(Component)]
58/// # struct SomeComponent;
59/// # #[derive(Resource)]
60/// # struct SomeResource;
61/// # #[derive(Message)]
62/// # struct SomeMessage;
63/// # #[derive(Resource)]
64/// # struct SomeOtherResource;
65/// # use bevy_ecs::system::SystemParam;
66/// # #[derive(SystemParam)]
67/// # struct ParamsExample<'w, 's> {
68/// #    query:
69/// Query<'w, 's, Entity>,
70/// #    query2:
71/// Query<'w, 's, &'static SomeComponent>,
72/// #    res:
73/// Res<'w, SomeResource>,
74/// #    res_mut:
75/// ResMut<'w, SomeOtherResource>,
76/// #    local:
77/// Local<'s, u8>,
78/// #    commands:
79/// Commands<'w, 's>,
80/// #    message_reader:
81/// MessageReader<'w, 's, SomeMessage>,
82/// #    message_writer:
83/// MessageWriter<'w, SomeMessage>
84/// # }
85/// ```
86/// ## `PhantomData`
87///
88/// [`PhantomData`] is a special type of `SystemParam` that does nothing.
89/// This is useful for constraining generic types or lifetimes.
90///
91/// # Example
92///
93/// ```
94/// # use bevy_ecs::prelude::*;
95/// # #[derive(Resource)]
96/// # struct SomeResource;
97/// use std::marker::PhantomData;
98/// use bevy_ecs::system::SystemParam;
99///
100/// #[derive(SystemParam)]
101/// struct MyParam<'w, Marker: 'static> {
102///     foo: Res<'w, SomeResource>,
103///     marker: PhantomData<Marker>,
104/// }
105///
106/// fn my_system<T: 'static>(param: MyParam<T>) {
107///     // Access the resource through `param.foo`
108/// }
109///
110/// # bevy_ecs::system::assert_is_system(my_system::<()>);
111/// ```
112///
113/// # Generic `SystemParam`s
114///
115/// When using the derive macro, you may see an error in the form of:
116///
117/// ```text
118/// expected ... [ParamType]
119/// found associated type `<[ParamType] as SystemParam>::Item<'_, '_>`
120/// ```
121/// where `[ParamType]` is the type of one of your fields.
122/// To solve this error, you can wrap the field of type `[ParamType]` with [`StaticSystemParam`]
123/// (i.e. `StaticSystemParam<[ParamType]>`).
124///
125/// ## Details
126///
127/// The derive macro requires that the [`SystemParam`] implementation of
128/// each field `F`'s [`Item`](`SystemParam::Item`)'s is itself `F`
129/// (ignoring lifetimes for simplicity).
130/// This assumption is due to type inference reasons, so that the derived [`SystemParam`] can be
131/// used as an argument to a function system.
132/// If the compiler cannot validate this property for `[ParamType]`, it will error in the form shown above.
133///
134/// This will most commonly occur when working with `SystemParam`s generically, as the requirement
135/// has not been proven to the compiler.
136///
137/// ## Custom Validation Messages
138///
139/// When using the derive macro, any [`SystemParamValidationError`]s will be propagated from the sub-parameters.
140/// If you want to override the error message, add a `#[system_param(validation_message = "New message")]` attribute to the parameter.
141///
142/// ```
143/// # use bevy_ecs::prelude::*;
144/// # #[derive(Resource)]
145/// # struct SomeResource;
146/// # use bevy_ecs::system::SystemParam;
147/// #
148/// #[derive(SystemParam)]
149/// struct MyParam<'w> {
150///     #[system_param(validation_message = "Custom Message")]
151///     foo: Res<'w, SomeResource>,
152/// }
153///
154/// let mut world = World::new();
155/// let err = world.run_system_cached(|param: MyParam| {}).unwrap_err();
156/// let expected = "Parameter `MyParam::foo` failed validation: Custom Message";
157/// # #[cfg(feature="Trace")] // Without debug_utils/debug enabled MyParam::foo is stripped and breaks the assert
158/// assert!(err.to_string().contains(expected));
159/// ```
160///
161/// ## Builders
162///
163/// If you want to use a [`SystemParamBuilder`](crate::system::SystemParamBuilder) with a derived [`SystemParam`] implementation,
164/// add a `#[system_param(builder)]` attribute to the struct.
165/// This will generate a builder struct whose name is the param struct suffixed with `Builder`.
166/// The builder will not be `pub`, so you may want to expose a method that returns an `impl SystemParamBuilder<T>`.
167///
168/// ```
169/// mod custom_param {
170/// #     use bevy_ecs::{
171/// #         prelude::*,
172/// #         system::{LocalBuilder, QueryParamBuilder, SystemParam},
173/// #     };
174/// #
175///     #[derive(SystemParam)]
176///     #[system_param(builder)]
177///     pub struct CustomParam<'w, 's> {
178///         query: Query<'w, 's, ()>,
179///         local: Local<'s, usize>,
180///     }
181///
182///     impl<'w, 's> CustomParam<'w, 's> {
183///         pub fn builder(
184///             local: usize,
185///             query: impl FnOnce(&mut QueryBuilder<()>),
186///         ) -> impl SystemParamBuilder<Self> {
187///             CustomParamBuilder {
188///                 local: LocalBuilder(local),
189///                 query: QueryParamBuilder::new(query),
190///             }
191///         }
192///     }
193/// }
194///
195/// use custom_param::CustomParam;
196///
197/// # use bevy_ecs::prelude::*;
198/// # #[derive(Component)]
199/// # struct A;
200/// #
201/// # let mut world = World::new();
202/// #
203/// let system = (CustomParam::builder(100, |builder| {
204///     builder.with::<A>();
205/// }),)
206///     .build_state(&mut world)
207///     .build_system(|param: CustomParam| {});
208/// ```
209///
210/// # Safety
211///
212/// The implementor must ensure the following is true.
213/// - [`SystemParam::init_access`] correctly registers all [`World`] accesses used
214///   by [`SystemParam::get_param`] with the provided [`system_meta`](SystemMeta).
215/// - None of the world accesses may conflict with any prior accesses registered
216///   on `system_meta`.
217pub unsafe trait SystemParam: Sized {
218    /// Used to store data which persists across invocations of a system.
219    type State: Send + Sync + 'static;
220
221    /// The item type returned when constructing this system param.
222    /// The value of this associated type should be `Self`, instantiated with new lifetimes.
223    ///
224    /// You could think of [`SystemParam::Item<'w, 's>`] as being an *operation* that changes the lifetimes bound to `Self`.
225    type Item<'world, 'state>: SystemParam<State = Self::State>;
226
227    /// Creates a new instance of this param's [`State`](SystemParam::State).
228    fn init_state(world: &mut World) -> Self::State;
229
230    /// Registers any [`World`] access used by this [`SystemParam`].
231    ///
232    /// This method must panic if the access would conflict with any existing access in the [`FilteredAccessSet`].
233    fn init_access(
234        state: &Self::State,
235        system_meta: &mut SystemMeta,
236        component_access_set: &mut FilteredAccessSet,
237        world: &mut World,
238    );
239
240    /// Applies any deferred mutations stored in this [`SystemParam`]'s state.
241    /// This is used to apply [`Commands`] during [`ApplyDeferred`](crate::prelude::ApplyDeferred).
242    ///
243    /// [`Commands`]: crate::prelude::Commands
244    #[inline]
245    #[expect(
246        unused_variables,
247        reason = "The parameters here are intentionally unused by the default implementation; however, putting underscores here will result in the underscores being copied by rust-analyzer's tab completion."
248    )]
249    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {}
250
251    /// Queues any deferred mutations to be applied at the next [`ApplyDeferred`](crate::prelude::ApplyDeferred).
252    #[inline]
253    #[expect(
254        unused_variables,
255        reason = "The parameters here are intentionally unused by the default implementation; however, putting underscores here will result in the underscores being copied by rust-analyzer's tab completion."
256    )]
257    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {}
258
259    /// Creates a parameter to be passed into a [`SystemParamFunction`](super::SystemParamFunction).
260    ///
261    /// This method also validates that the param can be acquired. If validation fails,
262    /// an appropriate [`SystemParamValidationError`] should be returned.
263    /// Systems will convert this to a [`RunSystemError`](super::RunSystemError),
264    /// and the built-in executors will ignore any "skipped" validation results,
265    /// but pass any "invalid" results to the fallback error handler defined in [`bevy_ecs::error`].
266    ///
267    /// For nested [`SystemParam`]s validation will fail if any
268    /// delegated validation fails.
269    ///
270    /// # Safety
271    ///
272    /// - The passed [`UnsafeWorldCell`] must have access to any world data registered
273    ///   in [`init_access`](SystemParam::init_access).
274    /// - [`SystemParam::init_access`] must not request conflicting access.
275    ///   If `Self` is `ReadOnlySystemParam`, the access is read-only and can never conflict.
276    ///   Otherwise, [`SystemParam::init_access`] must be called to ensure it does not panic.
277    /// - `world` must be the same [`World`] that was used to initialize [`state`](SystemParam::init_state).
278    unsafe fn get_param<'world, 'state>(
279        state: &'state mut Self::State,
280        system_meta: &SystemMeta,
281        world: UnsafeWorldCell<'world>,
282        change_tick: Tick,
283    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError>;
284}
285
286/// A [`SystemParam`] that only reads a given [`World`].
287///
288/// # Safety
289/// This must only be implemented for [`SystemParam`] impls that exclusively read the World passed in to [`SystemParam::get_param`]
290pub unsafe trait ReadOnlySystemParam: SystemParam {}
291
292/// Shorthand way of accessing the associated type [`SystemParam::Item`] for a given [`SystemParam`].
293pub type SystemParamItem<'w, 's, P> = <P as SystemParam>::Item<'w, 's>;
294
295// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
296unsafe impl<'w, 's, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
297    for Query<'w, 's, D, F>
298{
299}
300
301// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
302// this Query conflicts with any prior access, a panic will occur.
303unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam for Query<'_, '_, D, F> {
304    type State = QueryState<D, F>;
305    type Item<'w, 's> = Query<'w, 's, D, F>;
306
307    fn init_state(world: &mut World) -> Self::State {
308        // SAFETY: `SystemParam::init_access` calls `QueryState::init_access`,
309        // `SystemParam::init_access` must be called before `SystemParam::get_param`,
310        // and we only call methods on the `QueryState` in `get_param`.
311        unsafe { QueryState::new_unchecked(world) }
312    }
313
314    fn init_access(
315        state: &Self::State,
316        system_meta: &mut SystemMeta,
317        component_access_set: &mut FilteredAccessSet,
318        world: &mut World,
319    ) {
320        state.init_access(Some(system_meta.name()), component_access_set, world.into());
321    }
322
323    #[inline]
324    unsafe fn get_param<'w, 's>(
325        state: &'s mut Self::State,
326        system_meta: &SystemMeta,
327        world: UnsafeWorldCell<'w>,
328        change_tick: Tick,
329    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
330        // SAFETY: We have registered all of the query's world accesses,
331        // so the caller ensures that `world` has permission to access any
332        // world data that the query needs.
333        // The caller ensures the world matches the one used in init_state.
334        Ok(unsafe { state.query_unchecked_with_ticks(world, system_meta.last_run, change_tick) })
335    }
336}
337
338// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
339// this Query conflicts with any prior access, a panic will occur.
340unsafe impl<'a, 'b, D: IterQueryData + 'static, F: QueryFilter + 'static> SystemParam
341    for Single<'a, 'b, D, F>
342{
343    type State = QueryState<D, F>;
344    type Item<'w, 's> = Single<'w, 's, D, F>;
345
346    fn init_state(world: &mut World) -> Self::State {
347        Query::init_state(world)
348    }
349
350    fn init_access(
351        state: &Self::State,
352        system_meta: &mut SystemMeta,
353        component_access_set: &mut FilteredAccessSet,
354        world: &mut World,
355    ) {
356        Query::init_access(state, system_meta, component_access_set, world);
357    }
358
359    #[inline]
360    unsafe fn get_param<'w, 's>(
361        state: &'s mut Self::State,
362        system_meta: &SystemMeta,
363        world: UnsafeWorldCell<'w>,
364        change_tick: Tick,
365    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
366        // SAFETY: State ensures that the components it accesses are not accessible somewhere elsewhere.
367        // The caller ensures the world matches the one used in init_state.
368        let query =
369            unsafe { state.query_unchecked_with_ticks(world, system_meta.last_run, change_tick) };
370        match query.single_inner() {
371            Ok(single) => Ok(Single {
372                item: single,
373                _filter: PhantomData,
374            }),
375            Err(QuerySingleError::NoEntities(_)) => Err(
376                SystemParamValidationError::skipped::<Self>("No matching entities"),
377            ),
378            Err(QuerySingleError::MultipleEntities(_)) => Err(
379                SystemParamValidationError::skipped::<Self>("Multiple matching entities"),
380            ),
381        }
382    }
383}
384
385// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
386unsafe impl<'a, 'b, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
387    for Single<'a, 'b, D, F>
388{
389}
390
391// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
392// this Query conflicts with any prior access, a panic will occur.
393unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam
394    for Populated<'_, '_, D, F>
395{
396    type State = QueryState<D, F>;
397    type Item<'w, 's> = Populated<'w, 's, D, F>;
398
399    fn init_state(world: &mut World) -> Self::State {
400        Query::init_state(world)
401    }
402
403    fn init_access(
404        state: &Self::State,
405        system_meta: &mut SystemMeta,
406        component_access_set: &mut FilteredAccessSet,
407        world: &mut World,
408    ) {
409        Query::init_access(state, system_meta, component_access_set, world);
410    }
411
412    #[inline]
413    unsafe fn get_param<'w, 's>(
414        state: &'s mut Self::State,
415        system_meta: &SystemMeta,
416        world: UnsafeWorldCell<'w>,
417        change_tick: Tick,
418    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
419        // SAFETY: Delegate to existing `SystemParam` implementations.
420        let query = unsafe { Query::get_param(state, system_meta, world, change_tick) }?;
421        if query.is_empty() {
422            Err(SystemParamValidationError::skipped::<Self>(
423                "No matching entities",
424            ))
425        } else {
426            Ok(Populated(query))
427        }
428    }
429}
430
431// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
432unsafe impl<'w, 's, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
433    for Populated<'w, 's, D, F>
434{
435}
436
437/// A collection of potentially conflicting [`SystemParam`]s allowed by disjoint access.
438///
439/// Allows systems to safely access and interact with up to 8 mutually exclusive [`SystemParam`]s, such as
440/// two queries that reference the same mutable data or an event reader and writer of the same type.
441///
442/// Each individual [`SystemParam`] can be accessed by using the functions `p0()`, `p1()`, ..., `p7()`,
443/// according to the order they are defined in the `ParamSet`. This ensures that there's either
444/// only one mutable reference to a parameter at a time or any number of immutable references.
445///
446/// # Examples
447///
448/// The following system mutably accesses the same component two times,
449/// which is not allowed due to rust's mutability rules.
450///
451/// ```should_panic
452/// # use bevy_ecs::prelude::*;
453/// #
454/// # #[derive(Component)]
455/// # struct Health;
456/// #
457/// # #[derive(Component)]
458/// # struct Enemy;
459/// #
460/// # #[derive(Component)]
461/// # struct Ally;
462/// #
463/// // This will panic at runtime when the system gets initialized.
464/// fn bad_system(
465///     mut enemies: Query<&mut Health, With<Enemy>>,
466///     mut allies: Query<&mut Health, With<Ally>>,
467/// ) {
468///     // ...
469/// }
470/// #
471/// # let mut bad_system_system = IntoSystem::into_system(bad_system);
472/// # let mut world = World::new();
473/// # bad_system_system.initialize(&mut world);
474/// # bad_system_system.run((), &mut world);
475/// ```
476///
477/// Conflicting `SystemParam`s like these can be placed in a `ParamSet`,
478/// which leverages the borrow checker to ensure that only one of the contained parameters are accessed at a given time.
479///
480/// ```
481/// # use bevy_ecs::prelude::*;
482/// #
483/// # #[derive(Component)]
484/// # struct Health;
485/// #
486/// # #[derive(Component)]
487/// # struct Enemy;
488/// #
489/// # #[derive(Component)]
490/// # struct Ally;
491/// #
492/// // Given the following system
493/// fn fancy_system(
494///     mut set: ParamSet<(
495///         Query<&mut Health, With<Enemy>>,
496///         Query<&mut Health, With<Ally>>,
497///     )>
498/// ) {
499///     // This will access the first `SystemParam`.
500///     for mut health in set.p0().iter_mut() {
501///         // Do your fancy stuff here...
502///     }
503///
504///     // The second `SystemParam`.
505///     // This would fail to compile if the previous parameter was still borrowed.
506///     for mut health in set.p1().iter_mut() {
507///         // Do even fancier stuff here...
508///     }
509/// }
510/// # bevy_ecs::system::assert_is_system(fancy_system);
511/// ```
512///
513/// Of course, `ParamSet`s can be used with any kind of `SystemParam`, not just [queries](Query).
514///
515/// ```
516/// # use bevy_ecs::prelude::*;
517/// #
518/// # #[derive(Message)]
519/// # struct MyMessage;
520/// # impl MyMessage {
521/// #   pub fn new() -> Self { Self }
522/// # }
523/// fn message_system(
524///     mut set: ParamSet<(
525///         // PROBLEM: `MessageReader` and `MessageWriter` cannot be used together normally,
526///         // because they both need access to the same message queue.
527///         // SOLUTION: `ParamSet` allows these conflicting parameters to be used safely
528///         // by ensuring only one is accessed at a time.
529///         // Note that a better solution here is to use `MessageMutator`,
530///         // which both reads and writes messages with a single parameter.
531///         MessageReader<MyMessage>,
532///         MessageWriter<MyMessage>,
533///         // PROBLEM: `&World` needs read access to everything, which conflicts with
534///         // any mutable access in the same system.
535///         // SOLUTION: `ParamSet` ensures `&World` is only accessed when we're not
536///         // using the other mutable parameters.
537///         &World,
538///     )>,
539/// ) {
540///     for message in set.p0().read() {
541///         // ...
542///         # let _message = message;
543///     }
544///     set.p1().write(MyMessage::new());
545///
546///     let entities = set.p2().entities();
547///     // ...
548///     # let _entities = entities;
549/// }
550/// # bevy_ecs::system::assert_is_system(message_system);
551/// ```
552pub struct ParamSet<'w, 's, T: SystemParam> {
553    param_states: &'s mut T::State,
554    world: UnsafeWorldCell<'w>,
555    system_meta: SystemMeta,
556    change_tick: Tick,
557}
558
559macro_rules! impl_param_set {
560    ($(($index: tt, $param: ident, $fn_name: ident)),*) => {
561        // SAFETY: All parameters are constrained to ReadOnlySystemParam, so World is only read
562        unsafe impl<'w, 's, $($param,)*> ReadOnlySystemParam for ParamSet<'w, 's, ($($param,)*)>
563        where $($param: ReadOnlySystemParam,)*
564        { }
565
566        // SAFETY: Relevant parameter ComponentId access is applied to SystemMeta. If any ParamState conflicts
567        // with any prior access, a panic will occur.
568        unsafe impl<'_w, '_s, $($param: SystemParam,)*> SystemParam for ParamSet<'_w, '_s, ($($param,)*)>
569        {
570            type State = ($($param::State,)*);
571            type Item<'w, 's> = ParamSet<'w, 's, ($($param,)*)>;
572
573            #[expect(
574                clippy::allow_attributes,
575                reason = "This is inside a macro meant for tuples; as such, `non_snake_case` won't always lint."
576            )]
577            #[allow(
578                non_snake_case,
579                reason = "Certain variable names are provided by the caller, not by us."
580            )]
581            fn init_state(world: &mut World) -> Self::State {
582                ($($param::init_state(world),)*)
583            }
584
585            #[expect(
586                clippy::allow_attributes,
587                reason = "This is inside a macro meant for tuples; as such, `non_snake_case` won't always lint."
588            )]
589            #[allow(
590                non_snake_case,
591                reason = "Certain variable names are provided by the caller, not by us."
592            )]
593            fn init_access(state: &Self::State, system_meta: &mut SystemMeta, component_access_set: &mut FilteredAccessSet, world: &mut World) {
594                let ($($param,)*) = state;
595                $(
596                    // Call `init_access` on a clone of the original access set to check for conflicts
597                    let component_access_set_clone = &mut component_access_set.clone();
598                    $param::init_access($param, system_meta, component_access_set_clone, world);
599                )*
600                $(
601                    // Pretend to add the param to the system alone to gather the new access,
602                    // then merge its access into the system.
603                    let mut access_set = FilteredAccessSet::new();
604                    $param::init_access($param, system_meta, &mut access_set, world);
605                    component_access_set.extend(access_set);
606                )*
607            }
608
609            fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
610                <($($param,)*) as SystemParam>::apply(state, system_meta, world);
611            }
612
613            fn queue(state: &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
614                <($($param,)*) as SystemParam>::queue(state, system_meta, world.reborrow());
615            }
616
617            #[inline]
618            unsafe fn get_param<'w, 's>(
619                state: &'s mut Self::State,
620                system_meta: &SystemMeta,
621                world: UnsafeWorldCell<'w>,
622                change_tick: Tick,
623            ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
624                // Validate each sub-param eagerly so that the system is correctly
625                // skipped by the executor when any sub-param is unavailable.
626                // PERF: the sub-params will be fetched again lazily when accessed through
627                // the ParamSet, but this is no worse than the previous
628                // validate_param + get_param pattern.
629                $(
630                    // SAFETY: Upheld by caller.
631                    drop(unsafe { $param::get_param(&mut state.$index, system_meta, world, change_tick) }?);
632                )*
633
634                Ok(ParamSet {
635                    param_states: state,
636                    system_meta: system_meta.clone(),
637                    world,
638                    change_tick,
639                })
640            }
641        }
642
643        impl<'w, 's, $($param: SystemParam,)*> ParamSet<'w, 's, ($($param,)*)>
644        {
645            $(
646                /// Gets exclusive access to the parameter at index
647                #[doc = stringify!($index)]
648                /// in this [`ParamSet`].
649                /// No other parameters may be accessed while this one is active.
650                pub fn $fn_name<'a>(&'a mut self) -> SystemParamItem<'a, 'a, $param> {
651                    // SAFETY: systems run without conflicts with other systems.
652                    // Conflicting params in ParamSet are not accessible at the same time
653                    // ParamSets are guaranteed to not conflict with other SystemParams
654                    unsafe {
655                        $param::get_param(&mut self.param_states.$index, &self.system_meta, self.world, self.change_tick)
656                    }
657                    .unwrap_or_else(|err| panic!("ParamSet parameter validation failed: {err}"))
658                }
659            )*
660        }
661    }
662}
663
664unsafe impl<'w, 's, P0, P1, P2, P3, P4, P5, P6, P7> ReadOnlySystemParam for
    ParamSet<'w, 's, (P0, P1, P2, P3, P4, P5, P6, P7)> where
    P0: ReadOnlySystemParam, P1: ReadOnlySystemParam, P2: ReadOnlySystemParam,
    P3: ReadOnlySystemParam, P4: ReadOnlySystemParam, P5: ReadOnlySystemParam,
    P6: ReadOnlySystemParam, P7: ReadOnlySystemParam {}
unsafe impl<'_w, '_s, P0: SystemParam, P1: SystemParam, P2: SystemParam,
    P3: SystemParam, P4: SystemParam, P5: SystemParam, P6: SystemParam,
    P7: SystemParam> SystemParam for
    ParamSet<'_w, '_s, (P0, P1, P2, P3, P4, P5, P6, P7)> {
    type State =
        (P0::State, P1::State, P2::State, P3::State, P4::State, P5::State,
        P6::State, P7::State);
    type Item<'w, 's> = ParamSet<'w, 's, (P0, P1, P2, P3, P4, P5, P6, P7)>;
    #[expect(clippy :: allow_attributes, reason =
    "This is inside a macro meant for tuples; as such, `non_snake_case` won't always lint.")]
    #[allow(non_snake_case, reason =
    "Certain variable names are provided by the caller, not by us.")]
    fn init_state(world: &mut World) -> Self::State {
        (P0::init_state(world), P1::init_state(world), P2::init_state(world),
            P3::init_state(world), P4::init_state(world),
            P5::init_state(world), P6::init_state(world),
            P7::init_state(world))
    }
    #[expect(clippy :: allow_attributes, reason =
    "This is inside a macro meant for tuples; as such, `non_snake_case` won't always lint.")]
    #[allow(non_snake_case, reason =
    "Certain variable names are provided by the caller, not by us.")]
    fn init_access(state: &Self::State, system_meta: &mut SystemMeta,
        component_access_set: &mut FilteredAccessSet, world: &mut World) {
        let (P0, P1, P2, P3, P4, P5, P6, P7) = state;
        let component_access_set_clone = &mut component_access_set.clone();
        P0::init_access(P0, system_meta, component_access_set_clone, world);
        let component_access_set_clone = &mut component_access_set.clone();
        P1::init_access(P1, system_meta, component_access_set_clone, world);
        let component_access_set_clone = &mut component_access_set.clone();
        P2::init_access(P2, system_meta, component_access_set_clone, world);
        let component_access_set_clone = &mut component_access_set.clone();
        P3::init_access(P3, system_meta, component_access_set_clone, world);
        let component_access_set_clone = &mut component_access_set.clone();
        P4::init_access(P4, system_meta, component_access_set_clone, world);
        let component_access_set_clone = &mut component_access_set.clone();
        P5::init_access(P5, system_meta, component_access_set_clone, world);
        let component_access_set_clone = &mut component_access_set.clone();
        P6::init_access(P6, system_meta, component_access_set_clone, world);
        let component_access_set_clone = &mut component_access_set.clone();
        P7::init_access(P7, system_meta, component_access_set_clone, world);
        let mut access_set = FilteredAccessSet::new();
        P0::init_access(P0, system_meta, &mut access_set, world);
        component_access_set.extend(access_set);
        let mut access_set = FilteredAccessSet::new();
        P1::init_access(P1, system_meta, &mut access_set, world);
        component_access_set.extend(access_set);
        let mut access_set = FilteredAccessSet::new();
        P2::init_access(P2, system_meta, &mut access_set, world);
        component_access_set.extend(access_set);
        let mut access_set = FilteredAccessSet::new();
        P3::init_access(P3, system_meta, &mut access_set, world);
        component_access_set.extend(access_set);
        let mut access_set = FilteredAccessSet::new();
        P4::init_access(P4, system_meta, &mut access_set, world);
        component_access_set.extend(access_set);
        let mut access_set = FilteredAccessSet::new();
        P5::init_access(P5, system_meta, &mut access_set, world);
        component_access_set.extend(access_set);
        let mut access_set = FilteredAccessSet::new();
        P6::init_access(P6, system_meta, &mut access_set, world);
        component_access_set.extend(access_set);
        let mut access_set = FilteredAccessSet::new();
        P7::init_access(P7, system_meta, &mut access_set, world);
        component_access_set.extend(access_set);
    }
    fn apply(state: &mut Self::State, system_meta: &SystemMeta,
        world: &mut World) {
        <(P0, P1, P2, P3, P4, P5, P6, P7) as
                SystemParam>::apply(state, system_meta, world);
    }
    fn queue(state: &mut Self::State, system_meta: &SystemMeta,
        mut world: DeferredWorld) {
        <(P0, P1, P2, P3, P4, P5, P6, P7) as
                SystemParam>::queue(state, system_meta, world.reborrow());
    }
    #[inline]
    unsafe fn get_param<'w,
        's>(state: &'s mut Self::State, system_meta: &SystemMeta,
        world: UnsafeWorldCell<'w>, change_tick: Tick)
        -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
        drop(unsafe {
                    P0::get_param(&mut state.0, system_meta, world, change_tick)
                }?);
        drop(unsafe {
                    P1::get_param(&mut state.1, system_meta, world, change_tick)
                }?);
        drop(unsafe {
                    P2::get_param(&mut state.2, system_meta, world, change_tick)
                }?);
        drop(unsafe {
                    P3::get_param(&mut state.3, system_meta, world, change_tick)
                }?);
        drop(unsafe {
                    P4::get_param(&mut state.4, system_meta, world, change_tick)
                }?);
        drop(unsafe {
                    P5::get_param(&mut state.5, system_meta, world, change_tick)
                }?);
        drop(unsafe {
                    P6::get_param(&mut state.6, system_meta, world, change_tick)
                }?);
        drop(unsafe {
                    P7::get_param(&mut state.7, system_meta, world, change_tick)
                }?);
        Ok(ParamSet {
                param_states: state,
                system_meta: system_meta.clone(),
                world,
                change_tick,
            })
    }
}
impl<'w, 's, P0: SystemParam, P1: SystemParam, P2: SystemParam,
    P3: SystemParam, P4: SystemParam, P5: SystemParam, P6: SystemParam,
    P7: SystemParam> ParamSet<'w, 's, (P0, P1, P2, P3, P4, P5, P6, P7)> {
    /// Gets exclusive access to the parameter at index
    #[doc = "0"]
    /// in this [`ParamSet`].
    /// No other parameters may be accessed while this one is active.
    pub fn p0<'a>(&'a mut self) -> SystemParamItem<'a, 'a, P0> {
        unsafe {
                P0::get_param(&mut self.param_states.0, &self.system_meta,
                    self.world, self.change_tick)
            }.unwrap_or_else(|err|
                {
                    ::core::panicking::panic_fmt(format_args!("ParamSet parameter validation failed: {0}",
                            err));
                })
    }
    /// Gets exclusive access to the parameter at index
    #[doc = "1"]
    /// in this [`ParamSet`].
    /// No other parameters may be accessed while this one is active.
    pub fn p1<'a>(&'a mut self) -> SystemParamItem<'a, 'a, P1> {
        unsafe {
                P1::get_param(&mut self.param_states.1, &self.system_meta,
                    self.world, self.change_tick)
            }.unwrap_or_else(|err|
                {
                    ::core::panicking::panic_fmt(format_args!("ParamSet parameter validation failed: {0}",
                            err));
                })
    }
    /// Gets exclusive access to the parameter at index
    #[doc = "2"]
    /// in this [`ParamSet`].
    /// No other parameters may be accessed while this one is active.
    pub fn p2<'a>(&'a mut self) -> SystemParamItem<'a, 'a, P2> {
        unsafe {
                P2::get_param(&mut self.param_states.2, &self.system_meta,
                    self.world, self.change_tick)
            }.unwrap_or_else(|err|
                {
                    ::core::panicking::panic_fmt(format_args!("ParamSet parameter validation failed: {0}",
                            err));
                })
    }
    /// Gets exclusive access to the parameter at index
    #[doc = "3"]
    /// in this [`ParamSet`].
    /// No other parameters may be accessed while this one is active.
    pub fn p3<'a>(&'a mut self) -> SystemParamItem<'a, 'a, P3> {
        unsafe {
                P3::get_param(&mut self.param_states.3, &self.system_meta,
                    self.world, self.change_tick)
            }.unwrap_or_else(|err|
                {
                    ::core::panicking::panic_fmt(format_args!("ParamSet parameter validation failed: {0}",
                            err));
                })
    }
    /// Gets exclusive access to the parameter at index
    #[doc = "4"]
    /// in this [`ParamSet`].
    /// No other parameters may be accessed while this one is active.
    pub fn p4<'a>(&'a mut self) -> SystemParamItem<'a, 'a, P4> {
        unsafe {
                P4::get_param(&mut self.param_states.4, &self.system_meta,
                    self.world, self.change_tick)
            }.unwrap_or_else(|err|
                {
                    ::core::panicking::panic_fmt(format_args!("ParamSet parameter validation failed: {0}",
                            err));
                })
    }
    /// Gets exclusive access to the parameter at index
    #[doc = "5"]
    /// in this [`ParamSet`].
    /// No other parameters may be accessed while this one is active.
    pub fn p5<'a>(&'a mut self) -> SystemParamItem<'a, 'a, P5> {
        unsafe {
                P5::get_param(&mut self.param_states.5, &self.system_meta,
                    self.world, self.change_tick)
            }.unwrap_or_else(|err|
                {
                    ::core::panicking::panic_fmt(format_args!("ParamSet parameter validation failed: {0}",
                            err));
                })
    }
    /// Gets exclusive access to the parameter at index
    #[doc = "6"]
    /// in this [`ParamSet`].
    /// No other parameters may be accessed while this one is active.
    pub fn p6<'a>(&'a mut self) -> SystemParamItem<'a, 'a, P6> {
        unsafe {
                P6::get_param(&mut self.param_states.6, &self.system_meta,
                    self.world, self.change_tick)
            }.unwrap_or_else(|err|
                {
                    ::core::panicking::panic_fmt(format_args!("ParamSet parameter validation failed: {0}",
                            err));
                })
    }
    /// Gets exclusive access to the parameter at index
    #[doc = "7"]
    /// in this [`ParamSet`].
    /// No other parameters may be accessed while this one is active.
    pub fn p7<'a>(&'a mut self) -> SystemParamItem<'a, 'a, P7> {
        unsafe {
                P7::get_param(&mut self.param_states.7, &self.system_meta,
                    self.world, self.change_tick)
            }.unwrap_or_else(|err|
                {
                    ::core::panicking::panic_fmt(format_args!("ParamSet parameter validation failed: {0}",
                            err));
                })
    }
}all_tuples_enumerated!(impl_param_set, 1, 8, P, p);
665
666// SAFETY: Res only reads a single World resource
667unsafe impl<'a, T: Resource> ReadOnlySystemParam for Res<'a, T> {}
668
669// SAFETY: Res ComponentId access is applied to SystemMeta. If this Res
670// conflicts with any prior access, a panic will occur.
671unsafe impl<'a, T: Resource> SystemParam for Res<'a, T> {
672    type State = ComponentId;
673    type Item<'w, 's> = Res<'w, T>;
674
675    fn init_state(world: &mut World) -> Self::State {
676        world.components_registrator().register_component::<T>()
677    }
678
679    fn init_access(
680        &component_id: &Self::State,
681        system_meta: &mut SystemMeta,
682        component_access_set: &mut FilteredAccessSet,
683        world: &mut World,
684    ) {
685        let mut filter = FilteredAccess::default();
686        filter.add_read(component_id);
687        filter.and_with(IS_RESOURCE);
688
689        let conflicts = component_access_set.get_conflicts_single(&filter);
690        if conflicts.is_empty() {
691            component_access_set.add(filter);
692            return;
693        }
694
695        let mut accesses = conflicts.format_conflict_list(world.as_unsafe_world_cell());
696        // Access list may be empty (if access to all components requested)
697        if !accesses.is_empty() {
698            accesses.push(' ');
699        }
700        {
    ::core::panicking::panic_fmt(format_args!("error[B0002]: Res<{0}> in system {1} conflicts with a previous system parameter. Consider removing the duplicate access using `Without<IsResource>` to create disjoint Queries or merging conflicting Queries into a `ParamSet`. See: https://bevy.org/learn/errors/b0002",
            DebugName::type_name::<T>(), system_meta.name));
};panic!("error[B0002]: Res<{}> in system {} conflicts with a previous system parameter. Consider removing the duplicate access using `Without<IsResource>` to create disjoint Queries or merging conflicting Queries into a `ParamSet`. See: https://bevy.org/learn/errors/b0002", DebugName::type_name::<T>(), system_meta.name);
701    }
702
703    #[inline]
704    unsafe fn get_param<'w, 's>(
705        &mut component_id: &'s mut Self::State,
706        system_meta: &SystemMeta,
707        world: UnsafeWorldCell<'w>,
708        change_tick: Tick,
709    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
710        let (ptr, ticks) = world.get_resource_with_ticks(component_id).ok_or_else(|| {
711            SystemParamValidationError::invalid::<Self>("Resource does not exist")
712        })?;
713        Ok(Res {
714            value: ptr.deref(),
715            ticks: ComponentTicksRef {
716                added: ticks.added.deref(),
717                changed: ticks.changed.deref(),
718                changed_by: ticks.changed_by.map(|changed_by| changed_by.deref()),
719                last_run: system_meta.last_run,
720                this_run: change_tick,
721            },
722        })
723    }
724}
725
726// SAFETY: Res ComponentId access is applied to SystemMeta. If this Res
727// conflicts with any prior access, a panic will occur.
728unsafe impl<'a, T: Resource<Mutability = Mutable>> SystemParam for ResMut<'a, T> {
729    type State = ComponentId;
730    type Item<'w, 's> = ResMut<'w, T>;
731
732    fn init_state(world: &mut World) -> Self::State {
733        world.components_registrator().register_component::<T>()
734    }
735
736    fn init_access(
737        &component_id: &Self::State,
738        system_meta: &mut SystemMeta,
739        component_access_set: &mut FilteredAccessSet,
740        world: &mut World,
741    ) {
742        let mut filter = FilteredAccess::default();
743        filter.add_write(component_id);
744        filter.and_with(IS_RESOURCE);
745
746        let conflicts = component_access_set.get_conflicts_single(&filter);
747        if conflicts.is_empty() {
748            component_access_set.add(filter);
749            return;
750        }
751
752        let mut accesses = conflicts.format_conflict_list(world.as_unsafe_world_cell());
753        // Access list may be empty (if access to all components requested)
754        if !accesses.is_empty() {
755            accesses.push(' ');
756        }
757        {
    ::core::panicking::panic_fmt(format_args!("error[B0002]: ResMut<{0}> in system {1} conflicts with a previous system parameter. Consider removing the duplicate access or using `Without<IsResource>` to create disjoint Queries or merging conflicting Queries into a `ParamSet`. See: https://bevy.org/learn/errors/b0002",
            DebugName::type_name::<T>(), system_meta.name));
};panic!("error[B0002]: ResMut<{}> in system {} conflicts with a previous system parameter. Consider removing the duplicate access or using `Without<IsResource>` to create disjoint Queries or merging conflicting Queries into a `ParamSet`. See: https://bevy.org/learn/errors/b0002", DebugName::type_name::<T>(), system_meta.name);
758    }
759
760    #[inline]
761    unsafe fn get_param<'w, 's>(
762        &mut component_id: &'s mut Self::State,
763        system_meta: &SystemMeta,
764        world: UnsafeWorldCell<'w>,
765        change_tick: Tick,
766    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
767        let value = world.get_resource_mut_by_id(component_id).ok_or_else(|| {
768            SystemParamValidationError::invalid::<Self>("Resource does not exist")
769        })?;
770        Ok(ResMut {
771            value: value.value.deref_mut::<T>(),
772            ticks: ComponentTicksMut {
773                added: value.ticks.added,
774                changed: value.ticks.changed,
775                changed_by: value.ticks.changed_by,
776                last_run: system_meta.last_run,
777                this_run: change_tick,
778            },
779        })
780    }
781}
782
783// SAFETY: only reads world
784unsafe impl<'w> ReadOnlySystemParam for &'w World {}
785
786// SAFETY: `read_all` access is set and conflicts result in a panic
787unsafe impl SystemParam for &'_ World {
788    type State = ();
789    type Item<'w, 's> = &'w World;
790
791    fn init_state(_world: &mut World) -> Self::State {}
792
793    fn init_access(
794        _state: &Self::State,
795        _system_meta: &mut SystemMeta,
796        component_access_set: &mut FilteredAccessSet,
797        _world: &mut World,
798    ) {
799        let mut filtered_access = FilteredAccess::default();
800
801        filtered_access.read_all();
802        if !component_access_set
803            .get_conflicts_single(&filtered_access)
804            .is_empty()
805        {
806            {
    ::core::panicking::panic_fmt(format_args!("&World conflicts with a previous mutable system parameter. Allowing this would break Rust\'s mutability rules"));
};panic!("&World conflicts with a previous mutable system parameter. Allowing this would break Rust's mutability rules");
807        }
808        component_access_set.add(filtered_access);
809    }
810
811    #[inline]
812    unsafe fn get_param<'w, 's>(
813        _state: &'s mut Self::State,
814        _system_meta: &SystemMeta,
815        world: UnsafeWorldCell<'w>,
816        _change_tick: Tick,
817    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
818        // SAFETY: Read-only access to the entire world was registered in `init_state`.
819        Ok(unsafe { world.world() })
820    }
821}
822
823// SAFETY: `DeferredWorld` can read all components and resources but cannot be used to gain any other mutable references.
824unsafe impl<'w> SystemParam for DeferredWorld<'w> {
825    type State = ();
826    type Item<'world, 'state> = DeferredWorld<'world>;
827
828    fn init_state(_world: &mut World) -> Self::State {}
829
830    fn init_access(
831        _state: &Self::State,
832        system_meta: &mut SystemMeta,
833        component_access_set: &mut FilteredAccessSet,
834        _world: &mut World,
835    ) {
836        if !!component_access_set.combined_access().has_any_read() {
    {
        ::core::panicking::panic_fmt(format_args!("DeferredWorld in system {0} conflicts with a previous access.",
                system_meta.name));
    }
};assert!(
837            !component_access_set.combined_access().has_any_read(),
838            "DeferredWorld in system {} conflicts with a previous access.",
839            system_meta.name,
840        );
841        component_access_set.write_all();
842    }
843
844    unsafe fn get_param<'world, 'state>(
845        _state: &'state mut Self::State,
846        _system_meta: &SystemMeta,
847        world: UnsafeWorldCell<'world>,
848        _change_tick: Tick,
849    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
850        // SAFETY: Upheld by caller
851        Ok(unsafe { world.into_deferred() })
852    }
853}
854
855/// A [`SystemParam`] that provides a system-private value of `T` that persists across system calls.
856///
857/// The initial value is created by calling `T`'s [`FromWorld::from_world`] (or [`Default::default`] if `T: Default`).
858///
859/// A local may only be accessed by the system itself and is therefore not visible to other systems.
860/// If two or more systems specify the same local type each will have their own unique local.
861/// If multiple [`SystemParam`]s within the same system each specify the same local type
862/// each will get their own distinct data storage.
863///
864/// The supplied lifetime parameter is the [`SystemParam`]s `'s` lifetime.
865///
866/// # Examples
867///
868/// ```
869/// # use bevy_ecs::prelude::*;
870/// # let world = &mut World::default();
871/// fn counter(mut count: Local<u32>) -> u32 {
872///     *count += 1;
873///     *count
874/// }
875/// let mut counter_system = IntoSystem::into_system(counter);
876/// counter_system.initialize(world);
877///
878/// // Counter is initialized to u32's default value of 0, and increases to 1 on first run.
879/// assert_eq!(counter_system.run((), world).unwrap(), 1);
880/// // Counter gets the same value and increases to 2 on its second call.
881/// assert_eq!(counter_system.run((), world).unwrap(), 2);
882/// ```
883///
884/// A simple way to set a different default value for a local is by wrapping the value with an Option.
885///
886/// ```
887/// # use bevy_ecs::prelude::*;
888/// # let world = &mut World::default();
889/// fn counter_from_10(mut count: Local<Option<u32>>) -> u32 {
890///     let count = count.get_or_insert(10);
891///     *count += 1;
892///     *count
893/// }
894/// let mut counter_system = IntoSystem::into_system(counter_from_10);
895/// counter_system.initialize(world);
896///
897/// // Counter is initialized at 10, and increases to 11 on first run.
898/// assert_eq!(counter_system.run((), world).unwrap(), 11);
899/// // Counter is only increased by 1 on subsequent runs.
900/// assert_eq!(counter_system.run((), world).unwrap(), 12);
901/// ```
902///
903/// A system can have multiple `Local` values with the same type, each with distinct values.
904///
905/// ```
906/// # use bevy_ecs::prelude::*;
907/// # let world = &mut World::default();
908/// fn double_counter(mut count: Local<u32>, mut double_count: Local<u32>) -> (u32, u32) {
909///     *count += 1;
910///     *double_count += 2;
911///     (*count, *double_count)
912/// }
913/// let mut counter_system = IntoSystem::into_system(double_counter);
914/// counter_system.initialize(world);
915///
916/// assert_eq!(counter_system.run((), world).unwrap(), (1, 2));
917/// assert_eq!(counter_system.run((), world).unwrap(), (2, 4));
918/// ```
919///
920/// This example shows that two systems using the same type for their own `Local` get distinct locals.
921///
922/// ```
923/// # use bevy_ecs::prelude::*;
924/// # let world = &mut World::default();
925/// fn write_to_local(mut local: Local<usize>) {
926///     *local = 42;
927/// }
928/// fn read_from_local(local: Local<usize>) -> usize {
929///     *local
930/// }
931/// let mut write_system = IntoSystem::into_system(write_to_local);
932/// let mut read_system = IntoSystem::into_system(read_from_local);
933/// write_system.initialize(world);
934/// read_system.initialize(world);
935///
936/// assert_eq!(read_system.run((), world).unwrap(), 0);
937/// write_system.run((), world);
938/// // The read local is still 0 due to the locals not being shared.
939/// assert_eq!(read_system.run((), world).unwrap(), 0);
940/// ```
941///
942/// You can use a `Local` to avoid reallocating memory every system call.
943///
944/// ```
945/// # use bevy_ecs::prelude::*;
946/// fn some_system(mut vec: Local<Vec<u32>>) {
947///     // Do your regular system logic, using the vec, as normal.
948///
949///     // At end of function, clear the vec's contents so its empty for next system call.
950///     // If it's possible the capacity could get too large, you may want to check and resize that as well.
951///     vec.clear();
952/// }
953/// ```
954///
955/// N.B. A [`Local`]s value cannot be read or written to outside of the containing system.
956/// To add configuration to a system, convert a capturing closure into the system instead:
957///
958/// ```
959/// # use bevy_ecs::prelude::*;
960/// # use bevy_ecs::system::assert_is_system;
961/// struct Config(u32);
962/// #[derive(Resource)]
963/// struct MyU32Wrapper(u32);
964/// fn reset_to_system(value: Config) -> impl FnMut(ResMut<MyU32Wrapper>) {
965///     move |mut val| val.0 = value.0
966/// }
967///
968/// // .add_systems(reset_to_system(my_config))
969/// # assert_is_system(reset_to_system(Config(10)));
970/// ```
971#[derive(#[automatically_derived]
impl<'s, T: ::core::fmt::Debug + FromWorld + Send + 'static>
    ::core::fmt::Debug for Local<'s, T> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Local",
            &&self.0)
    }
}Debug)]
972pub struct Local<'s, T: FromWorld + Send + 'static>(pub(crate) &'s mut T);
973
974// SAFETY: Local only accesses internal state
975unsafe impl<'s, T: FromWorld + Send + 'static> ReadOnlySystemParam for Local<'s, T> {}
976
977impl<'s, T: FromWorld + Send + 'static> Deref for Local<'s, T> {
978    type Target = T;
979
980    #[inline]
981    fn deref(&self) -> &Self::Target {
982        self.0
983    }
984}
985
986impl<'s, T: FromWorld + Send + 'static> DerefMut for Local<'s, T> {
987    #[inline]
988    fn deref_mut(&mut self) -> &mut Self::Target {
989        self.0
990    }
991}
992
993impl<'s, 'a, T: FromWorld + Send + 'static> IntoIterator for &'a Local<'s, T>
994where
995    &'a T: IntoIterator,
996{
997    type Item = <&'a T as IntoIterator>::Item;
998    type IntoIter = <&'a T as IntoIterator>::IntoIter;
999
1000    fn into_iter(self) -> Self::IntoIter {
1001        self.0.into_iter()
1002    }
1003}
1004
1005impl<'s, 'a, T: FromWorld + Send + 'static> IntoIterator for &'a mut Local<'s, T>
1006where
1007    &'a mut T: IntoIterator,
1008{
1009    type Item = <&'a mut T as IntoIterator>::Item;
1010    type IntoIter = <&'a mut T as IntoIterator>::IntoIter;
1011
1012    fn into_iter(self) -> Self::IntoIter {
1013        self.0.into_iter()
1014    }
1015}
1016
1017// SAFETY: only local state is accessed
1018unsafe impl<'a, T: FromWorld + Send + 'static> SystemParam for Local<'a, T> {
1019    type State = SyncCell<T>;
1020    type Item<'w, 's> = Local<'s, T>;
1021
1022    fn init_state(world: &mut World) -> Self::State {
1023        SyncCell::new(T::from_world(world))
1024    }
1025
1026    fn init_access(
1027        _state: &Self::State,
1028        _system_meta: &mut SystemMeta,
1029        _component_access_set: &mut FilteredAccessSet,
1030        _world: &mut World,
1031    ) {
1032    }
1033
1034    #[inline]
1035    unsafe fn get_param<'w, 's>(
1036        state: &'s mut Self::State,
1037        _system_meta: &SystemMeta,
1038        _world: UnsafeWorldCell<'w>,
1039        _change_tick: Tick,
1040    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1041        Ok(Local(state.get()))
1042    }
1043}
1044
1045/// Types that can be used with [`Deferred<T>`] in systems.
1046/// This allows storing system-local data which is used to defer [`World`] mutations.
1047///
1048/// Types that implement `SystemBuffer` should take care to perform as many
1049/// computations up-front as possible. Buffers cannot be applied in parallel,
1050/// so you should try to minimize the time spent in [`SystemBuffer::apply`].
1051pub trait SystemBuffer: FromWorld + Send + 'static {
1052    /// Applies any deferred mutations to the [`World`].
1053    fn apply(&mut self, system_meta: &SystemMeta, world: &mut World) {
1054        self.queue(system_meta, world.into());
1055    }
1056    /// Queues any deferred mutations to be applied at the next [`ApplyDeferred`](crate::prelude::ApplyDeferred).
1057    ///
1058    /// To queue structural changes to [`DeferredWorld`], a command queue of the [`DeferredWorld`]
1059    /// should be used via [`commands`](crate::world::DeferredWorld::commands).
1060    fn queue(&mut self, _system_meta: &SystemMeta, _world: DeferredWorld);
1061}
1062
1063/// A [`SystemParam`] that stores a buffer which gets applied to the [`World`] during
1064/// [`ApplyDeferred`](crate::schedule::ApplyDeferred).
1065/// This is used internally by [`Commands`] to defer `World` mutations.
1066///
1067/// [`Commands`]: crate::system::Commands
1068///
1069/// # Examples
1070///
1071/// By using this type to defer mutations, you can avoid mutable `World` access within
1072/// a system, which allows it to run in parallel with more systems.
1073///
1074/// Note that deferring mutations is *not* free, and should only be used if
1075/// the gains in parallelization outweigh the time it takes to apply deferred mutations.
1076/// In general, [`Deferred`] should only be used for mutations that are infrequent,
1077/// or which otherwise take up a small portion of a system's run-time.
1078///
1079/// ```
1080/// # use bevy_ecs::prelude::*;
1081/// # use bevy_ecs::world::DeferredWorld;
1082/// // Tracks whether or not there is a threat the player should be aware of.
1083/// #[derive(Resource, Default)]
1084/// pub struct Alarm(bool);
1085///
1086/// #[derive(Component)]
1087/// pub struct Settlement {
1088///     // ...
1089/// }
1090///
1091/// // A threat from inside the settlement.
1092/// #[derive(Component)]
1093/// pub struct Criminal;
1094///
1095/// // A threat from outside the settlement.
1096/// #[derive(Component)]
1097/// pub struct Monster;
1098///
1099/// # impl Criminal { pub fn is_threat(&self, _: &Settlement) -> bool { true } }
1100///
1101/// use bevy_ecs::system::{Deferred, SystemBuffer, SystemMeta};
1102///
1103/// // Uses deferred mutations to allow signaling the alarm from multiple systems in parallel.
1104/// #[derive(Resource, Default)]
1105/// struct AlarmFlag(bool);
1106///
1107/// impl AlarmFlag {
1108///     /// Sounds the alarm the next time buffers are applied via ApplyDeferred.
1109///     pub fn flag(&mut self) {
1110///         self.0 = true;
1111///     }
1112/// }
1113///
1114/// impl SystemBuffer for AlarmFlag {
1115///     // When `AlarmFlag` is used in a system, this function will get
1116///     // called the next time buffers are applied via ApplyDeferred.
1117///     fn queue(&mut self, system_meta: &SystemMeta, mut world: DeferredWorld) {
1118///         if self.0 {
1119///             world.resource_mut::<Alarm>().0 = true;
1120///             self.0 = false;
1121///         }
1122///     }
1123/// }
1124///
1125/// // Sound the alarm if there are any criminals who pose a threat.
1126/// fn alert_criminal(
1127///     settlement: Single<&Settlement>,
1128///     criminals: Query<&Criminal>,
1129///     mut alarm: Deferred<AlarmFlag>
1130/// ) {
1131///     for criminal in &criminals {
1132///         // Only sound the alarm if the criminal is a threat.
1133///         // For this example, assume that this check is expensive to run.
1134///         // Since the majority of this system's run-time is dominated
1135///         // by calling `is_threat()`, we defer sounding the alarm to
1136///         // allow this system to run in parallel with other alarm systems.
1137///         if criminal.is_threat(*settlement) {
1138///             alarm.flag();
1139///         }
1140///     }
1141/// }
1142///
1143/// // Sound the alarm if there is a monster.
1144/// fn alert_monster(
1145///     monsters: Query<&Monster>,
1146///     mut alarm: ResMut<Alarm>
1147/// ) {
1148///     if monsters.iter().next().is_some() {
1149///         // Since this system does nothing except for sounding the alarm,
1150///         // it would be pointless to defer it, so we sound the alarm directly.
1151///         alarm.0 = true;
1152///     }
1153/// }
1154///
1155/// let mut world = World::new();
1156/// world.init_resource::<Alarm>();
1157/// world.spawn(Settlement {
1158///     // ...
1159/// });
1160///
1161/// let mut schedule = Schedule::default();
1162/// // These two systems have no conflicts and will run in parallel.
1163/// schedule.add_systems((alert_criminal, alert_monster));
1164///
1165/// // There are no criminals or monsters, so the alarm is not sounded.
1166/// schedule.run(&mut world);
1167/// assert_eq!(world.resource::<Alarm>().0, false);
1168///
1169/// // Spawn a monster, which will cause the alarm to be sounded.
1170/// let m_id = world.spawn(Monster).id();
1171/// schedule.run(&mut world);
1172/// assert_eq!(world.resource::<Alarm>().0, true);
1173///
1174/// // Remove the monster and reset the alarm.
1175/// world.entity_mut(m_id).despawn();
1176/// world.resource_mut::<Alarm>().0 = false;
1177///
1178/// // Spawn a criminal, which will cause the alarm to be sounded.
1179/// world.spawn(Criminal);
1180/// schedule.run(&mut world);
1181/// assert_eq!(world.resource::<Alarm>().0, true);
1182/// ```
1183pub struct Deferred<'a, T: SystemBuffer>(pub(crate) &'a mut T);
1184
1185impl<'a, T: SystemBuffer> Deref for Deferred<'a, T> {
1186    type Target = T;
1187    #[inline]
1188    fn deref(&self) -> &Self::Target {
1189        self.0
1190    }
1191}
1192
1193impl<'a, T: SystemBuffer> DerefMut for Deferred<'a, T> {
1194    #[inline]
1195    fn deref_mut(&mut self) -> &mut Self::Target {
1196        self.0
1197    }
1198}
1199
1200impl<T: SystemBuffer> Deferred<'_, T> {
1201    /// Returns a [`Deferred<T>`] with a smaller lifetime.
1202    /// This is useful if you have `&mut Deferred<T>` but need `Deferred<T>`.
1203    pub fn reborrow(&mut self) -> Deferred<'_, T> {
1204        Deferred(self.0)
1205    }
1206}
1207
1208// SAFETY: Only local state is accessed.
1209unsafe impl<T: SystemBuffer> ReadOnlySystemParam for Deferred<'_, T> {}
1210
1211// SAFETY: Only local state is accessed.
1212unsafe impl<T: SystemBuffer> SystemParam for Deferred<'_, T> {
1213    type State = SyncCell<T>;
1214    type Item<'w, 's> = Deferred<'s, T>;
1215
1216    #[track_caller]
1217    fn init_state(world: &mut World) -> Self::State {
1218        SyncCell::new(T::from_world(world))
1219    }
1220
1221    fn init_access(
1222        _state: &Self::State,
1223        system_meta: &mut SystemMeta,
1224        _component_access_set: &mut FilteredAccessSet,
1225        _world: &mut World,
1226    ) {
1227        system_meta.set_has_deferred();
1228    }
1229
1230    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1231        state.get().apply(system_meta, world);
1232    }
1233
1234    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1235        state.get().queue(system_meta, world);
1236    }
1237
1238    #[inline]
1239    unsafe fn get_param<'w, 's>(
1240        state: &'s mut Self::State,
1241        _system_meta: &SystemMeta,
1242        _world: UnsafeWorldCell<'w>,
1243        _change_tick: Tick,
1244    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1245        Ok(Deferred(state.get()))
1246    }
1247}
1248
1249/// A dummy type to tell the executor to run the system exclusively.
1250pub struct ExclusiveMarker(PhantomData<()>);
1251
1252// SAFETY: No world access.
1253unsafe impl SystemParam for ExclusiveMarker {
1254    type State = ();
1255    type Item<'w, 's> = Self;
1256
1257    #[inline]
1258    fn init_state(_world: &mut World) -> Self::State {}
1259
1260    fn init_access(
1261        _state: &Self::State,
1262        system_meta: &mut SystemMeta,
1263        _component_access_set: &mut FilteredAccessSet,
1264        _world: &mut World,
1265    ) {
1266        system_meta.set_exclusive();
1267    }
1268
1269    #[inline]
1270    unsafe fn get_param<'world, 'state>(
1271        _state: &'state mut Self::State,
1272        _system_meta: &SystemMeta,
1273        _world: UnsafeWorldCell<'world>,
1274        _change_tick: Tick,
1275    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1276        Ok(Self(PhantomData))
1277    }
1278}
1279
1280// SAFETY: Does not read any world state
1281unsafe impl ReadOnlySystemParam for ExclusiveMarker {}
1282
1283/// A dummy type that is [`!Send`](Send), to force systems to run on the main thread.
1284pub struct NonSendMarker(PhantomData<*mut ()>);
1285
1286// SAFETY: No world access.
1287unsafe impl SystemParam for NonSendMarker {
1288    type State = ();
1289    type Item<'w, 's> = Self;
1290
1291    #[inline]
1292    fn init_state(_world: &mut World) -> Self::State {}
1293
1294    fn init_access(
1295        _state: &Self::State,
1296        system_meta: &mut SystemMeta,
1297        _component_access_set: &mut FilteredAccessSet,
1298        _world: &mut World,
1299    ) {
1300        system_meta.set_non_send();
1301    }
1302
1303    #[inline]
1304    unsafe fn get_param<'world, 'state>(
1305        _state: &'state mut Self::State,
1306        _system_meta: &SystemMeta,
1307        _world: UnsafeWorldCell<'world>,
1308        _change_tick: Tick,
1309    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1310        Ok(Self(PhantomData))
1311    }
1312}
1313
1314// SAFETY: Does not read any world state
1315unsafe impl ReadOnlySystemParam for NonSendMarker {}
1316
1317// SAFETY: Only reads a single World non-send resource
1318unsafe impl<'w, T> ReadOnlySystemParam for NonSend<'w, T> {}
1319
1320// SAFETY: NonSendComponentId access is applied to SystemMeta. If this
1321// NonSend conflicts with any prior access, a panic will occur.
1322unsafe impl<'a, T: 'static> SystemParam for NonSend<'a, T> {
1323    type State = ComponentId;
1324    type Item<'w, 's> = NonSend<'w, T>;
1325
1326    fn init_state(world: &mut World) -> Self::State {
1327        world.components_registrator().register_non_send::<T>()
1328    }
1329
1330    fn init_access(
1331        &component_id: &Self::State,
1332        system_meta: &mut SystemMeta,
1333        component_access_set: &mut FilteredAccessSet,
1334        _world: &mut World,
1335    ) {
1336        system_meta.set_non_send();
1337
1338        let combined_access = component_access_set.combined_access();
1339        if !!combined_access.has_write(component_id) {
    {
        ::core::panicking::panic_fmt(format_args!("error[B0002]: NonSend<{0}> in system {1} conflicts with a previous mutable resource access ({0}). Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002",
                DebugName::type_name::<T>(), system_meta.name));
    }
};assert!(
1340            !combined_access.has_write(component_id),
1341            "error[B0002]: NonSend<{}> in system {} conflicts with a previous mutable resource access ({0}). Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002",
1342            DebugName::type_name::<T>(),
1343            system_meta.name,
1344        );
1345        component_access_set.add_unfiltered_component_read(component_id);
1346    }
1347
1348    #[inline]
1349    unsafe fn get_param<'w, 's>(
1350        &mut component_id: &'s mut Self::State,
1351        system_meta: &SystemMeta,
1352        world: UnsafeWorldCell<'w>,
1353        change_tick: Tick,
1354    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1355        let (ptr, ticks) = world.get_non_send_with_ticks(component_id).ok_or_else(|| {
1356            SystemParamValidationError::invalid::<Self>("Non-send data not found")
1357        })?;
1358        Ok(NonSend {
1359            value: ptr.deref(),
1360            ticks: ComponentTicksRef::from_tick_cells(ticks, system_meta.last_run, change_tick),
1361        })
1362    }
1363}
1364
1365// SAFETY: NonSendMut ComponentId access is applied to SystemMeta. If this
1366// NonSendMut conflicts with any prior access, a panic will occur.
1367unsafe impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> {
1368    type State = ComponentId;
1369    type Item<'w, 's> = NonSendMut<'w, T>;
1370
1371    fn init_state(world: &mut World) -> Self::State {
1372        world.components_registrator().register_non_send::<T>()
1373    }
1374
1375    fn init_access(
1376        &component_id: &Self::State,
1377        system_meta: &mut SystemMeta,
1378        component_access_set: &mut FilteredAccessSet,
1379        _world: &mut World,
1380    ) {
1381        system_meta.set_non_send();
1382
1383        let combined_access = component_access_set.combined_access();
1384        if combined_access.has_write(component_id) {
1385            {
    ::core::panicking::panic_fmt(format_args!("error[B0002]: NonSendMut<{0}> in system {1} conflicts with a previous mutable resource access ({0}). Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002",
            DebugName::type_name::<T>(), system_meta.name));
};panic!(
1386                "error[B0002]: NonSendMut<{}> in system {} conflicts with a previous mutable resource access ({0}). Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002",
1387                DebugName::type_name::<T>(), system_meta.name);
1388        } else if combined_access.has_read(component_id) {
1389            {
    ::core::panicking::panic_fmt(format_args!("error[B0002]: NonSendMut<{0}> in system {1} conflicts with a previous immutable resource access ({0}). Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002",
            DebugName::type_name::<T>(), system_meta.name));
};panic!(
1390                "error[B0002]: NonSendMut<{}> in system {} conflicts with a previous immutable resource access ({0}). Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002",
1391                DebugName::type_name::<T>(), system_meta.name);
1392        }
1393        component_access_set.add_unfiltered_component_write(component_id);
1394    }
1395
1396    #[inline]
1397    unsafe fn get_param<'w, 's>(
1398        &mut component_id: &'s mut Self::State,
1399        system_meta: &SystemMeta,
1400        world: UnsafeWorldCell<'w>,
1401        change_tick: Tick,
1402    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1403        let (ptr, ticks) = world.get_non_send_with_ticks(component_id).ok_or_else(|| {
1404            SystemParamValidationError::invalid::<Self>("Non-send data not found")
1405        })?;
1406        Ok(NonSendMut {
1407            value: ptr.assert_unique().deref_mut(),
1408            ticks: ComponentTicksMut::from_tick_cells(ticks, system_meta.last_run, change_tick),
1409        })
1410    }
1411}
1412
1413// SAFETY: Only reads World archetypes
1414unsafe impl<'a> ReadOnlySystemParam for &'a Archetypes {}
1415
1416// SAFETY: no component value access
1417unsafe impl<'a> SystemParam for &'a Archetypes {
1418    type State = ();
1419    type Item<'w, 's> = &'w Archetypes;
1420
1421    fn init_state(_world: &mut World) -> Self::State {}
1422
1423    fn init_access(
1424        _state: &Self::State,
1425        _system_meta: &mut SystemMeta,
1426        _component_access_set: &mut FilteredAccessSet,
1427        _world: &mut World,
1428    ) {
1429    }
1430
1431    #[inline]
1432    unsafe fn get_param<'w, 's>(
1433        _state: &'s mut Self::State,
1434        _system_meta: &SystemMeta,
1435        world: UnsafeWorldCell<'w>,
1436        _change_tick: Tick,
1437    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1438        Ok(world.archetypes())
1439    }
1440}
1441
1442// SAFETY: Only reads World components
1443unsafe impl<'a> ReadOnlySystemParam for &'a Components {}
1444
1445// SAFETY: no component value access
1446unsafe impl<'a> SystemParam for &'a Components {
1447    type State = ();
1448    type Item<'w, 's> = &'w Components;
1449
1450    fn init_state(_world: &mut World) -> Self::State {}
1451
1452    fn init_access(
1453        _state: &Self::State,
1454        _system_meta: &mut SystemMeta,
1455        _component_access_set: &mut FilteredAccessSet,
1456        _world: &mut World,
1457    ) {
1458    }
1459
1460    #[inline]
1461    unsafe fn get_param<'w, 's>(
1462        _state: &'s mut Self::State,
1463        _system_meta: &SystemMeta,
1464        world: UnsafeWorldCell<'w>,
1465        _change_tick: Tick,
1466    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1467        Ok(world.components())
1468    }
1469}
1470
1471// SAFETY: Only reads World entities
1472unsafe impl<'a> ReadOnlySystemParam for &'a Entities {}
1473
1474// SAFETY: no component value access
1475unsafe impl<'a> SystemParam for &'a Entities {
1476    type State = ();
1477    type Item<'w, 's> = &'w Entities;
1478
1479    fn init_state(_world: &mut World) -> Self::State {}
1480
1481    fn init_access(
1482        _state: &Self::State,
1483        _system_meta: &mut SystemMeta,
1484        _component_access_set: &mut FilteredAccessSet,
1485        _world: &mut World,
1486    ) {
1487    }
1488
1489    #[inline]
1490    unsafe fn get_param<'w, 's>(
1491        _state: &'s mut Self::State,
1492        _system_meta: &SystemMeta,
1493        world: UnsafeWorldCell<'w>,
1494        _change_tick: Tick,
1495    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1496        Ok(world.entities())
1497    }
1498}
1499
1500// SAFETY: Only reads World entities
1501unsafe impl<'a> ReadOnlySystemParam for &'a EntityAllocator {}
1502
1503// SAFETY: no component value access
1504unsafe impl<'a> SystemParam for &'a EntityAllocator {
1505    type State = ();
1506    type Item<'w, 's> = &'w EntityAllocator;
1507
1508    fn init_state(_world: &mut World) -> Self::State {}
1509
1510    fn init_access(
1511        _state: &Self::State,
1512        _system_meta: &mut SystemMeta,
1513        _component_access_set: &mut FilteredAccessSet,
1514        _world: &mut World,
1515    ) {
1516    }
1517
1518    #[inline]
1519    unsafe fn get_param<'w, 's>(
1520        _state: &'s mut Self::State,
1521        _system_meta: &SystemMeta,
1522        world: UnsafeWorldCell<'w>,
1523        _change_tick: Tick,
1524    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1525        Ok(world.entity_allocator())
1526    }
1527}
1528
1529// SAFETY: Only reads World bundles
1530unsafe impl<'a> ReadOnlySystemParam for &'a Bundles {}
1531
1532// SAFETY: no component value access
1533unsafe impl<'a> SystemParam for &'a Bundles {
1534    type State = ();
1535    type Item<'w, 's> = &'w Bundles;
1536
1537    fn init_state(_world: &mut World) -> Self::State {}
1538
1539    fn init_access(
1540        _state: &Self::State,
1541        _system_meta: &mut SystemMeta,
1542        _component_access_set: &mut FilteredAccessSet,
1543        _world: &mut World,
1544    ) {
1545    }
1546
1547    #[inline]
1548    unsafe fn get_param<'w, 's>(
1549        _state: &'s mut Self::State,
1550        _system_meta: &SystemMeta,
1551        world: UnsafeWorldCell<'w>,
1552        _change_tick: Tick,
1553    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1554        Ok(world.bundles())
1555    }
1556}
1557
1558/// A [`SystemParam`] that reads the previous and current change ticks of the system.
1559///
1560/// A system's change ticks are updated each time it runs:
1561/// - `last_run` copies the previous value of `change_tick`
1562/// - `this_run` copies the current value of [`World::read_change_tick`]
1563///
1564/// Component change ticks that are more recent than `last_run` will be detected by the system.
1565/// Those can be read by calling [`last_changed`](crate::change_detection::DetectChanges::last_changed)
1566/// on a [`Mut<T>`](crate::change_detection::Mut) or [`ResMut<T>`](ResMut).
1567#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SystemChangeTick {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "SystemChangeTick", "last_run", &self.last_run, "this_run",
            &&self.this_run)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for SystemChangeTick {
    #[inline]
    fn clone(&self) -> SystemChangeTick {
        let _: ::core::clone::AssertParamIsClone<Tick>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for SystemChangeTick { }Copy)]
1568pub struct SystemChangeTick {
1569    last_run: Tick,
1570    this_run: Tick,
1571}
1572
1573impl SystemChangeTick {
1574    /// Returns the current [`World`] change tick seen by the system.
1575    #[inline]
1576    pub fn this_run(&self) -> Tick {
1577        self.this_run
1578    }
1579
1580    /// Returns the [`World`] change tick seen by the system the previous time it ran.
1581    #[inline]
1582    pub fn last_run(&self) -> Tick {
1583        self.last_run
1584    }
1585}
1586
1587// SAFETY: Only reads internal system state
1588unsafe impl ReadOnlySystemParam for SystemChangeTick {}
1589
1590// SAFETY: `SystemChangeTick` doesn't require any world access
1591unsafe impl SystemParam for SystemChangeTick {
1592    type State = ();
1593    type Item<'w, 's> = SystemChangeTick;
1594
1595    fn init_state(_world: &mut World) -> Self::State {}
1596
1597    fn init_access(
1598        _state: &Self::State,
1599        _system_meta: &mut SystemMeta,
1600        _component_access_set: &mut FilteredAccessSet,
1601        _world: &mut World,
1602    ) {
1603    }
1604
1605    #[inline]
1606    unsafe fn get_param<'w, 's>(
1607        _state: &'s mut Self::State,
1608        system_meta: &SystemMeta,
1609        _world: UnsafeWorldCell<'w>,
1610        change_tick: Tick,
1611    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1612        Ok(SystemChangeTick {
1613            last_run: system_meta.last_run,
1614            this_run: change_tick,
1615        })
1616    }
1617}
1618
1619// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1620unsafe impl<T: SystemParam> SystemParam for Option<T> {
1621    type State = T::State;
1622
1623    type Item<'world, 'state> = Option<T::Item<'world, 'state>>;
1624
1625    fn init_state(world: &mut World) -> Self::State {
1626        T::init_state(world)
1627    }
1628
1629    fn init_access(
1630        state: &Self::State,
1631        system_meta: &mut SystemMeta,
1632        component_access_set: &mut FilteredAccessSet,
1633        world: &mut World,
1634    ) {
1635        T::init_access(state, system_meta, component_access_set, world);
1636    }
1637
1638    #[inline]
1639    unsafe fn get_param<'world, 'state>(
1640        state: &'state mut Self::State,
1641        system_meta: &SystemMeta,
1642        world: UnsafeWorldCell<'world>,
1643        change_tick: Tick,
1644    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1645        // SAFETY: Upheld by caller
1646        Ok(unsafe { T::get_param(state, system_meta, world, change_tick) }.ok())
1647    }
1648
1649    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1650        T::apply(state, system_meta, world);
1651    }
1652
1653    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1654        T::queue(state, system_meta, world);
1655    }
1656}
1657
1658// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1659unsafe impl<T: ReadOnlySystemParam> ReadOnlySystemParam for Option<T> {}
1660
1661// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1662unsafe impl<T: SystemParam> SystemParam for Result<T, SystemParamValidationError> {
1663    type State = T::State;
1664
1665    type Item<'world, 'state> = Result<T::Item<'world, 'state>, SystemParamValidationError>;
1666
1667    fn init_state(world: &mut World) -> Self::State {
1668        T::init_state(world)
1669    }
1670
1671    fn init_access(
1672        state: &Self::State,
1673        system_meta: &mut SystemMeta,
1674        component_access_set: &mut FilteredAccessSet,
1675        world: &mut World,
1676    ) {
1677        T::init_access(state, system_meta, component_access_set, world);
1678    }
1679
1680    #[inline]
1681    unsafe fn get_param<'world, 'state>(
1682        state: &'state mut Self::State,
1683        system_meta: &SystemMeta,
1684        world: UnsafeWorldCell<'world>,
1685        change_tick: Tick,
1686    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1687        // SAFETY: Upheld by caller
1688        Ok(unsafe { T::get_param(state, system_meta, world, change_tick) })
1689    }
1690
1691    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1692        T::apply(state, system_meta, world);
1693    }
1694
1695    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1696        T::queue(state, system_meta, world);
1697    }
1698}
1699
1700// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1701unsafe impl<T: ReadOnlySystemParam> ReadOnlySystemParam for Result<T, SystemParamValidationError> {}
1702
1703/// A [`SystemParam`] that wraps another parameter and causes its system to skip instead of failing when the parameter is invalid.
1704///
1705/// # Example
1706///
1707/// ```
1708/// # use bevy_ecs::prelude::*;
1709/// # #[derive(Resource)]
1710/// # struct SomeResource;
1711/// // This system will fail if `SomeResource` is not present.
1712/// fn fails_on_missing_resource(res: Res<SomeResource>) {}
1713///
1714/// // This system will skip without error if `SomeResource` is not present.
1715/// fn skips_on_missing_resource(res: If<Res<SomeResource>>) {
1716///     // The inner parameter is available using `Deref`
1717///     let some_resource: &SomeResource = &res;
1718/// }
1719/// # bevy_ecs::system::assert_is_system(skips_on_missing_resource);
1720/// ```
1721#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug> ::core::fmt::Debug for If<T> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "If", &&self.0)
    }
}Debug)]
1722pub struct If<T>(pub T);
1723
1724impl<T> If<T> {
1725    /// Returns the inner `T`.
1726    ///
1727    /// The inner value is `pub`, so you can also obtain it by destructuring the parameter:
1728    ///
1729    /// ```
1730    /// # use bevy_ecs::prelude::*;
1731    /// # #[derive(Resource)]
1732    /// # struct SomeResource;
1733    /// fn skips_on_missing_resource(If(res): If<Res<SomeResource>>) {
1734    ///     let some_resource: Res<SomeResource> = res;
1735    /// }
1736    /// # bevy_ecs::system::assert_is_system(skips_on_missing_resource);
1737    /// ```
1738    pub fn into_inner(self) -> T {
1739        self.0
1740    }
1741}
1742
1743impl<T> Deref for If<T> {
1744    type Target = T;
1745    fn deref(&self) -> &Self::Target {
1746        &self.0
1747    }
1748}
1749
1750impl<T> DerefMut for If<T> {
1751    fn deref_mut(&mut self) -> &mut Self::Target {
1752        &mut self.0
1753    }
1754}
1755
1756// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1757unsafe impl<T: SystemParam> SystemParam for If<T> {
1758    type State = T::State;
1759
1760    type Item<'world, 'state> = If<T::Item<'world, 'state>>;
1761
1762    fn init_state(world: &mut World) -> Self::State {
1763        T::init_state(world)
1764    }
1765
1766    fn init_access(
1767        state: &Self::State,
1768        system_meta: &mut SystemMeta,
1769        component_access_set: &mut FilteredAccessSet,
1770        world: &mut World,
1771    ) {
1772        T::init_access(state, system_meta, component_access_set, world);
1773    }
1774
1775    #[inline]
1776    unsafe fn get_param<'world, 'state>(
1777        state: &'state mut Self::State,
1778        system_meta: &SystemMeta,
1779        world: UnsafeWorldCell<'world>,
1780        change_tick: Tick,
1781    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1782        // SAFETY: Upheld by caller.
1783        unsafe { T::get_param(state, system_meta, world, change_tick) }
1784            .map(If)
1785            .map_err(|mut e| {
1786                e.skipped = true;
1787                e
1788            })
1789    }
1790
1791    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1792        T::apply(state, system_meta, world);
1793    }
1794
1795    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1796        T::queue(state, system_meta, world);
1797    }
1798}
1799
1800// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1801unsafe impl<T: ReadOnlySystemParam> ReadOnlySystemParam for If<T> {}
1802
1803// SAFETY: Registers access for each element of `state`.
1804// If any one conflicts, it will panic.
1805unsafe impl<T: SystemParam> SystemParam for Vec<T> {
1806    type State = Vec<T::State>;
1807
1808    type Item<'world, 'state> = Vec<T::Item<'world, 'state>>;
1809
1810    fn init_state(_world: &mut World) -> Self::State {
1811        Vec::new()
1812    }
1813
1814    fn init_access(
1815        state: &Self::State,
1816        system_meta: &mut SystemMeta,
1817        component_access_set: &mut FilteredAccessSet,
1818        world: &mut World,
1819    ) {
1820        for state in state {
1821            T::init_access(state, system_meta, component_access_set, world);
1822        }
1823    }
1824
1825    #[inline]
1826    unsafe fn get_param<'world, 'state>(
1827        state: &'state mut Self::State,
1828        system_meta: &SystemMeta,
1829        world: UnsafeWorldCell<'world>,
1830        change_tick: Tick,
1831    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1832        state
1833            .iter_mut()
1834            // SAFETY:
1835            // - We initialized the access for each parameter in `init_access`, so the caller ensures we have access to any world data needed by each param.
1836            // - The caller ensures this was the world used to initialize our state, and we used that world to initialize parameter states
1837            .map(|state| unsafe { T::get_param(state, system_meta, world, change_tick) })
1838            .collect()
1839    }
1840
1841    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1842        for state in state {
1843            T::apply(state, system_meta, world);
1844        }
1845    }
1846
1847    fn queue(state: &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
1848        for state in state {
1849            T::queue(state, system_meta, world.reborrow());
1850        }
1851    }
1852}
1853
1854// SAFETY: Registers access for each element of `state`.
1855// If any one conflicts with a previous parameter,
1856// the call passing a copy of the current access will panic.
1857unsafe impl<T: SystemParam> SystemParam for ParamSet<'_, '_, Vec<T>> {
1858    type State = Vec<T::State>;
1859
1860    type Item<'world, 'state> = ParamSet<'world, 'state, Vec<T>>;
1861
1862    fn init_state(_world: &mut World) -> Self::State {
1863        Vec::new()
1864    }
1865
1866    fn init_access(
1867        state: &Self::State,
1868        system_meta: &mut SystemMeta,
1869        component_access_set: &mut FilteredAccessSet,
1870        world: &mut World,
1871    ) {
1872        for state in state {
1873            // Call `init_access` on a clone of the original access set to check for conflicts
1874            let component_access_set_clone = &mut component_access_set.clone();
1875            T::init_access(state, system_meta, component_access_set_clone, world);
1876        }
1877        for state in state {
1878            // Pretend to add the param to the system alone to gather the new access,
1879            // then merge its access into the system.
1880            let mut access_set = FilteredAccessSet::new();
1881            T::init_access(state, system_meta, &mut access_set, world);
1882            component_access_set.extend(access_set);
1883        }
1884    }
1885
1886    #[inline]
1887    unsafe fn get_param<'world, 'state>(
1888        state: &'state mut Self::State,
1889        system_meta: &SystemMeta,
1890        world: UnsafeWorldCell<'world>,
1891        change_tick: Tick,
1892    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1893        // Validate each sub-param eagerly so that the system is correctly
1894        // skipped by the executor when any sub-param is unavailable.
1895        // PERF: the sub-params will be fetched again lazily when accessed through
1896        // the ParamSet, but this is no worse than the previous
1897        // validate_param + get_param pattern.
1898        for s in state.iter_mut() {
1899            // SAFETY: Upheld by caller.
1900            drop(unsafe { T::get_param(s, system_meta, world, change_tick) }?);
1901        }
1902
1903        Ok(ParamSet {
1904            param_states: state,
1905            system_meta: system_meta.clone(),
1906            world,
1907            change_tick,
1908        })
1909    }
1910
1911    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1912        for state in state {
1913            T::apply(state, system_meta, world);
1914        }
1915    }
1916
1917    fn queue(state: &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
1918        for state in state {
1919            T::queue(state, system_meta, world.reborrow());
1920        }
1921    }
1922}
1923
1924impl<T: SystemParam> ParamSet<'_, '_, Vec<T>> {
1925    /// Accesses the parameter at the given index.
1926    /// No other parameters may be accessed while this one is active.
1927    pub fn get_mut(&mut self, index: usize) -> T::Item<'_, '_> {
1928        // SAFETY:
1929        // - We initialized the access for each parameter, so the caller ensures we have access to any world data needed by any param.
1930        //   We have mutable access to the ParamSet, so no other params in the set are active.
1931        // - The caller of `get_param` ensured that this was the world used to initialize our state, and we used that world to initialize parameter states
1932        unsafe {
1933            T::get_param(
1934                &mut self.param_states[index],
1935                &self.system_meta,
1936                self.world,
1937                self.change_tick,
1938            )
1939            .unwrap()
1940        }
1941    }
1942
1943    /// Calls a closure for each parameter in the set.
1944    pub fn for_each(&mut self, mut f: impl FnMut(T::Item<'_, '_>)) {
1945        self.param_states.iter_mut().for_each(|state| {
1946            f(
1947                // SAFETY:
1948                // - We initialized the access for each parameter, so the caller ensures we have access to any world data needed by any param.
1949                //   We have mutable access to the ParamSet, so no other params in the set are active.
1950                // - The caller of `get_param` ensured that this was the world used to initialize our state, and we used that world to initialize parameter states
1951                unsafe { T::get_param(state, &self.system_meta, self.world, self.change_tick) }
1952                    .unwrap_or_else(|err| {
    ::core::panicking::panic_fmt(format_args!("ParamSet parameter validation failed: {0}",
            err));
}panic!("ParamSet parameter validation failed: {err}")),
1953            );
1954        });
1955    }
1956}
1957
1958macro_rules! impl_system_param_tuple {
1959    ($(#[$meta:meta])* $($param: ident),*) => {
1960        $(#[$meta])*
1961        // SAFETY: tuple consists only of ReadOnlySystemParams
1962        unsafe impl<$($param: ReadOnlySystemParam),*> ReadOnlySystemParam for ($($param,)*) {}
1963
1964        #[expect(
1965            clippy::allow_attributes,
1966            reason = "This is in a macro, and as such, the below lints may not always apply."
1967        )]
1968        #[allow(
1969            non_snake_case,
1970            reason = "Certain variable names are provided by the caller, not by us."
1971        )]
1972        #[allow(
1973            unused_variables,
1974            reason = "Zero-length tuples won't use some of the parameters."
1975        )]
1976        #[allow(clippy::unused_unit, reason = "Zero length tuple is unit.")]
1977        $(#[$meta])*
1978        // SAFETY: implementers of each `SystemParam` in the tuple have validated their impls
1979        unsafe impl<$($param: SystemParam),*> SystemParam for ($($param,)*) {
1980            type State = ($($param::State,)*);
1981            type Item<'w, 's> = ($($param::Item::<'w, 's>,)*);
1982
1983            #[inline]
1984            #[track_caller]
1985            fn init_state(world: &mut World) -> Self::State {
1986                ($($param::init_state(world),)*)
1987            }
1988
1989            fn init_access(state: &Self::State, _system_meta: &mut SystemMeta, _component_access_set: &mut FilteredAccessSet, _world: &mut World) {
1990                let ($($param,)*) = state;
1991                $($param::init_access($param, _system_meta, _component_access_set, _world);)*
1992            }
1993
1994            #[inline]
1995            fn apply(($($param,)*): &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1996                $($param::apply($param, system_meta, world);)*
1997            }
1998
1999            #[inline]
2000            #[allow(
2001                unused_mut,
2002                reason = "The `world` parameter is unused for zero-length tuples; however, it must be mutable for other lengths of tuples."
2003            )]
2004            fn queue(($($param,)*): &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
2005                $($param::queue($param, system_meta, world.reborrow());)*
2006            }
2007
2008            #[inline]
2009            #[track_caller]
2010            unsafe fn get_param<'w, 's>(
2011                state: &'s mut Self::State,
2012                system_meta: &SystemMeta,
2013                world: UnsafeWorldCell<'w>,
2014                change_tick: Tick,
2015            ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
2016                let ($($param,)*) = state;
2017
2018                #[allow(
2019                    unused_unsafe,
2020                    reason = "Zero-length tuples won't have any params to validate."
2021                )]
2022                // SAFETY: Upheld by caller
2023                unsafe {
2024                    #[allow(
2025                        clippy::unused_unit,
2026                        reason = "Zero-length tuples won't have any params to get."
2027                    )]
2028                    Ok(($($param::get_param($param, system_meta, world, change_tick)?,)*))
2029                }
2030            }
2031        }
2032    };
2033}
2034
2035#[doc(hidden)]
unsafe impl<P0: ReadOnlySystemParam, P1: ReadOnlySystemParam,
    P2: ReadOnlySystemParam, P3: ReadOnlySystemParam, P4: ReadOnlySystemParam,
    P5: ReadOnlySystemParam, P6: ReadOnlySystemParam, P7: ReadOnlySystemParam,
    P8: ReadOnlySystemParam, P9: ReadOnlySystemParam,
    P10: ReadOnlySystemParam, P11: ReadOnlySystemParam,
    P12: ReadOnlySystemParam, P13: ReadOnlySystemParam,
    P14: ReadOnlySystemParam, P15: ReadOnlySystemParam> ReadOnlySystemParam
    for (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15)
    {
}
#[expect(clippy :: allow_attributes, reason =
"This is in a macro, and as such, the below lints may not always apply.")]
#[allow(non_snake_case, reason =
"Certain variable names are provided by the caller, not by us.")]
#[allow(unused_variables, reason =
"Zero-length tuples won't use some of the parameters.")]
#[allow(clippy :: unused_unit, reason = "Zero length tuple is unit.")]
#[doc(hidden)]
unsafe impl<P0: SystemParam, P1: SystemParam, P2: SystemParam,
    P3: SystemParam, P4: SystemParam, P5: SystemParam, P6: SystemParam,
    P7: SystemParam, P8: SystemParam, P9: SystemParam, P10: SystemParam,
    P11: SystemParam, P12: SystemParam, P13: SystemParam, P14: SystemParam,
    P15: SystemParam> SystemParam for
    (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15) {
    type State =
        (P0::State, P1::State, P2::State, P3::State, P4::State, P5::State,
        P6::State, P7::State, P8::State, P9::State, P10::State, P11::State,
        P12::State, P13::State, P14::State, P15::State);
    type Item<'w, 's> =
        (P0::Item<'w, 's>, P1::Item<'w, 's>, P2::Item<'w, 's>,
        P3::Item<'w, 's>, P4::Item<'w, 's>, P5::Item<'w, 's>,
        P6::Item<'w, 's>, P7::Item<'w, 's>, P8::Item<'w, 's>,
        P9::Item<'w, 's>, P10::Item<'w, 's>, P11::Item<'w, 's>,
        P12::Item<'w, 's>, P13::Item<'w, 's>, P14::Item<'w, 's>,
        P15::Item<'w, 's>);
    #[inline]
    #[track_caller]
    fn init_state(world: &mut World) -> Self::State {
        (P0::init_state(world), P1::init_state(world), P2::init_state(world),
            P3::init_state(world), P4::init_state(world),
            P5::init_state(world), P6::init_state(world),
            P7::init_state(world), P8::init_state(world),
            P9::init_state(world), P10::init_state(world),
            P11::init_state(world), P12::init_state(world),
            P13::init_state(world), P14::init_state(world),
            P15::init_state(world))
    }
    fn init_access(state: &Self::State, _system_meta: &mut SystemMeta,
        _component_access_set: &mut FilteredAccessSet, _world: &mut World) {
        let (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14,
                P15) = state;
        P0::init_access(P0, _system_meta, _component_access_set, _world);
        P1::init_access(P1, _system_meta, _component_access_set, _world);
        P2::init_access(P2, _system_meta, _component_access_set, _world);
        P3::init_access(P3, _system_meta, _component_access_set, _world);
        P4::init_access(P4, _system_meta, _component_access_set, _world);
        P5::init_access(P5, _system_meta, _component_access_set, _world);
        P6::init_access(P6, _system_meta, _component_access_set, _world);
        P7::init_access(P7, _system_meta, _component_access_set, _world);
        P8::init_access(P8, _system_meta, _component_access_set, _world);
        P9::init_access(P9, _system_meta, _component_access_set, _world);
        P10::init_access(P10, _system_meta, _component_access_set, _world);
        P11::init_access(P11, _system_meta, _component_access_set, _world);
        P12::init_access(P12, _system_meta, _component_access_set, _world);
        P13::init_access(P13, _system_meta, _component_access_set, _world);
        P14::init_access(P14, _system_meta, _component_access_set, _world);
        P15::init_access(P15, _system_meta, _component_access_set, _world);
    }
    #[inline]
    fn apply((P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14,
            P15): &mut Self::State, system_meta: &SystemMeta,
        world: &mut World) {
        P0::apply(P0, system_meta, world);
        P1::apply(P1, system_meta, world);
        P2::apply(P2, system_meta, world);
        P3::apply(P3, system_meta, world);
        P4::apply(P4, system_meta, world);
        P5::apply(P5, system_meta, world);
        P6::apply(P6, system_meta, world);
        P7::apply(P7, system_meta, world);
        P8::apply(P8, system_meta, world);
        P9::apply(P9, system_meta, world);
        P10::apply(P10, system_meta, world);
        P11::apply(P11, system_meta, world);
        P12::apply(P12, system_meta, world);
        P13::apply(P13, system_meta, world);
        P14::apply(P14, system_meta, world);
        P15::apply(P15, system_meta, world);
    }
    #[inline]
    #[allow(unused_mut, reason =
    "The `world` parameter is unused for zero-length tuples; however, it must be mutable for other lengths of tuples.")]
    fn queue((P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14,
            P15): &mut Self::State, system_meta: &SystemMeta,
        mut world: DeferredWorld) {
        P0::queue(P0, system_meta, world.reborrow());
        P1::queue(P1, system_meta, world.reborrow());
        P2::queue(P2, system_meta, world.reborrow());
        P3::queue(P3, system_meta, world.reborrow());
        P4::queue(P4, system_meta, world.reborrow());
        P5::queue(P5, system_meta, world.reborrow());
        P6::queue(P6, system_meta, world.reborrow());
        P7::queue(P7, system_meta, world.reborrow());
        P8::queue(P8, system_meta, world.reborrow());
        P9::queue(P9, system_meta, world.reborrow());
        P10::queue(P10, system_meta, world.reborrow());
        P11::queue(P11, system_meta, world.reborrow());
        P12::queue(P12, system_meta, world.reborrow());
        P13::queue(P13, system_meta, world.reborrow());
        P14::queue(P14, system_meta, world.reborrow());
        P15::queue(P15, system_meta, world.reborrow());
    }
    #[inline]
    #[track_caller]
    unsafe fn get_param<'w,
        's>(state: &'s mut Self::State, system_meta: &SystemMeta,
        world: UnsafeWorldCell<'w>, change_tick: Tick)
        -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
        let (P0, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14,
                P15) = state;

        #[allow(unused_unsafe, reason =
        "Zero-length tuples won't have any params to validate.")]
        unsafe {

            #[allow(clippy :: unused_unit, reason =
            "Zero-length tuples won't have any params to get.")]
            Ok((P0::get_param(P0, system_meta, world, change_tick)?,
                    P1::get_param(P1, system_meta, world, change_tick)?,
                    P2::get_param(P2, system_meta, world, change_tick)?,
                    P3::get_param(P3, system_meta, world, change_tick)?,
                    P4::get_param(P4, system_meta, world, change_tick)?,
                    P5::get_param(P5, system_meta, world, change_tick)?,
                    P6::get_param(P6, system_meta, world, change_tick)?,
                    P7::get_param(P7, system_meta, world, change_tick)?,
                    P8::get_param(P8, system_meta, world, change_tick)?,
                    P9::get_param(P9, system_meta, world, change_tick)?,
                    P10::get_param(P10, system_meta, world, change_tick)?,
                    P11::get_param(P11, system_meta, world, change_tick)?,
                    P12::get_param(P12, system_meta, world, change_tick)?,
                    P13::get_param(P13, system_meta, world, change_tick)?,
                    P14::get_param(P14, system_meta, world, change_tick)?,
                    P15::get_param(P15, system_meta, world, change_tick)?))
        }
    }
}all_tuples!(
2036    #[doc(fake_variadic)]
2037    impl_system_param_tuple,
2038    0,
2039    16,
2040    P
2041);
2042
2043/// Contains type aliases for built-in [`SystemParam`]s with `'static` lifetimes.
2044/// This makes it more convenient to refer to these types in contexts where
2045/// explicit lifetime annotations are required.
2046///
2047/// Note that this is entirely safe and tracks lifetimes correctly.
2048/// This purely exists for convenience.
2049///
2050/// You can't instantiate a static `SystemParam`, you'll always end up with
2051/// `Res<'w, T>`, `ResMut<'w, T>` or `&'w T` bound to the lifetime of the provided
2052/// `&'w World`.
2053///
2054/// [`SystemParam`]: super::SystemParam
2055pub mod lifetimeless {
2056    /// A [`Query`](super::Query) with `'static` lifetimes.
2057    pub type SQuery<D, F = ()> = super::Query<'static, 'static, D, F>;
2058    /// A shorthand for writing `&'static T`.
2059    pub type Read<T> = &'static T;
2060    /// A shorthand for writing `&'static mut T`.
2061    pub type Write<T> = &'static mut T;
2062    /// A [`Res`](super::Res) with `'static` lifetimes.
2063    pub type SRes<T> = super::Res<'static, T>;
2064    /// A [`ResMut`](super::ResMut) with `'static` lifetimes.
2065    pub type SResMut<T> = super::ResMut<'static, T>;
2066    /// [`Commands`](crate::system::Commands) with `'static` lifetimes.
2067    pub type SCommands = crate::system::Commands<'static, 'static>;
2068}
2069
2070/// A helper for using system parameters in generic contexts
2071///
2072/// This type is a [`SystemParam`] adapter which always has
2073/// `Self::Item == Self` (ignoring lifetimes for brevity),
2074/// no matter the argument [`SystemParam`] (`P`) (other than
2075/// that `P` must be `'static`)
2076///
2077/// This makes it useful for having arbitrary [`SystemParam`] type arguments
2078/// to function systems, or for generic types using the [`derive@SystemParam`]
2079/// derive:
2080///
2081/// ```
2082/// # use bevy_ecs::prelude::*;
2083/// use bevy_ecs::system::{SystemParam, StaticSystemParam};
2084/// #[derive(SystemParam)]
2085/// struct GenericParam<'w,'s, T: SystemParam + 'static> {
2086///     field: StaticSystemParam<'w, 's, T>,
2087/// }
2088/// fn do_thing_generically<T: SystemParam + 'static>(t: StaticSystemParam<T>) {}
2089///
2090/// fn check_always_is_system<T: SystemParam + 'static>(){
2091///     bevy_ecs::system::assert_is_system(do_thing_generically::<T>);
2092/// }
2093/// ```
2094/// Note that in a real case you'd generally want
2095/// additional bounds on `P`, for your use of the parameter
2096/// to have a reason to be generic.
2097///
2098/// For example, using this would allow a type to be generic over
2099/// whether a resource is accessed mutably or not, with
2100/// impls being bounded on [`P: Deref<Target=MyType>`](Deref), and
2101/// [`P: DerefMut<Target=MyType>`](DerefMut) depending on whether the
2102/// method requires mutable access or not.
2103///
2104/// The method which doesn't use this type will not compile:
2105/// ```compile_fail
2106/// # use bevy_ecs::prelude::*;
2107/// # use bevy_ecs::system::{SystemParam, StaticSystemParam};
2108///
2109/// fn do_thing_generically<T: SystemParam + 'static>(t: T) {}
2110///
2111/// #[derive(SystemParam)]
2112/// struct GenericParam<'w, 's, T: SystemParam> {
2113///     field: T,
2114///     // Use the lifetimes in this type, or they will be unbound.
2115///     phantom: std::marker::PhantomData<&'w &'s ()>
2116/// }
2117/// # fn check_always_is_system<T: SystemParam + 'static>(){
2118/// #    bevy_ecs::system::assert_is_system(do_thing_generically::<T>);
2119/// # }
2120/// ```
2121pub struct StaticSystemParam<'w, 's, P: SystemParam>(SystemParamItem<'w, 's, P>);
2122
2123impl<'w, 's, P: SystemParam> Deref for StaticSystemParam<'w, 's, P> {
2124    type Target = SystemParamItem<'w, 's, P>;
2125
2126    fn deref(&self) -> &Self::Target {
2127        &self.0
2128    }
2129}
2130
2131impl<'w, 's, P: SystemParam> DerefMut for StaticSystemParam<'w, 's, P> {
2132    fn deref_mut(&mut self) -> &mut Self::Target {
2133        &mut self.0
2134    }
2135}
2136
2137impl<'w, 's, P: SystemParam> StaticSystemParam<'w, 's, P> {
2138    /// Get the value of the parameter
2139    pub fn into_inner(self) -> SystemParamItem<'w, 's, P> {
2140        self.0
2141    }
2142}
2143
2144// SAFETY: This doesn't add any more reads, and the delegated fetch confirms it
2145unsafe impl<'w, 's, P: ReadOnlySystemParam + 'static> ReadOnlySystemParam
2146    for StaticSystemParam<'w, 's, P>
2147{
2148}
2149
2150// SAFETY: all methods are just delegated to `P`'s `SystemParam` implementation
2151unsafe impl<P: SystemParam + 'static> SystemParam for StaticSystemParam<'_, '_, P> {
2152    type State = P::State;
2153    type Item<'world, 'state> = StaticSystemParam<'world, 'state, P>;
2154
2155    fn init_state(world: &mut World) -> Self::State {
2156        P::init_state(world)
2157    }
2158
2159    fn init_access(
2160        state: &Self::State,
2161        system_meta: &mut SystemMeta,
2162        component_access_set: &mut FilteredAccessSet,
2163        world: &mut World,
2164    ) {
2165        P::init_access(state, system_meta, component_access_set, world);
2166    }
2167
2168    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
2169        P::apply(state, system_meta, world);
2170    }
2171
2172    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
2173        P::queue(state, system_meta, world);
2174    }
2175
2176    #[inline]
2177    unsafe fn get_param<'world, 'state>(
2178        state: &'state mut Self::State,
2179        system_meta: &SystemMeta,
2180        world: UnsafeWorldCell<'world>,
2181        change_tick: Tick,
2182    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2183        // SAFETY: Defer to the safety of P::SystemParam
2184        unsafe { P::get_param(state, system_meta, world, change_tick) }.map(StaticSystemParam)
2185    }
2186}
2187
2188// SAFETY: No world access.
2189unsafe impl<T: ?Sized> SystemParam for PhantomData<T> {
2190    type State = ();
2191    type Item<'world, 'state> = Self;
2192
2193    fn init_state(_world: &mut World) -> Self::State {}
2194
2195    fn init_access(
2196        _state: &Self::State,
2197        _system_meta: &mut SystemMeta,
2198        _component_access_set: &mut FilteredAccessSet,
2199        _world: &mut World,
2200    ) {
2201    }
2202
2203    #[inline]
2204    unsafe fn get_param<'world, 'state>(
2205        _state: &'state mut Self::State,
2206        _system_meta: &SystemMeta,
2207        _world: UnsafeWorldCell<'world>,
2208        _change_tick: Tick,
2209    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2210        Ok(PhantomData)
2211    }
2212}
2213
2214// SAFETY: No world access.
2215unsafe impl<T: ?Sized> ReadOnlySystemParam for PhantomData<T> {}
2216
2217/// A [`SystemParam`] with a type that can be configured at runtime.
2218///
2219/// To be useful, this must be configured using a [`DynParamBuilder`](crate::system::DynParamBuilder) to build the system using a [`SystemParamBuilder`](crate::prelude::SystemParamBuilder).
2220///
2221/// # Examples
2222///
2223/// ```
2224/// # use bevy_ecs::{prelude::*, system::*};
2225/// #
2226/// # #[derive(Default, Resource)]
2227/// # struct A;
2228/// #
2229/// # #[derive(Default, Resource)]
2230/// # struct B;
2231/// #
2232/// # let mut world = World::new();
2233/// # world.init_resource::<A>();
2234/// # world.init_resource::<B>();
2235/// #
2236/// // If the inner parameter doesn't require any special building, use `ParamBuilder`.
2237/// // Either specify the type parameter on `DynParamBuilder::new()` ...
2238/// let system = (DynParamBuilder::new::<Res<A>>(ParamBuilder),)
2239///     .build_state(&mut world)
2240///     .build_system(expects_res_a);
2241/// # world.run_system_once(system);
2242///
2243/// // ... or use a factory method on `ParamBuilder` that returns a specific type.
2244/// let system = (DynParamBuilder::new(ParamBuilder::resource::<A>()),)
2245///     .build_state(&mut world)
2246///     .build_system(expects_res_a);
2247/// # world.run_system_once(system);
2248///
2249/// fn expects_res_a(mut param: DynSystemParam) {
2250///     // Use the `downcast` methods to retrieve the inner parameter.
2251///     // They will return `None` if the type does not match.
2252///     assert!(param.is::<Res<A>>());
2253///     assert!(!param.is::<Res<B>>());
2254///     assert!(param.downcast_mut::<Res<B>>().is_none());
2255///     let res = param.downcast_mut::<Res<A>>().unwrap();
2256///     // The type parameter can be left out if it can be determined from use.
2257///     let res: Res<A> = param.downcast().unwrap();
2258/// }
2259///
2260/// let system = (
2261///     // If the inner parameter also requires building,
2262///     // pass the appropriate `SystemParamBuilder`.
2263///     DynParamBuilder::new(LocalBuilder(10usize)),
2264///     // `DynSystemParam` is just an ordinary `SystemParam`,
2265///     // and can be combined with other parameters as usual!
2266///     ParamBuilder::query(),
2267/// )
2268///     .build_state(&mut world)
2269///     .build_system(|param: DynSystemParam, query: Query<()>| {
2270///         let local: Local<usize> = param.downcast::<Local<usize>>().unwrap();
2271///         assert_eq!(*local, 10);
2272///     });
2273/// # world.run_system_once(system);
2274/// ```
2275pub struct DynSystemParam<'w, 's> {
2276    /// A `ParamState<T>` wrapping the state for the underlying system param.
2277    state: &'s mut dyn Any,
2278    world: UnsafeWorldCell<'w>,
2279    system_meta: SystemMeta,
2280    change_tick: Tick,
2281}
2282
2283impl<'w, 's> DynSystemParam<'w, 's> {
2284    /// # Safety
2285    /// - `state` must be a `ParamState<T>` for some inner `T: SystemParam`.
2286    /// - The passed [`UnsafeWorldCell`] must have access to any world data registered
2287    ///   in [`init_state`](SystemParam::init_state) for the inner system param.
2288    /// - `world` must be the same `World` that was used to initialize
2289    ///   [`state`](SystemParam::init_state) for the inner system param.
2290    unsafe fn new(
2291        state: &'s mut dyn Any,
2292        world: UnsafeWorldCell<'w>,
2293        system_meta: SystemMeta,
2294        change_tick: Tick,
2295    ) -> Self {
2296        Self {
2297            state,
2298            world,
2299            system_meta,
2300            change_tick,
2301        }
2302    }
2303
2304    /// Returns `true` if the inner system param is the same as `T`.
2305    pub fn is<T: SystemParam>(&self) -> bool
2306    // See downcast() function for an explanation of the where clause
2307    where
2308        T::Item<'static, 'static>: SystemParam<Item<'w, 's> = T> + 'static,
2309    {
2310        self.state.is::<ParamState<T::Item<'static, 'static>>>()
2311    }
2312
2313    /// Returns the inner system param if it is the correct type.
2314    /// This consumes the dyn param, so the returned param can have its original world and state lifetimes.
2315    pub fn downcast<T: SystemParam>(self) -> Option<T>
2316    // See downcast() function for an explanation of the where clause
2317    where
2318        T::Item<'static, 'static>: SystemParam<Item<'w, 's> = T> + 'static,
2319    {
2320        // SAFETY:
2321        // - `DynSystemParam::new()` ensures `state` is a `ParamState<T>`, that the world matches,
2322        //   and that it has access required by the inner system param.
2323        // - This consumes the `DynSystemParam`, so it is the only use of `world` with this access and it is available for `'w`.
2324        unsafe { downcast::<T>(self.state, &self.system_meta, self.world, self.change_tick) }
2325    }
2326
2327    /// Returns the inner system parameter if it is the correct type.
2328    /// This borrows the dyn param, so the returned param is only valid for the duration of that borrow.
2329    pub fn downcast_mut<'a, T: SystemParam>(&'a mut self) -> Option<T>
2330    // See downcast() function for an explanation of the where clause
2331    where
2332        T::Item<'static, 'static>: SystemParam<Item<'a, 'a> = T> + 'static,
2333    {
2334        // SAFETY:
2335        // - `DynSystemParam::new()` ensures `state` is a `ParamState<T>`, that the world matches,
2336        //   and that it has access required by the inner system param.
2337        // - This exclusively borrows the `DynSystemParam` for `'_`, so it is the only use of `world` with this access for `'_`.
2338        unsafe { downcast::<T>(self.state, &self.system_meta, self.world, self.change_tick) }
2339    }
2340
2341    /// Returns the inner system parameter if it is the correct type.
2342    /// This borrows the dyn param, so the returned param is only valid for the duration of that borrow,
2343    /// but since it only performs read access it can keep the original world lifetime.
2344    /// This can be useful with methods like [`Query::iter_inner()`] or [`Res::into_inner()`]
2345    /// to obtain references with the original world lifetime.
2346    pub fn downcast_mut_inner<'a, T: ReadOnlySystemParam>(&'a mut self) -> Option<T>
2347    // See downcast() function for an explanation of the where clause
2348    where
2349        T::Item<'static, 'static>: SystemParam<Item<'w, 'a> = T> + 'static,
2350    {
2351        // SAFETY:
2352        // - `DynSystemParam::new()` ensures `state` is a `ParamState<T>`, that the world matches,
2353        //   and that it has access required by the inner system param.
2354        // - The inner system param only performs read access, so it's safe to copy that access for the full `'w` lifetime.
2355        unsafe { downcast::<T>(self.state, &self.system_meta, self.world, self.change_tick) }
2356    }
2357}
2358
2359/// # Safety
2360/// - `state` must be a `ParamState<T>` for some inner `T: SystemParam`.
2361/// - The passed [`UnsafeWorldCell`] must have access to any world data registered
2362///   in [`init_state`](SystemParam::init_state) for the inner system param.
2363/// - `world` must be the same `World` that was used to initialize
2364///   [`state`](SystemParam::init_state) for the inner system param.
2365unsafe fn downcast<'w, 's, T: SystemParam>(
2366    state: &'s mut dyn Any,
2367    system_meta: &SystemMeta,
2368    world: UnsafeWorldCell<'w>,
2369    change_tick: Tick,
2370) -> Option<T>
2371// We need a 'static version of the SystemParam to use with `Any::downcast_mut()`,
2372// and we need a <'w, 's> version to actually return.
2373// The type parameter T must be the one we return in order to get type inference from the return value.
2374// So we use `T::Item<'static, 'static>` as the 'static version, and require that it be 'static.
2375// That means the return value will be T::Item<'static, 'static>::Item<'w, 's>,
2376// so we constrain that to be equal to T.
2377// Every actual `SystemParam` implementation has `T::Item == T` up to lifetimes,
2378// so they should all work with this constraint.
2379where
2380    T::Item<'static, 'static>: SystemParam<Item<'w, 's> = T> + 'static,
2381{
2382    state
2383        .downcast_mut::<ParamState<T::Item<'static, 'static>>>()
2384        .and_then(|state| {
2385            // SAFETY:
2386            // - The caller ensures the world has access for the underlying system param,
2387            //   and since the downcast succeeded, the underlying system param is T.
2388            // - The caller ensures the `world` matches.
2389            unsafe { T::Item::get_param(&mut state.0, system_meta, world, change_tick) }.ok()
2390        })
2391}
2392
2393/// The [`SystemParam::State`] for a [`DynSystemParam`].
2394pub struct DynSystemParamState(Box<dyn DynParamState>);
2395
2396impl DynSystemParamState {
2397    pub(crate) fn new<T: SystemParam + 'static>(state: T::State) -> Self {
2398        Self(Box::new(ParamState::<T>(state)))
2399    }
2400}
2401
2402/// Allows a [`SystemParam::State`] to be used as a trait object for implementing [`DynSystemParam`].
2403trait DynParamState: Sync + Send + Any {
2404    /// Applies any deferred mutations stored in this [`SystemParam`]'s state.
2405    /// This is used to apply [`Commands`] during [`ApplyDeferred`](crate::prelude::ApplyDeferred).
2406    ///
2407    /// [`Commands`]: crate::prelude::Commands
2408    fn apply(&mut self, system_meta: &SystemMeta, world: &mut World);
2409
2410    /// Queues any deferred mutations to be applied at the next [`ApplyDeferred`](crate::prelude::ApplyDeferred).
2411    fn queue(&mut self, system_meta: &SystemMeta, world: DeferredWorld);
2412
2413    /// Registers any [`World`] access used by this [`SystemParam`]
2414    fn init_access(
2415        &self,
2416        system_meta: &mut SystemMeta,
2417        component_access_set: &mut FilteredAccessSet,
2418        world: &mut World,
2419    );
2420
2421    /// Validates the inner parameter by calling [`SystemParam::get_param`] and discarding the value.
2422    ///
2423    /// # Safety
2424    /// Refer to [`SystemParam::get_param`].
2425    unsafe fn validate(
2426        &mut self,
2427        system_meta: &SystemMeta,
2428        world: UnsafeWorldCell,
2429        change_tick: Tick,
2430    ) -> Result<(), SystemParamValidationError>;
2431}
2432
2433/// A wrapper around a [`SystemParam::State`] that can be used as a trait object in a [`DynSystemParam`].
2434struct ParamState<T: SystemParam>(T::State);
2435
2436impl<T: SystemParam + 'static> DynParamState for ParamState<T> {
2437    fn apply(&mut self, system_meta: &SystemMeta, world: &mut World) {
2438        T::apply(&mut self.0, system_meta, world);
2439    }
2440
2441    fn queue(&mut self, system_meta: &SystemMeta, world: DeferredWorld) {
2442        T::queue(&mut self.0, system_meta, world);
2443    }
2444
2445    fn init_access(
2446        &self,
2447        system_meta: &mut SystemMeta,
2448        component_access_set: &mut FilteredAccessSet,
2449        world: &mut World,
2450    ) {
2451        T::init_access(&self.0, system_meta, component_access_set, world);
2452    }
2453
2454    unsafe fn validate(
2455        &mut self,
2456        system_meta: &SystemMeta,
2457        world: UnsafeWorldCell,
2458        change_tick: Tick,
2459    ) -> Result<(), SystemParamValidationError> {
2460        // SAFETY: Upheld by caller.
2461        unsafe { T::get_param(&mut self.0, system_meta, world, change_tick) }.map(drop)
2462    }
2463}
2464
2465// SAFETY: Delegates to the wrapped parameter, which ensures the safety requirements are met
2466unsafe impl SystemParam for DynSystemParam<'_, '_> {
2467    type State = DynSystemParamState;
2468
2469    type Item<'world, 'state> = DynSystemParam<'world, 'state>;
2470
2471    fn init_state(_world: &mut World) -> Self::State {
2472        DynSystemParamState::new::<()>(())
2473    }
2474
2475    fn init_access(
2476        state: &Self::State,
2477        system_meta: &mut SystemMeta,
2478        component_access_set: &mut FilteredAccessSet,
2479        world: &mut World,
2480    ) {
2481        state
2482            .0
2483            .init_access(system_meta, component_access_set, world);
2484    }
2485
2486    #[inline]
2487    unsafe fn get_param<'world, 'state>(
2488        state: &'state mut Self::State,
2489        system_meta: &SystemMeta,
2490        world: UnsafeWorldCell<'world>,
2491        change_tick: Tick,
2492    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2493        // Validate the inner parameter eagerly so that systems using DynSystemParam
2494        // are correctly skipped by the executor when the inner param is unavailable.
2495        // SAFETY: Upheld by caller.
2496        unsafe { state.0.validate(system_meta, world, change_tick) }?;
2497        // SAFETY:
2498        // - `state.0` is a boxed `ParamState<T>`.
2499        // - `init_access` calls `DynParamState::init_access`, which calls `init_access` on the inner parameter,
2500        //   so the caller ensures the world has the necessary access.
2501        // - The caller ensures that the provided world is the same and has the required access.
2502        Ok(unsafe {
2503            DynSystemParam::new(state.0.as_mut(), world, system_meta.clone(), change_tick)
2504        })
2505    }
2506
2507    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
2508        state.0.apply(system_meta, world);
2509    }
2510
2511    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
2512        state.0.queue(system_meta, world);
2513    }
2514}
2515
2516// SAFETY: Resource ComponentId access is applied to the access. If this FilteredResources
2517// conflicts with any prior access, a panic will occur.
2518unsafe impl SystemParam for FilteredResources<'_, '_> {
2519    type State = Access;
2520
2521    type Item<'world, 'state> = FilteredResources<'world, 'state>;
2522
2523    fn init_state(_world: &mut World) -> Self::State {
2524        Access::new()
2525    }
2526
2527    fn init_access(
2528        access: &Self::State,
2529        system_meta: &mut SystemMeta,
2530        component_access_set: &mut FilteredAccessSet,
2531        world: &mut World,
2532    ) {
2533        let combined_access = component_access_set.combined_access();
2534        let conflicts = combined_access.get_conflicts(access);
2535        if !conflicts.is_empty() {
2536            let accesses = conflicts.format_conflict_list(world.into());
2537            let system_name = &system_meta.name;
2538            {
    ::core::panicking::panic_fmt(format_args!("error[B0002]: FilteredResources in system {0} accesses resources(s){1} in a way that conflicts with a previous system parameter. Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002",
            system_name, accesses));
};panic!("error[B0002]: FilteredResources in system {system_name} accesses resources(s){accesses} in a way that conflicts with a previous system parameter. Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002");
2539        }
2540
2541        let mut filter = FilteredAccess::matches_everything();
2542        filter.access_mut().extend(access);
2543        filter.and_with(IS_RESOURCE);
2544        component_access_set.add(filter);
2545    }
2546
2547    unsafe fn get_param<'world, 'state>(
2548        state: &'state mut Self::State,
2549        system_meta: &SystemMeta,
2550        world: UnsafeWorldCell<'world>,
2551        change_tick: Tick,
2552    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2553        // SAFETY: The caller ensures that `world` has access to anything registered in `init_access`,
2554        // and we registered all resource access in `state``.
2555        Ok(unsafe { FilteredResources::new(world, state, system_meta.last_run, change_tick) })
2556    }
2557}
2558
2559// SAFETY: FilteredResources only reads resources.
2560unsafe impl ReadOnlySystemParam for FilteredResources<'_, '_> {}
2561
2562// SAFETY: Resource ComponentId access is applied to the access. If this FilteredResourcesMut
2563// conflicts with any prior access, a panic will occur.
2564unsafe impl SystemParam for FilteredResourcesMut<'_, '_> {
2565    type State = Access;
2566
2567    type Item<'world, 'state> = FilteredResourcesMut<'world, 'state>;
2568
2569    fn init_state(_world: &mut World) -> Self::State {
2570        Access::new()
2571    }
2572
2573    fn init_access(
2574        access: &Self::State,
2575        system_meta: &mut SystemMeta,
2576        component_access_set: &mut FilteredAccessSet,
2577        world: &mut World,
2578    ) {
2579        let combined_access = component_access_set.combined_access();
2580        let conflicts = combined_access.get_conflicts(access);
2581        if !conflicts.is_empty() {
2582            let accesses = conflicts.format_conflict_list(world.into());
2583            let system_name = &system_meta.name;
2584            {
    ::core::panicking::panic_fmt(format_args!("error[B0002]: FilteredResourcesMut in system {0} accesses resources(s){1} in a way that conflicts with a previous system parameter. Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002",
            system_name, accesses));
};panic!("error[B0002]: FilteredResourcesMut in system {system_name} accesses resources(s){accesses} in a way that conflicts with a previous system parameter. Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002");
2585        }
2586
2587        let mut filter = FilteredAccess::matches_everything();
2588        filter.access_mut().extend(access);
2589        filter.and_with(IS_RESOURCE);
2590        component_access_set.add(filter);
2591    }
2592
2593    unsafe fn get_param<'world, 'state>(
2594        state: &'state mut Self::State,
2595        system_meta: &SystemMeta,
2596        world: UnsafeWorldCell<'world>,
2597        change_tick: Tick,
2598    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2599        // SAFETY: The caller ensures that `world` has access to anything registered in `init_access`,
2600        // and we registered all resource access in `state``.
2601        Ok(unsafe { FilteredResourcesMut::new(world, state, system_meta.last_run, change_tick) })
2602    }
2603}
2604
2605/// An error that occurs when a system parameter is not valid,
2606/// used by system executors to determine what to do with a system.
2607///
2608/// Returned as an error from [`SystemParam::get_param`],
2609/// and handled using the unified error handling mechanisms defined in [`bevy_ecs::error`].
2610#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SystemParamValidationError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f,
            "SystemParamValidationError", "skipped", &self.skipped, "message",
            &self.message, "param", &self.param, "field", &&self.field)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for SystemParamValidationError {
    #[inline]
    fn eq(&self, other: &SystemParamValidationError) -> bool {
        self.skipped == other.skipped && self.message == other.message &&
                self.param == other.param && self.field == other.field
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for SystemParamValidationError {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<bool>;
        let _: ::core::cmp::AssertParamIsEq<Cow<'static, str>>;
        let _: ::core::cmp::AssertParamIsEq<DebugName>;
        let _: ::core::cmp::AssertParamIsEq<Cow<'static, str>>;
    }
}Eq, #[automatically_derived]
impl ::core::clone::Clone for SystemParamValidationError {
    #[inline]
    fn clone(&self) -> SystemParamValidationError {
        SystemParamValidationError {
            skipped: ::core::clone::Clone::clone(&self.skipped),
            message: ::core::clone::Clone::clone(&self.message),
            param: ::core::clone::Clone::clone(&self.param),
            field: ::core::clone::Clone::clone(&self.field),
        }
    }
}Clone, #[allow(unused_qualifications)]
#[automatically_derived]
impl ::thiserror::__private18::Error for SystemParamValidationError { }Error)]
2611pub struct SystemParamValidationError {
2612    /// Whether the system should be skipped.
2613    ///
2614    /// If `false`, the error should be handled.
2615    /// By default, this will result in a panic. See [`error`](`crate::error`) for more information.
2616    ///
2617    /// This is the default behavior, and is suitable for system params that should *always* be valid,
2618    /// either because sensible fallback behavior exists (like [`Query`]) or because
2619    /// failures in validation should be considered a bug in the user's logic that must be immediately addressed (like [`Res`]).
2620    ///
2621    /// If `true`, the system should be skipped.
2622    /// This is set by wrapping the system param in [`If`],
2623    /// and indicates that the system is intended to only operate in certain application states.
2624    pub skipped: bool,
2625
2626    /// A message describing the validation error.
2627    pub message: Cow<'static, str>,
2628
2629    /// A string identifying the invalid parameter.
2630    /// This is usually the type name of the parameter.
2631    pub param: DebugName,
2632
2633    /// A string identifying the field within a parameter using `#[derive(SystemParam)]`.
2634    /// This will be an empty string for other parameters.
2635    ///
2636    /// This will be printed after `param` in the `Display` impl, and should include a `::` prefix if non-empty.
2637    pub field: Cow<'static, str>,
2638}
2639
2640impl SystemParamValidationError {
2641    /// Constructs a `SystemParamValidationError` that skips the system.
2642    /// The parameter name is initialized to the type name of `T`, so a `SystemParam` should usually pass `Self`.
2643    pub fn skipped<T>(message: impl Into<Cow<'static, str>>) -> Self {
2644        Self::new::<T>(true, message, Cow::Borrowed(""))
2645    }
2646
2647    /// Constructs a `SystemParamValidationError` for an invalid parameter that should be treated as an error.
2648    /// The parameter name is initialized to the type name of `T`, so a `SystemParam` should usually pass `Self`.
2649    pub fn invalid<T>(message: impl Into<Cow<'static, str>>) -> Self {
2650        Self::new::<T>(false, message, Cow::Borrowed(""))
2651    }
2652
2653    /// Constructs a `SystemParamValidationError` for an invalid parameter.
2654    /// The parameter name is initialized to the type name of `T`, so a `SystemParam` should usually pass `Self`.
2655    pub fn new<T>(
2656        skipped: bool,
2657        message: impl Into<Cow<'static, str>>,
2658        field: impl Into<Cow<'static, str>>,
2659    ) -> Self {
2660        Self {
2661            skipped,
2662            message: message.into(),
2663            param: DebugName::type_name::<T>(),
2664            field: field.into(),
2665        }
2666    }
2667
2668    pub(crate) const EMPTY: Self = Self {
2669        skipped: false,
2670        message: Cow::Borrowed(""),
2671        param: DebugName::borrowed(""),
2672        field: Cow::Borrowed(""),
2673    };
2674}
2675
2676impl Display for SystemParamValidationError {
2677    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
2678        fmt.write_fmt(format_args!("Parameter `{0}{1}` failed validation: {2}",
        self.param.shortname(), self.field, self.message))write!(
2679            fmt,
2680            "Parameter `{}{}` failed validation: {}",
2681            self.param.shortname(),
2682            self.field,
2683            self.message
2684        )?;
2685        if !self.skipped {
2686            fmt.write_fmt(format_args!("\nIf this is an expected state, wrap the parameter in `Option<T>` and handle `None` when it happens, or wrap the parameter in `If<T>` to skip the system when it happens."))write!(fmt, "\nIf this is an expected state, wrap the parameter in `Option<T>` and handle `None` when it happens, or wrap the parameter in `If<T>` to skip the system when it happens.")?;
2687        }
2688        Ok(())
2689    }
2690}
2691
2692#[cfg(test)]
2693mod tests {
2694    use super::*;
2695    use crate::query::Without;
2696    use crate::resource::IsResource;
2697    use crate::system::assert_is_system;
2698    use crate::world::EntityMut;
2699    use core::cell::RefCell;
2700
2701    #[test]
2702    #[should_panic]
2703    fn non_send_alias() {
2704        #[derive(Resource)]
2705        struct A(usize);
2706        fn my_system(mut res0: NonSendMut<A>, mut res1: NonSendMut<A>) {
2707            res0.0 += 1;
2708            res1.0 += 1;
2709        }
2710        let mut world = World::new();
2711        world.insert_non_send(A(42));
2712        let mut schedule = crate::schedule::Schedule::default();
2713        schedule.add_systems(my_system);
2714        schedule.run(&mut world);
2715    }
2716
2717    #[test]
2718    #[should_panic]
2719    fn non_send_and_entities() {
2720        #[derive(Resource)]
2721        struct A(usize);
2722        fn my_system(mut ns: NonSendMut<A>, _: Query<EntityMut>) {
2723            ns.0 += 1;
2724        }
2725        assert_is_system(my_system);
2726    }
2727
2728    #[test]
2729    #[should_panic]
2730    fn res_and_entities() {
2731        #[derive(Resource)]
2732        struct A(usize);
2733        fn my_system(mut res: ResMut<A>, _: Query<EntityMut>) {
2734            res.0 += 1;
2735        }
2736        assert_is_system(my_system);
2737    }
2738
2739    #[test]
2740    fn res_and_entities_filtered() {
2741        #[derive(Resource)]
2742        struct A(usize);
2743        fn res_system(mut res: ResMut<A>, _: Query<EntityMut, Without<IsResource>>) {
2744            res.0 += 1;
2745        }
2746        assert_is_system(res_system);
2747
2748        fn non_send_system(mut ns: NonSendMut<A>, _: Query<EntityMut, Without<A>>) {
2749            ns.0 += 1;
2750        }
2751
2752        assert_is_system(non_send_system);
2753    }
2754
2755    // Compile test for https://github.com/bevyengine/bevy/pull/2838.
2756    #[test]
2757    fn system_param_generic_bounds() {
2758        #[derive(SystemParam)]
2759        pub struct SpecialQuery<
2760            'w,
2761            's,
2762            D: QueryData + Send + Sync + 'static,
2763            F: QueryFilter + Send + Sync + 'static = (),
2764        > {
2765            _query: Query<'w, 's, D, F>,
2766        }
2767
2768        fn my_system(_: SpecialQuery<(), ()>) {}
2769        assert_is_system(my_system);
2770    }
2771
2772    // Compile tests for https://github.com/bevyengine/bevy/pull/6694.
2773    #[test]
2774    fn system_param_flexibility() {
2775        #[derive(SystemParam)]
2776        pub struct SpecialRes<'w, T: Resource> {
2777            _res: Res<'w, T>,
2778        }
2779
2780        #[derive(SystemParam)]
2781        pub struct SpecialLocal<'s, T: FromWorld + Send + 'static> {
2782            _local: Local<'s, T>,
2783        }
2784
2785        #[derive(Resource)]
2786        struct R;
2787
2788        fn my_system(_: SpecialRes<R>, _: SpecialLocal<u32>) {}
2789        assert_is_system(my_system);
2790    }
2791
2792    #[derive(Resource)]
2793    pub struct R<const I: usize>;
2794
2795    // Compile test for https://github.com/bevyengine/bevy/pull/7001.
2796    #[test]
2797    fn system_param_const_generics() {
2798        #[expect(
2799            dead_code,
2800            reason = "This struct is used to ensure that const generics are supported as a SystemParam; thus, the inner value never needs to be read."
2801        )]
2802        #[derive(SystemParam)]
2803        pub struct ConstGenericParam<'w, const I: usize>(Res<'w, R<I>>);
2804
2805        fn my_system(_: ConstGenericParam<0>, _: ConstGenericParam<1000>) {}
2806        assert_is_system(my_system);
2807    }
2808
2809    // Compile test for https://github.com/bevyengine/bevy/pull/6867.
2810    #[test]
2811    fn system_param_field_limit() {
2812        #[derive(SystemParam)]
2813        pub struct LongParam<'w> {
2814            // Each field should be a distinct type so there will
2815            // be an error if the derive messes up the field order.
2816            _r0: Res<'w, R<0>>,
2817            _r1: Res<'w, R<1>>,
2818            _r2: Res<'w, R<2>>,
2819            _r3: Res<'w, R<3>>,
2820            _r4: Res<'w, R<4>>,
2821            _r5: Res<'w, R<5>>,
2822            _r6: Res<'w, R<6>>,
2823            _r7: Res<'w, R<7>>,
2824            _r8: Res<'w, R<8>>,
2825            _r9: Res<'w, R<9>>,
2826            _r10: Res<'w, R<10>>,
2827            _r11: Res<'w, R<11>>,
2828            _r12: Res<'w, R<12>>,
2829            _r13: Res<'w, R<13>>,
2830            _r14: Res<'w, R<14>>,
2831            _r15: Res<'w, R<15>>,
2832            _r16: Res<'w, R<16>>,
2833        }
2834
2835        fn long_system(_: LongParam) {}
2836        assert_is_system(long_system);
2837    }
2838
2839    // Compile test for https://github.com/bevyengine/bevy/pull/6919.
2840    // Regression test for https://github.com/bevyengine/bevy/issues/7447.
2841    #[test]
2842    fn system_param_phantom_data() {
2843        #[derive(SystemParam)]
2844        struct PhantomParam<'w, T: Resource, Marker: 'static> {
2845            _foo: Res<'w, T>,
2846            marker: PhantomData<&'w Marker>,
2847        }
2848
2849        fn my_system(_: PhantomParam<R<0>, ()>) {}
2850        assert_is_system(my_system);
2851    }
2852
2853    // Compile tests for https://github.com/bevyengine/bevy/pull/6957.
2854    #[test]
2855    fn system_param_struct_variants() {
2856        #[derive(SystemParam)]
2857        pub struct UnitParam;
2858
2859        #[expect(
2860            dead_code,
2861            reason = "This struct is used to ensure that tuple structs are supported as a SystemParam; thus, the inner values never need to be read."
2862        )]
2863        #[derive(SystemParam)]
2864        pub struct TupleParam<'w, 's, R: Resource, L: FromWorld + Send + 'static>(
2865            Res<'w, R>,
2866            Local<'s, L>,
2867        );
2868
2869        fn my_system(_: UnitParam, _: TupleParam<R<0>, u32>) {}
2870        assert_is_system(my_system);
2871    }
2872
2873    // Regression test for https://github.com/bevyengine/bevy/issues/4200.
2874    #[test]
2875    fn system_param_private_fields() {
2876        #[derive(Resource)]
2877        struct PrivateResource;
2878
2879        #[expect(
2880            dead_code,
2881            reason = "This struct is used to ensure that SystemParam's derive can't leak private fields; thus, the inner values never need to be read."
2882        )]
2883        #[derive(SystemParam)]
2884        pub struct EncapsulatedParam<'w>(Res<'w, PrivateResource>);
2885
2886        fn my_system(_: EncapsulatedParam) {}
2887        assert_is_system(my_system);
2888    }
2889
2890    // Regression test for https://github.com/bevyengine/bevy/issues/7103.
2891    #[test]
2892    fn system_param_where_clause() {
2893        #[derive(SystemParam)]
2894        pub struct WhereParam<'w, 's, D>
2895        where
2896            D: 'static + QueryData,
2897        {
2898            _q: Query<'w, 's, D, ()>,
2899        }
2900
2901        fn my_system(_: WhereParam<()>) {}
2902        assert_is_system(my_system);
2903    }
2904
2905    // Regression test for https://github.com/bevyengine/bevy/issues/1727.
2906    #[test]
2907    fn system_param_name_collision() {
2908        #[derive(Resource)]
2909        pub struct FetchState;
2910
2911        #[derive(SystemParam)]
2912        pub struct Collide<'w> {
2913            _x: Res<'w, FetchState>,
2914        }
2915
2916        fn my_system(_: Collide) {}
2917        assert_is_system(my_system);
2918    }
2919
2920    // Regression test for https://github.com/bevyengine/bevy/issues/8192.
2921    #[test]
2922    fn system_param_invariant_lifetime() {
2923        #[derive(SystemParam)]
2924        pub struct InvariantParam<'w, 's> {
2925            _set: ParamSet<'w, 's, (Query<'w, 's, ()>,)>,
2926        }
2927
2928        fn my_system(_: InvariantParam) {}
2929        assert_is_system(my_system);
2930    }
2931
2932    // Compile test for https://github.com/bevyengine/bevy/pull/9589.
2933    #[test]
2934    fn non_sync_local() {
2935        fn non_sync_system(cell: Local<RefCell<u8>>) {
2936            assert_eq!(*cell.borrow(), 0);
2937        }
2938
2939        let mut world = World::new();
2940        let mut schedule = crate::schedule::Schedule::default();
2941        schedule.add_systems(non_sync_system);
2942        schedule.run(&mut world);
2943    }
2944
2945    // Regression test for https://github.com/bevyengine/bevy/issues/10207.
2946    #[test]
2947    fn param_set_non_send_first() {
2948        fn non_send_param_set(mut p: ParamSet<(NonSend<*mut u8>, ())>) {
2949            let _ = p.p0();
2950            p.p1();
2951        }
2952
2953        let mut world = World::new();
2954        world.insert_non_send(core::ptr::null_mut::<u8>());
2955        let mut schedule = crate::schedule::Schedule::default();
2956        schedule.add_systems((non_send_param_set, non_send_param_set, non_send_param_set));
2957        schedule.run(&mut world);
2958    }
2959
2960    // Regression test for https://github.com/bevyengine/bevy/issues/10207.
2961    #[test]
2962    fn param_set_non_send_second() {
2963        fn non_send_param_set(mut p: ParamSet<((), NonSendMut<*mut u8>)>) {
2964            p.p0();
2965            let _ = p.p1();
2966        }
2967
2968        let mut world = World::new();
2969        world.insert_non_send(core::ptr::null_mut::<u8>());
2970        let mut schedule = crate::schedule::Schedule::default();
2971        schedule.add_systems((non_send_param_set, non_send_param_set, non_send_param_set));
2972        schedule.run(&mut world);
2973    }
2974
2975    fn _dyn_system_param_type_inference(mut p: DynSystemParam) {
2976        // Make sure the downcast() methods are able to infer their type parameters from the use of the return type.
2977        // This is just a compilation test, so there is nothing to run.
2978        let _query: Query<()> = p.downcast_mut().unwrap();
2979        let _query: Query<()> = p.downcast_mut_inner().unwrap();
2980        let _query: Query<()> = p.downcast().unwrap();
2981    }
2982
2983    #[test]
2984    #[should_panic]
2985    fn missing_resource_error() {
2986        #[derive(Resource)]
2987        pub struct MissingResource;
2988
2989        let mut schedule = crate::schedule::Schedule::default();
2990        schedule.add_systems(res_system);
2991        let mut world = World::new();
2992        schedule.run(&mut world);
2993
2994        fn res_system(_: Res<MissingResource>) {}
2995    }
2996
2997    #[test]
2998    #[should_panic]
2999    fn missing_message_error() {
3000        use crate::prelude::{Message, MessageReader};
3001
3002        #[derive(Message)]
3003        pub struct MissingEvent;
3004
3005        let mut schedule = crate::schedule::Schedule::default();
3006        schedule.add_systems(message_system);
3007        let mut world = World::new();
3008        schedule.run(&mut world);
3009
3010        fn message_system(_: MessageReader<MissingEvent>) {}
3011    }
3012}