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, IterQueryData, QueryData, QueryFilter, QuerySingleError,
15        QueryState, ReadOnlyQueryData,
16    },
17    resource::{Resource, ResourceEntities, IS_RESOURCE},
18    system::{Query, Single, SystemAccess, SystemMeta, SystemState},
19    world::{unsafe_world_cell::UnsafeWorldCell, DeferredWorld, FromWorld, World},
20};
21
22#[expect(deprecated, reason = "`FilteredResources` will be removed.")]
23use crate::world::{FilteredResources, FilteredResourcesMut};
24
25use alloc::{borrow::Cow, boxed::Box, vec::Vec};
26pub use bevy_ecs_macros::SystemParam;
27use bevy_platform::cell::SyncCell;
28use bevy_ptr::UnsafeCellDeref;
29use bevy_utils::prelude::DebugName;
30use core::{
31    any::Any,
32    fmt::{Debug, Display},
33    marker::PhantomData,
34    ops::{Deref, DerefMut},
35};
36use smallvec::SmallVec;
37use thiserror::Error;
38
39use super::Populated;
40use variadics_please::{all_tuples, all_tuples_enumerated};
41
42/// A parameter that can be used in a [`System`](super::System).
43///
44/// # Derive
45///
46/// This trait can be derived with the [`derive@super::SystemParam`] macro.
47/// This macro only works if each field on the derived struct implements [`SystemParam`].
48/// Note: There are additional requirements on the field types.
49/// See the *Generic `SystemParam`s* section for details and workarounds of the probable
50/// cause if this derive causes an error to be emitted.
51///
52/// Derived `SystemParam` structs may have two lifetimes: `'w` for data stored in the [`World`],
53/// and `'s` for data stored in the parameter's state.
54///
55/// The following list shows the most common [`SystemParam`]s and which lifetime they require
56///
57/// ```
58/// # use bevy_ecs::prelude::*;
59/// # #[derive(Component)]
60/// # struct SomeComponent;
61/// # #[derive(Resource)]
62/// # struct SomeResource;
63/// # #[derive(Message)]
64/// # struct SomeMessage;
65/// # #[derive(Resource)]
66/// # struct SomeOtherResource;
67/// # use bevy_ecs::system::SystemParam;
68/// # #[derive(SystemParam)]
69/// # struct ParamsExample<'w, 's> {
70/// #    query:
71/// Query<'w, 's, Entity>,
72/// #    query2:
73/// Query<'w, 's, &'static SomeComponent>,
74/// #    res:
75/// Res<'w, SomeResource>,
76/// #    res_mut:
77/// ResMut<'w, SomeOtherResource>,
78/// #    local:
79/// Local<'s, u8>,
80/// #    commands:
81/// Commands<'w, 's>,
82/// #    message_reader:
83/// MessageReader<'w, 's, SomeMessage>,
84/// #    message_writer:
85/// MessageWriter<'w, SomeMessage>
86/// # }
87/// ```
88/// ## `PhantomData`
89///
90/// [`PhantomData`] is a special type of `SystemParam` that does nothing.
91/// This is useful for constraining generic types or lifetimes.
92///
93/// # Example
94///
95/// ```
96/// # use bevy_ecs::prelude::*;
97/// # #[derive(Resource)]
98/// # struct SomeResource;
99/// use std::marker::PhantomData;
100/// use bevy_ecs::system::SystemParam;
101///
102/// #[derive(SystemParam)]
103/// struct MyParam<'w, Marker: 'static> {
104///     foo: Res<'w, SomeResource>,
105///     marker: PhantomData<Marker>,
106/// }
107///
108/// fn my_system<T: 'static>(param: MyParam<T>) {
109///     // Access the resource through `param.foo`
110/// }
111///
112/// # bevy_ecs::system::assert_is_system(my_system::<()>);
113/// ```
114///
115/// # Generic `SystemParam`s
116///
117/// When using the derive macro, you may see an error in the form of:
118///
119/// ```text
120/// expected ... [ParamType]
121/// found associated type `<[ParamType] as SystemParam>::Item<'_, '_>`
122/// ```
123/// where `[ParamType]` is the type of one of your fields.
124/// To solve this error, you can wrap the field of type `[ParamType]` with [`StaticSystemParam`]
125/// (i.e. `StaticSystemParam<[ParamType]>`).
126///
127/// ## Details
128///
129/// The derive macro requires that the [`SystemParam`] implementation of
130/// each field `F`'s [`Item`](`SystemParam::Item`)'s is itself `F`
131/// (ignoring lifetimes for simplicity).
132/// This assumption is due to type inference reasons, so that the derived [`SystemParam`] can be
133/// used as an argument to a function system.
134/// If the compiler cannot validate this property for `[ParamType]`, it will error in the form shown above.
135///
136/// This will most commonly occur when working with `SystemParam`s generically, as the requirement
137/// has not been proven to the compiler.
138///
139/// ## Custom Validation Messages
140///
141/// When using the derive macro, any [`SystemParamValidationError`]s will be propagated from the sub-parameters.
142/// If you want to override the error message, add a `#[system_param(validation_message = "New message")]` attribute to the parameter.
143///
144/// ```
145/// # use bevy_ecs::prelude::*;
146/// # #[derive(Resource)]
147/// # struct SomeResource;
148/// # use bevy_ecs::system::SystemParam;
149/// #
150/// #[derive(SystemParam)]
151/// struct MyParam<'w> {
152///     #[system_param(validation_message = "Custom Message")]
153///     foo: Res<'w, SomeResource>,
154/// }
155///
156/// let mut world = World::new();
157/// let err = world.run_system_cached(|param: MyParam| {}).unwrap_err();
158/// let expected = "Parameter `MyParam::foo` failed validation: Custom Message";
159/// # #[cfg(feature="Trace")] // Without debug_utils/debug enabled MyParam::foo is stripped and breaks the assert
160/// assert!(err.to_string().contains(expected));
161/// ```
162///
163/// ## Builders
164///
165/// If you want to use a [`SystemParamBuilder`](crate::system::SystemParamBuilder) with a derived [`SystemParam`] implementation,
166/// add a `#[system_param(builder)]` attribute to the struct.
167/// This will generate a builder struct whose name is the param struct suffixed with `Builder`.
168/// The builder will not be `pub`, so you may want to expose a method that returns an `impl SystemParamBuilder<T>`.
169///
170/// ```
171/// mod custom_param {
172/// #     use bevy_ecs::{
173/// #         prelude::*,
174/// #         system::{LocalBuilder, QueryParamBuilder, SystemParam},
175/// #     };
176/// #
177///     #[derive(SystemParam)]
178///     #[system_param(builder)]
179///     pub struct CustomParam<'w, 's> {
180///         query: Query<'w, 's, ()>,
181///         local: Local<'s, usize>,
182///     }
183///
184///     impl<'w, 's> CustomParam<'w, 's> {
185///         pub fn builder(
186///             local: usize,
187///             query: impl FnOnce(&mut QueryBuilder<()>),
188///         ) -> impl SystemParamBuilder<Self> {
189///             CustomParamBuilder {
190///                 local: LocalBuilder(local),
191///                 query: QueryParamBuilder::new(query),
192///             }
193///         }
194///     }
195/// }
196///
197/// use custom_param::CustomParam;
198///
199/// # use bevy_ecs::prelude::*;
200/// # #[derive(Component)]
201/// # struct A;
202/// #
203/// # let mut world = World::new();
204/// #
205/// let system = (CustomParam::builder(100, |builder| {
206///     builder.with::<A>();
207/// }),)
208///     .build_state(&mut world)
209///     .build_system(|param: CustomParam| {});
210/// ```
211///
212/// # Safety
213///
214/// The implementor must ensure the following is true.
215/// - [`SystemParam::init_access`] correctly registers all [`World`] accesses used
216///   by [`SystemParam::get_param`] with the provided [`system_meta`](SystemMeta).
217/// - None of the world accesses may conflict with any prior accesses registered
218///   on `system_meta`.
219pub unsafe trait SystemParam: Sized {
220    /// Used to store data which persists across invocations of a system.
221    type State: Send + Sync + 'static;
222
223    /// The item type returned when constructing this system param.
224    /// The value of this associated type should be `Self`, instantiated with new lifetimes.
225    ///
226    /// You could think of [`SystemParam::Item<'w, 's>`] as being an *operation* that changes the lifetimes bound to `Self`.
227    type Item<'world, 'state>: SystemParam<State = Self::State>;
228
229    /// Creates a new instance of this param's [`State`](SystemParam::State).
230    fn init_state(world: &mut World) -> Self::State;
231
232    /// Registers any [`World`] access used by this [`SystemParam`].
233    ///
234    /// This method must panic if the access would conflict with any existing
235    /// access in the [`SystemAccess`].
236    fn init_access(
237        state: &Self::State,
238        system_meta: &mut SystemMeta,
239        system_access: &mut SystemAccess,
240        world: &mut World,
241    );
242
243    /// Applies any deferred mutations stored in this [`SystemParam`]'s state.
244    /// This is used to apply [`Commands`] during [`ApplyDeferred`](crate::prelude::ApplyDeferred).
245    ///
246    /// [`Commands`]: crate::prelude::Commands
247    #[inline]
248    #[expect(
249        unused_variables,
250        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."
251    )]
252    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {}
253
254    /// Queues any deferred mutations to be applied at the next [`ApplyDeferred`](crate::prelude::ApplyDeferred).
255    #[inline]
256    #[expect(
257        unused_variables,
258        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."
259    )]
260    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {}
261
262    /// Creates a parameter to be passed into a [`SystemParamFunction`](super::SystemParamFunction).
263    ///
264    /// This method also validates that the param can be acquired. If validation fails,
265    /// an appropriate [`SystemParamValidationError`] should be returned.
266    /// Systems will convert this to a [`RunSystemError`](super::RunSystemError),
267    /// and the built-in executors will ignore any "skipped" validation results,
268    /// but pass any "invalid" results to the fallback error handler defined in [`bevy_ecs::error`].
269    ///
270    /// For nested [`SystemParam`]s validation will fail if any
271    /// delegated validation fails.
272    ///
273    /// # Safety
274    ///
275    /// - The passed [`UnsafeWorldCell`] must have access to any world data registered
276    ///   in [`init_access`](SystemParam::init_access).
277    /// - The passed [`UnsafeWorldCell`] must not be accessed in any way if no
278    ///   access was registered in [`init_access`](SystemParam::init_access).
279    /// - [`SystemParam::init_access`] must not request conflicting access.
280    ///   If `Self` is `ReadOnlySystemParam`, the access is read-only and can never conflict.
281    ///   Otherwise, [`SystemParam::init_access`] must be called to ensure it does not panic.
282    /// - `world` must be the same [`World`] that was used to initialize [`state`](SystemParam::init_state).
283    unsafe fn get_param<'world, 'state>(
284        state: &'state mut Self::State,
285        system_meta: &SystemMeta,
286        world: UnsafeWorldCell<'world>,
287        change_tick: Tick,
288    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError>;
289}
290
291/// A [`SystemParam`] that only reads a given [`World`].
292///
293/// # Safety
294/// This must only be implemented for [`SystemParam`] impls that exclusively read the World passed in to [`SystemParam::get_param`]
295pub unsafe trait ReadOnlySystemParam: SystemParam {}
296
297/// Shorthand way of accessing the associated type [`SystemParam::Item`] for a given [`SystemParam`].
298pub type SystemParamItem<'w, 's, P> = <P as SystemParam>::Item<'w, 's>;
299
300// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
301unsafe impl<'w, 's, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
302    for Query<'w, 's, D, F>
303{
304}
305
306// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
307// this Query conflicts with any prior access, a panic will occur.
308unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam for Query<'_, '_, D, F> {
309    type State = QueryState<D, F>;
310    type Item<'w, 's> = Query<'w, 's, D, F>;
311
312    fn init_state(world: &mut World) -> Self::State {
313        // SAFETY: `SystemParam::init_access` calls `QueryState::init_access`,
314        // `SystemParam::init_access` must be called before `SystemParam::get_param`,
315        // and we only call methods on the `QueryState` in `get_param`.
316        unsafe { QueryState::new_unchecked(world) }
317    }
318
319    fn init_access(
320        state: &Self::State,
321        system_meta: &mut SystemMeta,
322        system_access: &mut SystemAccess,
323        world: &mut World,
324    ) {
325        let component_access_set = system_access.require_shared_access::<Self>(system_meta);
326        state.init_access(Some(system_meta.name()), component_access_set, world.into());
327    }
328
329    #[inline]
330    unsafe fn get_param<'w, 's>(
331        state: &'s mut Self::State,
332        system_meta: &SystemMeta,
333        world: UnsafeWorldCell<'w>,
334        change_tick: Tick,
335    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
336        // SAFETY: We have registered all of the query's world accesses,
337        // so the caller ensures that `world` has permission to access any
338        // world data that the query needs.
339        // The caller ensures the world matches the one used in init_state.
340        Ok(unsafe { state.query_unchecked_with_ticks(world, system_meta.last_run, change_tick) })
341    }
342}
343
344// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
345// this Query conflicts with any prior access, a panic will occur.
346unsafe impl<'a, 'b, D: IterQueryData + 'static, F: QueryFilter + 'static> SystemParam
347    for Single<'a, 'b, D, F>
348{
349    type State = QueryState<D, F>;
350    type Item<'w, 's> = Single<'w, 's, D, F>;
351
352    fn init_state(world: &mut World) -> Self::State {
353        Query::init_state(world)
354    }
355
356    fn init_access(
357        state: &Self::State,
358        system_meta: &mut SystemMeta,
359        system_access: &mut SystemAccess,
360        world: &mut World,
361    ) {
362        Query::init_access(state, system_meta, system_access, world);
363    }
364
365    #[inline]
366    unsafe fn get_param<'w, 's>(
367        state: &'s mut Self::State,
368        system_meta: &SystemMeta,
369        world: UnsafeWorldCell<'w>,
370        change_tick: Tick,
371    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
372        // SAFETY: State ensures that the components it accesses are not accessible somewhere elsewhere.
373        // The caller ensures the world matches the one used in init_state.
374        let query =
375            unsafe { state.query_unchecked_with_ticks(world, system_meta.last_run, change_tick) };
376        match query.single_inner() {
377            Ok(single) => Ok(Single {
378                item: single,
379                _filter: PhantomData,
380            }),
381            Err(QuerySingleError::NoEntities(_)) => Err(
382                SystemParamValidationError::skipped::<Self>("No matching entities"),
383            ),
384            Err(QuerySingleError::MultipleEntities(_)) => Err(
385                SystemParamValidationError::skipped::<Self>("Multiple matching entities"),
386            ),
387        }
388    }
389}
390
391// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
392unsafe impl<'a, 'b, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
393    for Single<'a, 'b, D, F>
394{
395}
396
397// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
398// this Query conflicts with any prior access, a panic will occur.
399unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam
400    for Populated<'_, '_, D, F>
401{
402    type State = QueryState<D, F>;
403    type Item<'w, 's> = Populated<'w, 's, D, F>;
404
405    fn init_state(world: &mut World) -> Self::State {
406        Query::init_state(world)
407    }
408
409    fn init_access(
410        state: &Self::State,
411        system_meta: &mut SystemMeta,
412        system_access: &mut SystemAccess,
413        world: &mut World,
414    ) {
415        Query::init_access(state, system_meta, system_access, world);
416    }
417
418    #[inline]
419    unsafe fn get_param<'w, 's>(
420        state: &'s mut Self::State,
421        system_meta: &SystemMeta,
422        world: UnsafeWorldCell<'w>,
423        change_tick: Tick,
424    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
425        // SAFETY: Delegate to existing `SystemParam` implementations.
426        let query = unsafe { Query::get_param(state, system_meta, world, change_tick) }?;
427        if query.is_empty() {
428            Err(SystemParamValidationError::skipped::<Self>(
429                "No matching entities",
430            ))
431        } else {
432            Ok(Populated(query))
433        }
434    }
435}
436
437// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
438unsafe impl<'w, 's, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
439    for Populated<'w, 's, D, F>
440{
441}
442
443/// A collection of potentially conflicting [`SystemParam`]s allowed by disjoint access.
444///
445/// Allows systems to safely access and interact with up to 8 mutually exclusive [`SystemParam`]s, such as
446/// two queries that reference the same mutable data or an event reader and writer of the same type.
447///
448/// Each individual [`SystemParam`] can be accessed by using the functions `p0()`, `p1()`, ..., `p7()`,
449/// according to the order they are defined in the `ParamSet`. This ensures that there's either
450/// only one mutable reference to a parameter at a time or any number of immutable references.
451///
452/// # Examples
453///
454/// The following system mutably accesses the same component two times,
455/// which is not allowed due to rust's mutability rules.
456///
457/// ```should_panic
458/// # use bevy_ecs::prelude::*;
459/// #
460/// # #[derive(Component)]
461/// # struct Health;
462/// #
463/// # #[derive(Component)]
464/// # struct Enemy;
465/// #
466/// # #[derive(Component)]
467/// # struct Ally;
468/// #
469/// // This will panic at runtime when the system gets initialized.
470/// fn bad_system(
471///     mut enemies: Query<&mut Health, With<Enemy>>,
472///     mut allies: Query<&mut Health, With<Ally>>,
473/// ) {
474///     // ...
475/// }
476/// #
477/// # let mut bad_system_system = IntoSystem::into_system(bad_system);
478/// # let mut world = World::new();
479/// # bad_system_system.initialize(&mut world);
480/// # bad_system_system.run((), &mut world);
481/// ```
482///
483/// Conflicting `SystemParam`s like these can be placed in a `ParamSet`,
484/// which leverages the borrow checker to ensure that only one of the contained parameters are accessed at a given time.
485///
486/// ```
487/// # use bevy_ecs::prelude::*;
488/// #
489/// # #[derive(Component)]
490/// # struct Health;
491/// #
492/// # #[derive(Component)]
493/// # struct Enemy;
494/// #
495/// # #[derive(Component)]
496/// # struct Ally;
497/// #
498/// // Given the following system
499/// fn fancy_system(
500///     mut set: ParamSet<(
501///         Query<&mut Health, With<Enemy>>,
502///         Query<&mut Health, With<Ally>>,
503///     )>
504/// ) {
505///     // This will access the first `SystemParam`.
506///     for mut health in set.p0().iter_mut() {
507///         // Do your fancy stuff here...
508///     }
509///
510///     // The second `SystemParam`.
511///     // This would fail to compile if the previous parameter was still borrowed.
512///     for mut health in set.p1().iter_mut() {
513///         // Do even fancier stuff here...
514///     }
515/// }
516/// # bevy_ecs::system::assert_is_system(fancy_system);
517/// ```
518///
519/// Of course, `ParamSet`s can be used with any kind of `SystemParam`, not just [queries](Query).
520///
521/// ```
522/// # use bevy_ecs::prelude::*;
523/// #
524/// # #[derive(Message)]
525/// # struct MyMessage;
526/// # impl MyMessage {
527/// #   pub fn new() -> Self { Self }
528/// # }
529/// fn message_system(
530///     mut set: ParamSet<(
531///         // PROBLEM: `MessageReader` and `MessageWriter` cannot be used together normally,
532///         // because they both need access to the same message queue.
533///         // SOLUTION: `ParamSet` allows these conflicting parameters to be used safely
534///         // by ensuring only one is accessed at a time.
535///         // Note that a better solution here is to use `MessageMutator`,
536///         // which both reads and writes messages with a single parameter.
537///         MessageReader<MyMessage>,
538///         MessageWriter<MyMessage>,
539///         // PROBLEM: `&World` needs read access to everything, which conflicts with
540///         // any mutable access in the same system.
541///         // SOLUTION: `ParamSet` ensures `&World` is only accessed when we're not
542///         // using the other mutable parameters.
543///         &World,
544///     )>,
545/// ) {
546///     for message in set.p0().read() {
547///         // ...
548///         # let _message = message;
549///     }
550///     set.p1().write(MyMessage::new());
551///
552///     let entities = set.p2().entities();
553///     // ...
554///     # let _entities = entities;
555/// }
556/// # bevy_ecs::system::assert_is_system(message_system);
557/// ```
558pub struct ParamSet<'w, 's, T: SystemParam> {
559    param_states: &'s mut T::State,
560    world: UnsafeWorldCell<'w>,
561    system_meta: SystemMeta,
562    change_tick: Tick,
563}
564
565macro_rules! impl_param_set {
566    ($(($index: tt, $param: ident, $fn_name: ident)),*) => {
567        // SAFETY: All parameters are constrained to ReadOnlySystemParam, so World is only read
568        unsafe impl<'w, 's, $($param,)*> ReadOnlySystemParam for ParamSet<'w, 's, ($($param,)*)>
569        where $($param: ReadOnlySystemParam,)*
570        { }
571
572        // SAFETY: Relevant parameter ComponentId access is applied to SystemMeta. If any ParamState conflicts
573        // with any prior access, a panic will occur.
574        unsafe impl<'_w, '_s, $($param: SystemParam,)*> SystemParam for ParamSet<'_w, '_s, ($($param,)*)>
575        {
576            type State = ($($param::State,)*);
577            type Item<'w, 's> = ParamSet<'w, 's, ($($param,)*)>;
578
579            #[expect(
580                clippy::allow_attributes,
581                reason = "This is inside a macro meant for tuples; as such, `non_snake_case` won't always lint."
582            )]
583            #[allow(
584                non_snake_case,
585                reason = "Certain variable names are provided by the caller, not by us."
586            )]
587            fn init_state(world: &mut World) -> Self::State {
588                ($($param::init_state(world),)*)
589            }
590
591            #[expect(
592                clippy::allow_attributes,
593                reason = "This is inside a macro meant for tuples; as such, `non_snake_case` won't always lint."
594            )]
595            #[allow(
596                non_snake_case,
597                reason = "Certain variable names are provided by the caller, not by us."
598            )]
599            fn init_access(state: &Self::State, system_meta: &mut SystemMeta, system_access: &mut SystemAccess, world: &mut World) {
600                let ($($param,)*) = state;
601                $(
602                    // Call `init_access` on a clone of the original access set to check for conflicts
603                    let system_access_clone = &mut system_access.clone();
604                    $param::init_access($param, system_meta, system_access_clone, world);
605                )*
606                $(
607                    // Pretend to add the param to the system alone to gather the new access,
608                    // then merge its access into the system.
609                    let mut param_access = SystemAccess::default();
610                    $param::init_access($param, system_meta, &mut param_access, world);
611                    system_access.extend(param_access);
612                )*
613            }
614
615            fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
616                <($($param,)*) as SystemParam>::apply(state, system_meta, world);
617            }
618
619            fn queue(state: &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
620                <($($param,)*) as SystemParam>::queue(state, system_meta, world.reborrow());
621            }
622
623            #[inline]
624            unsafe fn get_param<'w, 's>(
625                state: &'s mut Self::State,
626                system_meta: &SystemMeta,
627                world: UnsafeWorldCell<'w>,
628                change_tick: Tick,
629            ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
630                // Validate each sub-param eagerly so that the system is correctly
631                // skipped by the executor when any sub-param is unavailable.
632                // PERF: the sub-params will be fetched again lazily when accessed through
633                // the ParamSet, but this is no worse than the previous
634                // validate_param + get_param pattern.
635                $(
636                    // SAFETY: Upheld by caller.
637                    drop(unsafe { $param::get_param(&mut state.$index, system_meta, world, change_tick) }?);
638                )*
639
640                Ok(ParamSet {
641                    param_states: state,
642                    system_meta: system_meta.clone(),
643                    world,
644                    change_tick,
645                })
646            }
647        }
648
649        impl<'w, 's, $($param: SystemParam,)*> ParamSet<'w, 's, ($($param,)*)>
650        {
651            $(
652                /// Gets exclusive access to the parameter at index
653                #[doc = stringify!($index)]
654                /// in this [`ParamSet`].
655                /// No other parameters may be accessed while this one is active.
656                pub fn $fn_name<'a>(&'a mut self) -> SystemParamItem<'a, 'a, $param> {
657                    // SAFETY: systems run without conflicts with other systems.
658                    // Conflicting params in ParamSet are not accessible at the same time
659                    // ParamSets are guaranteed to not conflict with other SystemParams
660                    unsafe {
661                        $param::get_param(&mut self.param_states.$index, &self.system_meta, self.world, self.change_tick)
662                    }
663                    .unwrap_or_else(|err| panic!("ParamSet parameter validation failed: {err}"))
664                }
665            )*
666        }
667    }
668}
669
670all_tuples_enumerated!(impl_param_set, 1, 8, P, p);
671
672// SAFETY: Res only reads a single World resource
673unsafe impl<'a, T: Resource> ReadOnlySystemParam for Res<'a, T> {}
674
675// SAFETY: Res ComponentId access is applied to SystemMeta. If this Res
676// conflicts with any prior access, a panic will occur.
677unsafe impl<'a, T: Resource> SystemParam for Res<'a, T> {
678    type State = ComponentId;
679    type Item<'w, 's> = Res<'w, T>;
680
681    fn init_state(world: &mut World) -> Self::State {
682        world.components_registrator().register_component::<T>()
683    }
684
685    fn init_access(
686        &component_id: &Self::State,
687        system_meta: &mut SystemMeta,
688        system_access: &mut SystemAccess,
689        world: &mut World,
690    ) {
691        let mut filter = FilteredAccess::default();
692        filter.add_read(component_id);
693        filter.and_with(IS_RESOURCE);
694
695        if let Err(conflicts) = system_access.try_add(filter) {
696            let mut accesses = conflicts.format_conflict_list(world.as_unsafe_world_cell());
697            // Access list may be empty (if access to all components requested)
698            if !accesses.is_empty() {
699                accesses.push(' ');
700            }
701            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);
702        }
703    }
704
705    #[inline]
706    unsafe fn get_param<'w, 's>(
707        &mut component_id: &'s mut Self::State,
708        system_meta: &SystemMeta,
709        world: UnsafeWorldCell<'w>,
710        change_tick: Tick,
711    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
712        let (ptr, ticks) = world.get_resource_with_ticks(component_id).ok_or_else(|| {
713            SystemParamValidationError::invalid::<Self>("Resource does not exist")
714        })?;
715        Ok(Res {
716            value: ptr.deref(),
717            ticks: ComponentTicksRef {
718                added: ticks.added.deref(),
719                changed: ticks.changed.deref(),
720                changed_by: ticks.changed_by.map(|changed_by| changed_by.deref()),
721                last_run: system_meta.last_run,
722                this_run: change_tick,
723            },
724        })
725    }
726}
727
728// SAFETY: Res ComponentId access is applied to SystemMeta. If this Res
729// conflicts with any prior access, a panic will occur.
730unsafe impl<'a, T: Resource<Mutability = Mutable>> SystemParam for ResMut<'a, T> {
731    type State = ComponentId;
732    type Item<'w, 's> = ResMut<'w, T>;
733
734    fn init_state(world: &mut World) -> Self::State {
735        world.components_registrator().register_component::<T>()
736    }
737
738    fn init_access(
739        &component_id: &Self::State,
740        system_meta: &mut SystemMeta,
741        system_access: &mut SystemAccess,
742        world: &mut World,
743    ) {
744        let mut filter = FilteredAccess::default();
745        filter.add_write(component_id);
746        filter.and_with(IS_RESOURCE);
747
748        if let Err(conflicts) = system_access.try_add(filter) {
749            let mut accesses = conflicts.format_conflict_list(world.as_unsafe_world_cell());
750            // Access list may be empty (if access to all components requested)
751            if !accesses.is_empty() {
752                accesses.push(' ');
753            }
754            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);
755        }
756    }
757
758    #[inline]
759    unsafe fn get_param<'w, 's>(
760        &mut component_id: &'s mut Self::State,
761        system_meta: &SystemMeta,
762        world: UnsafeWorldCell<'w>,
763        change_tick: Tick,
764    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
765        let value = world.get_resource_mut_by_id(component_id).ok_or_else(|| {
766            SystemParamValidationError::invalid::<Self>("Resource does not exist")
767        })?;
768        Ok(ResMut {
769            value: value.value.deref_mut::<T>(),
770            ticks: ComponentTicksMut {
771                added: value.ticks.added,
772                changed: value.ticks.changed,
773                changed_by: value.ticks.changed_by,
774                last_run: system_meta.last_run,
775                this_run: change_tick,
776                summary_tick: None,
777            },
778        })
779    }
780}
781
782// SAFETY: only reads world
783unsafe impl<'w> ReadOnlySystemParam for &'w World {}
784
785// SAFETY: `read_all` access is set and conflicts result in a panic
786unsafe impl SystemParam for &'_ World {
787    type State = ();
788    type Item<'w, 's> = &'w World;
789
790    fn init_state(_world: &mut World) -> Self::State {}
791
792    fn init_access(
793        _state: &Self::State,
794        system_meta: &mut SystemMeta,
795        system_access: &mut SystemAccess,
796        _world: &mut World,
797    ) {
798        let mut filtered_access = FilteredAccess::default();
799        filtered_access.read_all();
800
801        if system_access.try_add(filtered_access).is_err() {
802            panic!(
803                "&World in system {} conflicts with a previous system parameter's access.",
804                system_meta.name,
805            );
806        }
807    }
808
809    #[inline]
810    unsafe fn get_param<'w, 's>(
811        _state: &'s mut Self::State,
812        _system_meta: &SystemMeta,
813        world: UnsafeWorldCell<'w>,
814        _change_tick: Tick,
815    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
816        // SAFETY: Read-only access to the entire world was registered in `init_access`.
817        Ok(unsafe { world.world() })
818    }
819}
820
821// SAFETY: `write_all` access is set and conflicts result in a panic
822unsafe impl SystemParam for &'_ mut World {
823    type State = ();
824    type Item<'world, 'state> = &'world mut World;
825
826    fn init_state(_world: &mut World) -> Self::State {}
827
828    fn init_access(
829        _state: &Self::State,
830        system_meta: &mut SystemMeta,
831        system_access: &mut SystemAccess,
832        _world: &mut World,
833    ) {
834        // Exclusive systems must be ran on the main thread.
835        system_meta.set_non_send();
836
837        system_access.require_exclusive_access::<Self>(system_meta);
838    }
839
840    #[inline]
841    unsafe fn get_param<'world, 'state>(
842        _state: &'state mut Self::State,
843        _system_meta: &SystemMeta,
844        world: UnsafeWorldCell<'world>,
845        _change_tick: Tick,
846    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
847        // SAFETY: Write access to the entire world was registered in `init_access`.
848        Ok(unsafe { world.world_mut() })
849    }
850}
851
852// SAFETY: `DeferredWorld` can read all components and resources but cannot be used to gain any other mutable references.
853unsafe impl<'w> SystemParam for DeferredWorld<'w> {
854    type State = ();
855    type Item<'world, 'state> = DeferredWorld<'world>;
856
857    fn init_state(_world: &mut World) -> Self::State {}
858
859    fn init_access(
860        _state: &Self::State,
861        system_meta: &mut SystemMeta,
862        system_access: &mut SystemAccess,
863        _world: &mut World,
864    ) {
865        let mut filtered_access = FilteredAccess::default();
866        filtered_access.write_all();
867
868        if system_access.try_add(filtered_access).is_err() {
869            panic!(
870                "DeferredWorld in system {} conflicts with a previous system parameter's access.",
871                system_meta.name,
872            );
873        }
874    }
875
876    unsafe fn get_param<'world, 'state>(
877        _state: &'state mut Self::State,
878        _system_meta: &SystemMeta,
879        world: UnsafeWorldCell<'world>,
880        _change_tick: Tick,
881    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
882        // SAFETY: Write access to the entire world was registered in `init_access`
883        Ok(unsafe { world.into_deferred() })
884    }
885}
886
887/// A [`SystemParam`] that provides a system-private value of `T` that persists across system calls.
888///
889/// The initial value is created by calling `T`'s [`FromWorld::from_world`] (or [`Default::default`] if `T: Default`).
890///
891/// A local may only be accessed by the system itself and is therefore not visible to other systems.
892/// If two or more systems specify the same local type each will have their own unique local.
893/// If multiple [`SystemParam`]s within the same system each specify the same local type
894/// each will get their own distinct data storage.
895///
896/// The supplied lifetime parameter is the [`SystemParam`]s `'s` lifetime.
897///
898/// # Examples
899///
900/// ```
901/// # use bevy_ecs::prelude::*;
902/// # let world = &mut World::default();
903/// fn counter(mut count: Local<u32>) -> u32 {
904///     *count += 1;
905///     *count
906/// }
907/// let mut counter_system = IntoSystem::into_system(counter);
908/// counter_system.initialize(world);
909///
910/// // Counter is initialized to u32's default value of 0, and increases to 1 on first run.
911/// assert_eq!(counter_system.run((), world).unwrap(), 1);
912/// // Counter gets the same value and increases to 2 on its second call.
913/// assert_eq!(counter_system.run((), world).unwrap(), 2);
914/// ```
915///
916/// A simple way to set a different default value for a local is by wrapping the value with an Option.
917///
918/// ```
919/// # use bevy_ecs::prelude::*;
920/// # let world = &mut World::default();
921/// fn counter_from_10(mut count: Local<Option<u32>>) -> u32 {
922///     let count = count.get_or_insert(10);
923///     *count += 1;
924///     *count
925/// }
926/// let mut counter_system = IntoSystem::into_system(counter_from_10);
927/// counter_system.initialize(world);
928///
929/// // Counter is initialized at 10, and increases to 11 on first run.
930/// assert_eq!(counter_system.run((), world).unwrap(), 11);
931/// // Counter is only increased by 1 on subsequent runs.
932/// assert_eq!(counter_system.run((), world).unwrap(), 12);
933/// ```
934///
935/// A system can have multiple `Local` values with the same type, each with distinct values.
936///
937/// ```
938/// # use bevy_ecs::prelude::*;
939/// # let world = &mut World::default();
940/// fn double_counter(mut count: Local<u32>, mut double_count: Local<u32>) -> (u32, u32) {
941///     *count += 1;
942///     *double_count += 2;
943///     (*count, *double_count)
944/// }
945/// let mut counter_system = IntoSystem::into_system(double_counter);
946/// counter_system.initialize(world);
947///
948/// assert_eq!(counter_system.run((), world).unwrap(), (1, 2));
949/// assert_eq!(counter_system.run((), world).unwrap(), (2, 4));
950/// ```
951///
952/// This example shows that two systems using the same type for their own `Local` get distinct locals.
953///
954/// ```
955/// # use bevy_ecs::prelude::*;
956/// # let world = &mut World::default();
957/// fn write_to_local(mut local: Local<usize>) {
958///     *local = 42;
959/// }
960/// fn read_from_local(local: Local<usize>) -> usize {
961///     *local
962/// }
963/// let mut write_system = IntoSystem::into_system(write_to_local);
964/// let mut read_system = IntoSystem::into_system(read_from_local);
965/// write_system.initialize(world);
966/// read_system.initialize(world);
967///
968/// assert_eq!(read_system.run((), world).unwrap(), 0);
969/// write_system.run((), world);
970/// // The read local is still 0 due to the locals not being shared.
971/// assert_eq!(read_system.run((), world).unwrap(), 0);
972/// ```
973///
974/// You can use a `Local` to avoid reallocating memory every system call.
975///
976/// ```
977/// # use bevy_ecs::prelude::*;
978/// fn some_system(mut vec: Local<Vec<u32>>) {
979///     // Do your regular system logic, using the vec, as normal.
980///
981///     // At end of function, clear the vec's contents so its empty for next system call.
982///     // If it's possible the capacity could get too large, you may want to check and resize that as well.
983///     vec.clear();
984/// }
985/// ```
986///
987/// N.B. A [`Local`]s value cannot be read or written to outside of the containing system.
988/// To add configuration to a system, convert a capturing closure into the system instead:
989///
990/// ```
991/// # use bevy_ecs::prelude::*;
992/// # use bevy_ecs::system::assert_is_system;
993/// struct Config(u32);
994/// #[derive(Resource)]
995/// struct MyU32Wrapper(u32);
996/// fn reset_to_system(value: Config) -> impl FnMut(ResMut<MyU32Wrapper>) {
997///     move |mut val| val.0 = value.0
998/// }
999///
1000/// // .add_systems(reset_to_system(my_config))
1001/// # assert_is_system(reset_to_system(Config(10)));
1002/// ```
1003#[derive(Debug)]
1004pub struct Local<'s, T: FromWorld + Send + 'static>(pub(crate) &'s mut T);
1005
1006// SAFETY: Local only accesses internal state
1007unsafe impl<'s, T: FromWorld + Send + 'static> ReadOnlySystemParam for Local<'s, T> {}
1008
1009impl<'s, T: FromWorld + Send + 'static> Deref for Local<'s, T> {
1010    type Target = T;
1011
1012    #[inline]
1013    fn deref(&self) -> &Self::Target {
1014        self.0
1015    }
1016}
1017
1018impl<'s, T: FromWorld + Send + 'static> DerefMut for Local<'s, T> {
1019    #[inline]
1020    fn deref_mut(&mut self) -> &mut Self::Target {
1021        self.0
1022    }
1023}
1024
1025impl<'s, 'a, T: FromWorld + Send + 'static> IntoIterator for &'a Local<'s, T>
1026where
1027    &'a T: IntoIterator,
1028{
1029    type Item = <&'a T as IntoIterator>::Item;
1030    type IntoIter = <&'a T as IntoIterator>::IntoIter;
1031
1032    fn into_iter(self) -> Self::IntoIter {
1033        self.0.into_iter()
1034    }
1035}
1036
1037impl<'s, 'a, T: FromWorld + Send + 'static> IntoIterator for &'a mut Local<'s, T>
1038where
1039    &'a mut T: IntoIterator,
1040{
1041    type Item = <&'a mut T as IntoIterator>::Item;
1042    type IntoIter = <&'a mut T as IntoIterator>::IntoIter;
1043
1044    fn into_iter(self) -> Self::IntoIter {
1045        self.0.into_iter()
1046    }
1047}
1048
1049// SAFETY: only local state is accessed
1050unsafe impl<'a, T: FromWorld + Send + 'static> SystemParam for Local<'a, T> {
1051    type State = SyncCell<T>;
1052    type Item<'w, 's> = Local<'s, T>;
1053
1054    fn init_state(world: &mut World) -> Self::State {
1055        SyncCell::new(T::from_world(world))
1056    }
1057
1058    fn init_access(
1059        _state: &Self::State,
1060        _system_meta: &mut SystemMeta,
1061        _system_access: &mut SystemAccess,
1062        _world: &mut World,
1063    ) {
1064    }
1065
1066    #[inline]
1067    unsafe fn get_param<'w, 's>(
1068        state: &'s mut Self::State,
1069        _system_meta: &SystemMeta,
1070        _world: UnsafeWorldCell<'w>,
1071        _change_tick: Tick,
1072    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1073        Ok(Local(state.get()))
1074    }
1075}
1076
1077/// Types that can be used with [`Deferred<T>`] in systems.
1078/// This allows storing system-local data which is used to defer [`World`] mutations.
1079///
1080/// Types that implement `SystemBuffer` should take care to perform as many
1081/// computations up-front as possible. Buffers cannot be applied in parallel,
1082/// so you should try to minimize the time spent in [`SystemBuffer::apply`].
1083pub trait SystemBuffer: FromWorld + Send + 'static {
1084    /// Applies any deferred mutations to the [`World`].
1085    fn apply(&mut self, system_meta: &SystemMeta, world: &mut World) {
1086        self.queue(system_meta, world.into());
1087    }
1088    /// Queues any deferred mutations to be applied at the next [`ApplyDeferred`](crate::prelude::ApplyDeferred).
1089    ///
1090    /// To queue structural changes to [`DeferredWorld`], a command queue of the [`DeferredWorld`]
1091    /// should be used via [`commands`](crate::world::DeferredWorld::commands).
1092    fn queue(&mut self, _system_meta: &SystemMeta, _world: DeferredWorld);
1093}
1094
1095/// A [`SystemParam`] that stores a buffer which gets applied to the [`World`] during
1096/// [`ApplyDeferred`](crate::schedule::ApplyDeferred).
1097/// This is used internally by [`Commands`] to defer `World` mutations.
1098///
1099/// [`Commands`]: crate::system::Commands
1100///
1101/// # Examples
1102///
1103/// By using this type to defer mutations, you can avoid mutable `World` access within
1104/// a system, which allows it to run in parallel with more systems.
1105///
1106/// Note that deferring mutations is *not* free, and should only be used if
1107/// the gains in parallelization outweigh the time it takes to apply deferred mutations.
1108/// In general, [`Deferred`] should only be used for mutations that are infrequent,
1109/// or which otherwise take up a small portion of a system's run-time.
1110///
1111/// ```
1112/// # use bevy_ecs::prelude::*;
1113/// # use bevy_ecs::world::DeferredWorld;
1114/// // Tracks whether or not there is a threat the player should be aware of.
1115/// #[derive(Resource, Default)]
1116/// pub struct Alarm(bool);
1117///
1118/// #[derive(Component)]
1119/// pub struct Settlement {
1120///     // ...
1121/// }
1122///
1123/// // A threat from inside the settlement.
1124/// #[derive(Component)]
1125/// pub struct Criminal;
1126///
1127/// // A threat from outside the settlement.
1128/// #[derive(Component)]
1129/// pub struct Monster;
1130///
1131/// # impl Criminal { pub fn is_threat(&self, _: &Settlement) -> bool { true } }
1132///
1133/// use bevy_ecs::system::{Deferred, SystemBuffer, SystemMeta};
1134///
1135/// // Uses deferred mutations to allow signaling the alarm from multiple systems in parallel.
1136/// #[derive(Resource, Default)]
1137/// struct AlarmFlag(bool);
1138///
1139/// impl AlarmFlag {
1140///     /// Sounds the alarm the next time buffers are applied via ApplyDeferred.
1141///     pub fn flag(&mut self) {
1142///         self.0 = true;
1143///     }
1144/// }
1145///
1146/// impl SystemBuffer for AlarmFlag {
1147///     // When `AlarmFlag` is used in a system, this function will get
1148///     // called the next time buffers are applied via ApplyDeferred.
1149///     fn queue(&mut self, system_meta: &SystemMeta, mut world: DeferredWorld) {
1150///         if self.0 {
1151///             world.resource_mut::<Alarm>().0 = true;
1152///             self.0 = false;
1153///         }
1154///     }
1155/// }
1156///
1157/// // Sound the alarm if there are any criminals who pose a threat.
1158/// fn alert_criminal(
1159///     settlement: Single<&Settlement>,
1160///     criminals: Query<&Criminal>,
1161///     mut alarm: Deferred<AlarmFlag>
1162/// ) {
1163///     for criminal in &criminals {
1164///         // Only sound the alarm if the criminal is a threat.
1165///         // For this example, assume that this check is expensive to run.
1166///         // Since the majority of this system's run-time is dominated
1167///         // by calling `is_threat()`, we defer sounding the alarm to
1168///         // allow this system to run in parallel with other alarm systems.
1169///         if criminal.is_threat(*settlement) {
1170///             alarm.flag();
1171///         }
1172///     }
1173/// }
1174///
1175/// // Sound the alarm if there is a monster.
1176/// fn alert_monster(
1177///     monsters: Query<&Monster>,
1178///     mut alarm: ResMut<Alarm>
1179/// ) {
1180///     if monsters.iter().next().is_some() {
1181///         // Since this system does nothing except for sounding the alarm,
1182///         // it would be pointless to defer it, so we sound the alarm directly.
1183///         alarm.0 = true;
1184///     }
1185/// }
1186///
1187/// let mut world = World::new();
1188/// world.init_resource::<Alarm>();
1189/// world.spawn(Settlement {
1190///     // ...
1191/// });
1192///
1193/// let mut schedule = Schedule::default();
1194/// // These two systems have no conflicts and will run in parallel.
1195/// schedule.add_systems((alert_criminal, alert_monster));
1196///
1197/// // There are no criminals or monsters, so the alarm is not sounded.
1198/// schedule.run(&mut world);
1199/// assert_eq!(world.resource::<Alarm>().0, false);
1200///
1201/// // Spawn a monster, which will cause the alarm to be sounded.
1202/// let m_id = world.spawn(Monster).id();
1203/// schedule.run(&mut world);
1204/// assert_eq!(world.resource::<Alarm>().0, true);
1205///
1206/// // Remove the monster and reset the alarm.
1207/// world.entity_mut(m_id).despawn();
1208/// world.resource_mut::<Alarm>().0 = false;
1209///
1210/// // Spawn a criminal, which will cause the alarm to be sounded.
1211/// world.spawn(Criminal);
1212/// schedule.run(&mut world);
1213/// assert_eq!(world.resource::<Alarm>().0, true);
1214/// ```
1215pub struct Deferred<'a, T: SystemBuffer>(pub(crate) &'a mut T);
1216
1217impl<'a, T: SystemBuffer> Deref for Deferred<'a, T> {
1218    type Target = T;
1219    #[inline]
1220    fn deref(&self) -> &Self::Target {
1221        self.0
1222    }
1223}
1224
1225impl<'a, T: SystemBuffer> DerefMut for Deferred<'a, T> {
1226    #[inline]
1227    fn deref_mut(&mut self) -> &mut Self::Target {
1228        self.0
1229    }
1230}
1231
1232impl<T: SystemBuffer> Deferred<'_, T> {
1233    /// Returns a [`Deferred<T>`] with a smaller lifetime.
1234    /// This is useful if you have `&mut Deferred<T>` but need `Deferred<T>`.
1235    pub fn reborrow(&mut self) -> Deferred<'_, T> {
1236        Deferred(self.0)
1237    }
1238}
1239
1240// SAFETY: Only local state is accessed.
1241unsafe impl<T: SystemBuffer> ReadOnlySystemParam for Deferred<'_, T> {}
1242
1243// SAFETY: Only local state is accessed.
1244unsafe impl<T: SystemBuffer> SystemParam for Deferred<'_, T> {
1245    type State = SyncCell<T>;
1246    type Item<'w, 's> = Deferred<'s, T>;
1247
1248    #[track_caller]
1249    fn init_state(world: &mut World) -> Self::State {
1250        SyncCell::new(T::from_world(world))
1251    }
1252
1253    fn init_access(
1254        _state: &Self::State,
1255        system_meta: &mut SystemMeta,
1256        _system_access: &mut SystemAccess,
1257        _world: &mut World,
1258    ) {
1259        system_meta.set_has_deferred();
1260    }
1261
1262    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1263        state.get().apply(system_meta, world);
1264    }
1265
1266    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1267        state.get().queue(system_meta, world);
1268    }
1269
1270    #[inline]
1271    unsafe fn get_param<'w, 's>(
1272        state: &'s mut Self::State,
1273        _system_meta: &SystemMeta,
1274        _world: UnsafeWorldCell<'w>,
1275        _change_tick: Tick,
1276    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1277        Ok(Deferred(state.get()))
1278    }
1279}
1280
1281/// A dummy type that is [`!Send`](Send), to force systems to run on the main thread.
1282pub struct NonSendMarker(PhantomData<*mut ()>);
1283
1284// SAFETY: No world access.
1285unsafe impl SystemParam for NonSendMarker {
1286    type State = ();
1287    type Item<'w, 's> = Self;
1288
1289    #[inline]
1290    fn init_state(_world: &mut World) -> Self::State {}
1291
1292    fn init_access(
1293        _state: &Self::State,
1294        system_meta: &mut SystemMeta,
1295        _system_access: &mut SystemAccess,
1296        _world: &mut World,
1297    ) {
1298        system_meta.set_non_send();
1299    }
1300
1301    #[inline]
1302    unsafe fn get_param<'world, 'state>(
1303        _state: &'state mut Self::State,
1304        _system_meta: &SystemMeta,
1305        _world: UnsafeWorldCell<'world>,
1306        _change_tick: Tick,
1307    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1308        Ok(Self(PhantomData))
1309    }
1310}
1311
1312// SAFETY: Does not read any world state
1313unsafe impl ReadOnlySystemParam for NonSendMarker {}
1314
1315// SAFETY: Only reads a single World non-send resource
1316unsafe impl<'w, T> ReadOnlySystemParam for NonSend<'w, T> {}
1317
1318// SAFETY: NonSendComponentId access is applied to SystemMeta. If this
1319// NonSend conflicts with any prior access, a panic will occur.
1320unsafe impl<'a, T: 'static> SystemParam for NonSend<'a, T> {
1321    type State = ComponentId;
1322    type Item<'w, 's> = NonSend<'w, T>;
1323
1324    fn init_state(world: &mut World) -> Self::State {
1325        world.components_registrator().register_non_send::<T>()
1326    }
1327
1328    fn init_access(
1329        &component_id: &Self::State,
1330        system_meta: &mut SystemMeta,
1331        system_access: &mut SystemAccess,
1332        _world: &mut World,
1333    ) {
1334        system_meta.set_non_send();
1335
1336        let mut filtered_access = FilteredAccess::default();
1337        filtered_access.add_read(component_id);
1338
1339        if system_access.try_add(filtered_access).is_err() {
1340            panic!(
1341                "error[B0002]: NonSend<{}> in system {} conflicts with a previous system parameter's access. Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002",
1342                DebugName::type_name::<T>(), system_meta.name,
1343            );
1344        }
1345    }
1346
1347    #[inline]
1348    unsafe fn get_param<'w, 's>(
1349        &mut component_id: &'s mut Self::State,
1350        system_meta: &SystemMeta,
1351        world: UnsafeWorldCell<'w>,
1352        change_tick: Tick,
1353    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1354        let (ptr, ticks) = world.get_non_send_with_ticks(component_id).ok_or_else(|| {
1355            SystemParamValidationError::invalid::<Self>("Non-send data not found")
1356        })?;
1357        Ok(NonSend {
1358            value: ptr.deref(),
1359            ticks: ComponentTicksRef::from_tick_cells(ticks, system_meta.last_run, change_tick),
1360        })
1361    }
1362}
1363
1364// SAFETY: NonSendMut ComponentId access is applied to SystemMeta. If this
1365// NonSendMut conflicts with any prior access, a panic will occur.
1366unsafe impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> {
1367    type State = ComponentId;
1368    type Item<'w, 's> = NonSendMut<'w, T>;
1369
1370    fn init_state(world: &mut World) -> Self::State {
1371        world.components_registrator().register_non_send::<T>()
1372    }
1373
1374    fn init_access(
1375        &component_id: &Self::State,
1376        system_meta: &mut SystemMeta,
1377        system_access: &mut SystemAccess,
1378        _world: &mut World,
1379    ) {
1380        system_meta.set_non_send();
1381
1382        let mut filtered_access = FilteredAccess::default();
1383        filtered_access.add_write(component_id);
1384
1385        if system_access.try_add(filtered_access).is_err() {
1386            panic!(
1387                "error[B0002]: NonSendMut<{}> in system {} conflicts with a previous system parameter's access. Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002",
1388                DebugName::type_name::<T>(), system_meta.name,
1389            );
1390        }
1391    }
1392
1393    #[inline]
1394    unsafe fn get_param<'w, 's>(
1395        &mut component_id: &'s mut Self::State,
1396        system_meta: &SystemMeta,
1397        world: UnsafeWorldCell<'w>,
1398        change_tick: Tick,
1399    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1400        let (ptr, ticks) = world.get_non_send_with_ticks(component_id).ok_or_else(|| {
1401            SystemParamValidationError::invalid::<Self>("Non-send data not found")
1402        })?;
1403        Ok(NonSendMut {
1404            value: ptr.assert_unique().deref_mut(),
1405            ticks: ComponentTicksMut::from_tick_cells(ticks, system_meta.last_run, change_tick),
1406        })
1407    }
1408}
1409
1410// SAFETY: Only reads World archetypes
1411unsafe impl<'a> ReadOnlySystemParam for &'a Archetypes {}
1412
1413// SAFETY: no component value access
1414unsafe impl<'a> SystemParam for &'a Archetypes {
1415    type State = ();
1416    type Item<'w, 's> = &'w Archetypes;
1417
1418    fn init_state(_world: &mut World) -> Self::State {}
1419
1420    fn init_access(
1421        _state: &Self::State,
1422        system_meta: &mut SystemMeta,
1423        system_access: &mut SystemAccess,
1424        _world: &mut World,
1425    ) {
1426        system_access.require_shared_access::<Self>(system_meta);
1427    }
1428
1429    #[inline]
1430    unsafe fn get_param<'w, 's>(
1431        _state: &'s mut Self::State,
1432        _system_meta: &SystemMeta,
1433        world: UnsafeWorldCell<'w>,
1434        _change_tick: Tick,
1435    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1436        Ok(world.archetypes())
1437    }
1438}
1439
1440// SAFETY: Only reads World resource entities
1441unsafe impl<'a> ReadOnlySystemParam for &'a ResourceEntities {}
1442
1443// SAFETY: no component value access
1444unsafe impl<'a> SystemParam for &'a ResourceEntities {
1445    type State = ();
1446    type Item<'w, 's> = &'w ResourceEntities;
1447
1448    fn init_state(_world: &mut World) -> Self::State {}
1449
1450    fn init_access(
1451        _state: &Self::State,
1452        system_meta: &mut SystemMeta,
1453        system_access: &mut SystemAccess,
1454        _world: &mut World,
1455    ) {
1456        system_access.require_shared_access::<Self>(system_meta);
1457    }
1458
1459    #[inline]
1460    unsafe fn get_param<'w, 's>(
1461        _state: &'s mut Self::State,
1462        _system_meta: &SystemMeta,
1463        world: UnsafeWorldCell<'w>,
1464        _change_tick: Tick,
1465    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1466        Ok(world.resource_entities())
1467    }
1468}
1469
1470// SAFETY: Only reads World components
1471unsafe impl<'a> ReadOnlySystemParam for &'a Components {}
1472
1473// SAFETY: no component value access
1474unsafe impl<'a> SystemParam for &'a Components {
1475    type State = ();
1476    type Item<'w, 's> = &'w Components;
1477
1478    fn init_state(_world: &mut World) -> Self::State {}
1479
1480    fn init_access(
1481        _state: &Self::State,
1482        system_meta: &mut SystemMeta,
1483        system_access: &mut SystemAccess,
1484        _world: &mut World,
1485    ) {
1486        system_access.require_shared_access::<Self>(system_meta);
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.components())
1497    }
1498}
1499
1500// SAFETY: Only reads World entities
1501unsafe impl<'a> ReadOnlySystemParam for &'a Entities {}
1502
1503// SAFETY: no component value access
1504unsafe impl<'a> SystemParam for &'a Entities {
1505    type State = ();
1506    type Item<'w, 's> = &'w Entities;
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        system_access: &mut SystemAccess,
1514        _world: &mut World,
1515    ) {
1516        system_access.require_shared_access::<Self>(system_meta);
1517    }
1518
1519    #[inline]
1520    unsafe fn get_param<'w, 's>(
1521        _state: &'s mut Self::State,
1522        _system_meta: &SystemMeta,
1523        world: UnsafeWorldCell<'w>,
1524        _change_tick: Tick,
1525    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1526        Ok(world.entities())
1527    }
1528}
1529
1530// SAFETY: Only reads World entities
1531unsafe impl<'a> ReadOnlySystemParam for &'a EntityAllocator {}
1532
1533// SAFETY: no component value access
1534unsafe impl<'a> SystemParam for &'a EntityAllocator {
1535    type State = ();
1536    type Item<'w, 's> = &'w EntityAllocator;
1537
1538    fn init_state(_world: &mut World) -> Self::State {}
1539
1540    fn init_access(
1541        _state: &Self::State,
1542        system_meta: &mut SystemMeta,
1543        system_access: &mut SystemAccess,
1544        _world: &mut World,
1545    ) {
1546        system_access.require_shared_access::<Self>(system_meta);
1547    }
1548
1549    #[inline]
1550    unsafe fn get_param<'w, 's>(
1551        _state: &'s mut Self::State,
1552        _system_meta: &SystemMeta,
1553        world: UnsafeWorldCell<'w>,
1554        _change_tick: Tick,
1555    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1556        Ok(world.entity_allocator())
1557    }
1558}
1559
1560// SAFETY: Only reads World bundles
1561unsafe impl<'a> ReadOnlySystemParam for &'a Bundles {}
1562
1563// SAFETY: no component value access
1564unsafe impl<'a> SystemParam for &'a Bundles {
1565    type State = ();
1566    type Item<'w, 's> = &'w Bundles;
1567
1568    fn init_state(_world: &mut World) -> Self::State {}
1569
1570    fn init_access(
1571        _state: &Self::State,
1572        system_meta: &mut SystemMeta,
1573        system_access: &mut SystemAccess,
1574        _world: &mut World,
1575    ) {
1576        system_access.require_shared_access::<Self>(system_meta);
1577    }
1578
1579    #[inline]
1580    unsafe fn get_param<'w, 's>(
1581        _state: &'s mut Self::State,
1582        _system_meta: &SystemMeta,
1583        world: UnsafeWorldCell<'w>,
1584        _change_tick: Tick,
1585    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1586        Ok(world.bundles())
1587    }
1588}
1589
1590/// A [`SystemParam`] that reads the previous and current change ticks of the system.
1591///
1592/// A system's change ticks are updated each time it runs:
1593/// - `last_run` copies the previous value of `change_tick`
1594/// - `this_run` copies the current value of [`World::read_change_tick`]
1595///
1596/// Component change ticks that are more recent than `last_run` will be detected by the system.
1597/// Those can be read by calling [`last_changed`](crate::change_detection::DetectChanges::last_changed)
1598/// on a [`Mut<T>`](crate::change_detection::Mut) or [`ResMut<T>`](ResMut).
1599#[derive(Debug, Clone, Copy)]
1600pub struct SystemChangeTick {
1601    last_run: Tick,
1602    this_run: Tick,
1603}
1604
1605impl SystemChangeTick {
1606    /// Returns the current [`World`] change tick seen by the system.
1607    #[inline]
1608    pub fn this_run(&self) -> Tick {
1609        self.this_run
1610    }
1611
1612    /// Returns the [`World`] change tick seen by the system the previous time it ran.
1613    #[inline]
1614    pub fn last_run(&self) -> Tick {
1615        self.last_run
1616    }
1617}
1618
1619// SAFETY: Only reads internal system state
1620unsafe impl ReadOnlySystemParam for SystemChangeTick {}
1621
1622// SAFETY: `SystemChangeTick` doesn't require any world access
1623unsafe impl SystemParam for SystemChangeTick {
1624    type State = ();
1625    type Item<'w, 's> = SystemChangeTick;
1626
1627    fn init_state(_world: &mut World) -> Self::State {}
1628
1629    fn init_access(
1630        _state: &Self::State,
1631        _system_meta: &mut SystemMeta,
1632        _system_access: &mut SystemAccess,
1633        _world: &mut World,
1634    ) {
1635    }
1636
1637    #[inline]
1638    unsafe fn get_param<'w, 's>(
1639        _state: &'s mut Self::State,
1640        system_meta: &SystemMeta,
1641        _world: UnsafeWorldCell<'w>,
1642        change_tick: Tick,
1643    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1644        Ok(SystemChangeTick {
1645            last_run: system_meta.last_run,
1646            this_run: change_tick,
1647        })
1648    }
1649}
1650
1651// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1652unsafe impl<T: SystemParam> SystemParam for Option<T> {
1653    type State = T::State;
1654
1655    type Item<'world, 'state> = Option<T::Item<'world, 'state>>;
1656
1657    fn init_state(world: &mut World) -> Self::State {
1658        T::init_state(world)
1659    }
1660
1661    fn init_access(
1662        state: &Self::State,
1663        system_meta: &mut SystemMeta,
1664        system_access: &mut SystemAccess,
1665        world: &mut World,
1666    ) {
1667        T::init_access(state, system_meta, system_access, world);
1668    }
1669
1670    #[inline]
1671    unsafe fn get_param<'world, 'state>(
1672        state: &'state mut Self::State,
1673        system_meta: &SystemMeta,
1674        world: UnsafeWorldCell<'world>,
1675        change_tick: Tick,
1676    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1677        // SAFETY: Upheld by caller
1678        Ok(unsafe { T::get_param(state, system_meta, world, change_tick) }.ok())
1679    }
1680
1681    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1682        T::apply(state, system_meta, world);
1683    }
1684
1685    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1686        T::queue(state, system_meta, world);
1687    }
1688}
1689
1690// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1691unsafe impl<T: ReadOnlySystemParam> ReadOnlySystemParam for Option<T> {}
1692
1693// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1694unsafe impl<T: SystemParam> SystemParam for Result<T, SystemParamValidationError> {
1695    type State = T::State;
1696
1697    type Item<'world, 'state> = Result<T::Item<'world, 'state>, SystemParamValidationError>;
1698
1699    fn init_state(world: &mut World) -> Self::State {
1700        T::init_state(world)
1701    }
1702
1703    fn init_access(
1704        state: &Self::State,
1705        system_meta: &mut SystemMeta,
1706        system_access: &mut SystemAccess,
1707        world: &mut World,
1708    ) {
1709        T::init_access(state, system_meta, system_access, world);
1710    }
1711
1712    #[inline]
1713    unsafe fn get_param<'world, 'state>(
1714        state: &'state mut Self::State,
1715        system_meta: &SystemMeta,
1716        world: UnsafeWorldCell<'world>,
1717        change_tick: Tick,
1718    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1719        // SAFETY: Upheld by caller
1720        Ok(unsafe { T::get_param(state, system_meta, world, change_tick) })
1721    }
1722
1723    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1724        T::apply(state, system_meta, world);
1725    }
1726
1727    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1728        T::queue(state, system_meta, world);
1729    }
1730}
1731
1732// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1733unsafe impl<T: ReadOnlySystemParam> ReadOnlySystemParam for Result<T, SystemParamValidationError> {}
1734
1735/// A [`SystemParam`] that wraps another parameter and causes its system to skip instead of failing when the parameter is invalid.
1736///
1737/// # Example
1738///
1739/// ```
1740/// # use bevy_ecs::prelude::*;
1741/// # #[derive(Resource)]
1742/// # struct SomeResource;
1743/// // This system will fail if `SomeResource` is not present.
1744/// fn fails_on_missing_resource(res: Res<SomeResource>) {}
1745///
1746/// // This system will skip without error if `SomeResource` is not present.
1747/// fn skips_on_missing_resource(res: If<Res<SomeResource>>) {
1748///     // The inner parameter is available using `Deref`
1749///     let some_resource: &SomeResource = &res;
1750/// }
1751/// # bevy_ecs::system::assert_is_system(skips_on_missing_resource);
1752/// ```
1753#[derive(Debug)]
1754pub struct If<T>(pub T);
1755
1756impl<T> If<T> {
1757    /// Returns the inner `T`.
1758    ///
1759    /// The inner value is `pub`, so you can also obtain it by destructuring the parameter:
1760    ///
1761    /// ```
1762    /// # use bevy_ecs::prelude::*;
1763    /// # #[derive(Resource)]
1764    /// # struct SomeResource;
1765    /// fn skips_on_missing_resource(If(res): If<Res<SomeResource>>) {
1766    ///     let some_resource: Res<SomeResource> = res;
1767    /// }
1768    /// # bevy_ecs::system::assert_is_system(skips_on_missing_resource);
1769    /// ```
1770    pub fn into_inner(self) -> T {
1771        self.0
1772    }
1773}
1774
1775impl<T> Deref for If<T> {
1776    type Target = T;
1777    fn deref(&self) -> &Self::Target {
1778        &self.0
1779    }
1780}
1781
1782impl<T> DerefMut for If<T> {
1783    fn deref_mut(&mut self) -> &mut Self::Target {
1784        &mut self.0
1785    }
1786}
1787
1788// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1789unsafe impl<T: SystemParam> SystemParam for If<T> {
1790    type State = T::State;
1791
1792    type Item<'world, 'state> = If<T::Item<'world, 'state>>;
1793
1794    fn init_state(world: &mut World) -> Self::State {
1795        T::init_state(world)
1796    }
1797
1798    fn init_access(
1799        state: &Self::State,
1800        system_meta: &mut SystemMeta,
1801        system_access: &mut SystemAccess,
1802        world: &mut World,
1803    ) {
1804        T::init_access(state, system_meta, system_access, world);
1805    }
1806
1807    #[inline]
1808    unsafe fn get_param<'world, 'state>(
1809        state: &'state mut Self::State,
1810        system_meta: &SystemMeta,
1811        world: UnsafeWorldCell<'world>,
1812        change_tick: Tick,
1813    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1814        // SAFETY: Upheld by caller.
1815        unsafe { T::get_param(state, system_meta, world, change_tick) }
1816            .map(If)
1817            .map_err(|mut e| {
1818                e.skipped = true;
1819                e
1820            })
1821    }
1822
1823    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1824        T::apply(state, system_meta, world);
1825    }
1826
1827    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1828        T::queue(state, system_meta, world);
1829    }
1830}
1831
1832// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1833unsafe impl<T: ReadOnlySystemParam> ReadOnlySystemParam for If<T> {}
1834
1835// SAFETY: Registers access for each element of `state`.
1836// If any one conflicts, it will panic.
1837unsafe impl<T: SystemParam> SystemParam for Vec<T> {
1838    type State = Vec<T::State>;
1839
1840    type Item<'world, 'state> = Vec<T::Item<'world, 'state>>;
1841
1842    fn init_state(_world: &mut World) -> Self::State {
1843        Vec::new()
1844    }
1845
1846    fn init_access(
1847        state: &Self::State,
1848        system_meta: &mut SystemMeta,
1849        system_access: &mut SystemAccess,
1850        world: &mut World,
1851    ) {
1852        for state in state {
1853            T::init_access(state, system_meta, system_access, world);
1854        }
1855    }
1856
1857    #[inline]
1858    unsafe fn get_param<'world, 'state>(
1859        state: &'state mut Self::State,
1860        system_meta: &SystemMeta,
1861        world: UnsafeWorldCell<'world>,
1862        change_tick: Tick,
1863    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1864        state
1865            .iter_mut()
1866            // SAFETY:
1867            // - 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.
1868            // - The caller ensures this was the world used to initialize our state, and we used that world to initialize parameter states
1869            .map(|state| unsafe { T::get_param(state, system_meta, world, change_tick) })
1870            .collect()
1871    }
1872
1873    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1874        for state in state {
1875            T::apply(state, system_meta, world);
1876        }
1877    }
1878
1879    fn queue(state: &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
1880        for state in state {
1881            T::queue(state, system_meta, world.reborrow());
1882        }
1883    }
1884}
1885
1886// SAFETY: Registers access for each element of `state`.
1887// If any one conflicts with a previous parameter,
1888// the call passing a copy of the current access will panic.
1889unsafe impl<T: SystemParam> SystemParam for ParamSet<'_, '_, Vec<T>> {
1890    type State = Vec<T::State>;
1891
1892    type Item<'world, 'state> = ParamSet<'world, 'state, Vec<T>>;
1893
1894    fn init_state(_world: &mut World) -> Self::State {
1895        Vec::new()
1896    }
1897
1898    fn init_access(
1899        state: &Self::State,
1900        system_meta: &mut SystemMeta,
1901        system_access: &mut SystemAccess,
1902        world: &mut World,
1903    ) {
1904        for state in state {
1905            // Call `init_access` on a clone of the original access set to check for conflicts
1906            let system_access_clone = &mut system_access.clone();
1907            T::init_access(state, system_meta, system_access_clone, world);
1908        }
1909        for state in state {
1910            // Pretend to add the param to the system alone to gather the new access,
1911            // then merge its access into the system.
1912            let mut param_access = SystemAccess::default();
1913            T::init_access(state, system_meta, &mut param_access, world);
1914            system_access.extend(param_access);
1915        }
1916    }
1917
1918    #[inline]
1919    unsafe fn get_param<'world, 'state>(
1920        state: &'state mut Self::State,
1921        system_meta: &SystemMeta,
1922        world: UnsafeWorldCell<'world>,
1923        change_tick: Tick,
1924    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1925        // Validate each sub-param eagerly so that the system is correctly
1926        // skipped by the executor when any sub-param is unavailable.
1927        // PERF: the sub-params will be fetched again lazily when accessed through
1928        // the ParamSet, but this is no worse than the previous
1929        // validate_param + get_param pattern.
1930        for s in state.iter_mut() {
1931            // SAFETY: Upheld by caller.
1932            drop(unsafe { T::get_param(s, system_meta, world, change_tick) }?);
1933        }
1934
1935        Ok(ParamSet {
1936            param_states: state,
1937            system_meta: system_meta.clone(),
1938            world,
1939            change_tick,
1940        })
1941    }
1942
1943    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1944        for state in state {
1945            T::apply(state, system_meta, world);
1946        }
1947    }
1948
1949    fn queue(state: &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
1950        for state in state {
1951            T::queue(state, system_meta, world.reborrow());
1952        }
1953    }
1954}
1955
1956impl<T: SystemParam> ParamSet<'_, '_, Vec<T>> {
1957    /// Accesses the parameter at the given index.
1958    /// No other parameters may be accessed while this one is active.
1959    pub fn get_mut(&mut self, index: usize) -> T::Item<'_, '_> {
1960        // SAFETY:
1961        // - We initialized the access for each parameter, so the caller ensures we have access to any world data needed by any param.
1962        //   We have mutable access to the ParamSet, so no other params in the set are active.
1963        // - 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
1964        unsafe {
1965            T::get_param(
1966                &mut self.param_states[index],
1967                &self.system_meta,
1968                self.world,
1969                self.change_tick,
1970            )
1971            .unwrap()
1972        }
1973    }
1974
1975    /// Calls a closure for each parameter in the set.
1976    pub fn for_each(&mut self, mut f: impl FnMut(T::Item<'_, '_>)) {
1977        self.param_states.iter_mut().for_each(|state| {
1978            f(
1979                // SAFETY:
1980                // - We initialized the access for each parameter, so the caller ensures we have access to any world data needed by any param.
1981                //   We have mutable access to the ParamSet, so no other params in the set are active.
1982                // - 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
1983                unsafe { T::get_param(state, &self.system_meta, self.world, self.change_tick) }
1984                    .unwrap_or_else(|err| panic!("ParamSet parameter validation failed: {err}")),
1985            );
1986        });
1987    }
1988}
1989
1990// SAFETY: Registers access for each element of `state`.
1991// If any one conflicts, it will panic.
1992unsafe impl<T: SystemParam, const N: usize> SystemParam for SmallVec<[T; N]> {
1993    type State = SmallVec<[T::State; N]>;
1994
1995    type Item<'world, 'state> = SmallVec<[T::Item<'world, 'state>; N]>;
1996
1997    fn init_state(_world: &mut World) -> Self::State {
1998        SmallVec::new()
1999    }
2000
2001    fn init_access(
2002        state: &Self::State,
2003        system_meta: &mut SystemMeta,
2004        system_access: &mut SystemAccess,
2005        world: &mut World,
2006    ) {
2007        for state in state {
2008            T::init_access(state, system_meta, system_access, world);
2009        }
2010    }
2011
2012    #[inline]
2013    unsafe fn get_param<'world, 'state>(
2014        state: &'state mut Self::State,
2015        system_meta: &SystemMeta,
2016        world: UnsafeWorldCell<'world>,
2017        change_tick: Tick,
2018    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2019        state
2020            .iter_mut()
2021            // SAFETY:
2022            // - 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.
2023            // - The caller ensures this was the world used to initialize our state, and we used that world to initialize parameter states
2024            .map(|state| unsafe { T::get_param(state, system_meta, world, change_tick) })
2025            .collect()
2026    }
2027
2028    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
2029        for state in state {
2030            T::apply(state, system_meta, world);
2031        }
2032    }
2033
2034    fn queue(state: &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
2035        for state in state {
2036            T::queue(state, system_meta, world.reborrow());
2037        }
2038    }
2039}
2040
2041macro_rules! impl_system_param_tuple {
2042    ($(#[$meta:meta])* $($param: ident),*) => {
2043        $(#[$meta])*
2044        // SAFETY: tuple consists only of ReadOnlySystemParams
2045        unsafe impl<$($param: ReadOnlySystemParam),*> ReadOnlySystemParam for ($($param,)*) {}
2046
2047        #[expect(
2048            clippy::allow_attributes,
2049            reason = "This is in a macro, and as such, the below lints may not always apply."
2050        )]
2051        #[allow(
2052            non_snake_case,
2053            reason = "Certain variable names are provided by the caller, not by us."
2054        )]
2055        #[allow(
2056            unused_variables,
2057            reason = "Zero-length tuples won't use some of the parameters."
2058        )]
2059        #[allow(clippy::unused_unit, reason = "Zero length tuple is unit.")]
2060        $(#[$meta])*
2061        // SAFETY: implementers of each `SystemParam` in the tuple have validated their impls
2062        unsafe impl<$($param: SystemParam),*> SystemParam for ($($param,)*) {
2063            type State = ($($param::State,)*);
2064            type Item<'w, 's> = ($($param::Item::<'w, 's>,)*);
2065
2066            #[inline]
2067            #[track_caller]
2068            fn init_state(world: &mut World) -> Self::State {
2069                ($($param::init_state(world),)*)
2070            }
2071
2072            fn init_access(state: &Self::State, _system_meta: &mut SystemMeta, _system_access: &mut SystemAccess, _world: &mut World) {
2073                let ($($param,)*) = state;
2074                $($param::init_access($param, _system_meta, _system_access, _world);)*
2075            }
2076
2077
2078            #[inline]
2079            fn apply(($($param,)*): &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
2080                $($param::apply($param, system_meta, world);)*
2081            }
2082
2083            #[inline]
2084            #[allow(
2085                unused_mut,
2086                reason = "The `world` parameter is unused for zero-length tuples; however, it must be mutable for other lengths of tuples."
2087            )]
2088            fn queue(($($param,)*): &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
2089                $($param::queue($param, system_meta, world.reborrow());)*
2090            }
2091
2092            #[inline]
2093            #[track_caller]
2094            unsafe fn get_param<'w, 's>(
2095                state: &'s mut Self::State,
2096                system_meta: &SystemMeta,
2097                world: UnsafeWorldCell<'w>,
2098                change_tick: Tick,
2099            ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
2100                let ($($param,)*) = state;
2101
2102                #[allow(
2103                    unused_unsafe,
2104                    reason = "Zero-length tuples won't have any params to validate."
2105                )]
2106                // SAFETY: Upheld by caller
2107                unsafe {
2108                    #[allow(
2109                        clippy::unused_unit,
2110                        reason = "Zero-length tuples won't have any params to get."
2111                    )]
2112                    Ok(($($param::get_param($param, system_meta, world, change_tick)?,)*))
2113                }
2114            }
2115        }
2116    };
2117}
2118
2119all_tuples!(
2120    #[doc(fake_variadic)]
2121    impl_system_param_tuple,
2122    0,
2123    16,
2124    P
2125);
2126
2127/// Contains type aliases for built-in [`SystemParam`]s with `'static` lifetimes.
2128/// This makes it more convenient to refer to these types in contexts where
2129/// explicit lifetime annotations are required.
2130///
2131/// Note that this is entirely safe and tracks lifetimes correctly.
2132/// This purely exists for convenience.
2133///
2134/// You can't instantiate a static `SystemParam`, you'll always end up with
2135/// `Res<'w, T>`, `ResMut<'w, T>` or `&'w T` bound to the lifetime of the provided
2136/// `&'w World`.
2137///
2138/// [`SystemParam`]: super::SystemParam
2139pub mod lifetimeless {
2140    /// A [`Query`](super::Query) with `'static` lifetimes.
2141    pub type SQuery<D, F = ()> = super::Query<'static, 'static, D, F>;
2142    /// A shorthand for writing `&'static T`.
2143    pub type Read<T> = &'static T;
2144    /// A shorthand for writing `&'static mut T`.
2145    pub type Write<T> = &'static mut T;
2146    /// A [`Res`](super::Res) with `'static` lifetimes.
2147    pub type SRes<T> = super::Res<'static, T>;
2148    /// A [`ResMut`](super::ResMut) with `'static` lifetimes.
2149    pub type SResMut<T> = super::ResMut<'static, T>;
2150    /// [`Commands`](crate::system::Commands) with `'static` lifetimes.
2151    pub type SCommands = crate::system::Commands<'static, 'static>;
2152}
2153
2154/// A helper for using system parameters in generic contexts
2155///
2156/// This type is a [`SystemParam`] adapter which always has
2157/// `Self::Item == Self` (ignoring lifetimes for brevity),
2158/// no matter the argument [`SystemParam`] (`P`) (other than
2159/// that `P` must be `'static`)
2160///
2161/// This makes it useful for having arbitrary [`SystemParam`] type arguments
2162/// to function systems, or for generic types using the [`derive@SystemParam`]
2163/// derive:
2164///
2165/// ```
2166/// # use bevy_ecs::prelude::*;
2167/// use bevy_ecs::system::{SystemParam, StaticSystemParam};
2168/// #[derive(SystemParam)]
2169/// struct GenericParam<'w,'s, T: SystemParam + 'static> {
2170///     field: StaticSystemParam<'w, 's, T>,
2171/// }
2172/// fn do_thing_generically<T: SystemParam + 'static>(t: StaticSystemParam<T>) {}
2173///
2174/// fn check_always_is_system<T: SystemParam + 'static>(){
2175///     bevy_ecs::system::assert_is_system(do_thing_generically::<T>);
2176/// }
2177/// ```
2178/// Note that in a real case you'd generally want
2179/// additional bounds on `P`, for your use of the parameter
2180/// to have a reason to be generic.
2181///
2182/// For example, using this would allow a type to be generic over
2183/// whether a resource is accessed mutably or not, with
2184/// impls being bounded on [`P: Deref<Target=MyType>`](Deref), and
2185/// [`P: DerefMut<Target=MyType>`](DerefMut) depending on whether the
2186/// method requires mutable access or not.
2187///
2188/// The method which doesn't use this type will not compile:
2189/// ```compile_fail
2190/// # use bevy_ecs::prelude::*;
2191/// # use bevy_ecs::system::{SystemParam, StaticSystemParam};
2192///
2193/// fn do_thing_generically<T: SystemParam + 'static>(t: T) {}
2194///
2195/// #[derive(SystemParam)]
2196/// struct GenericParam<'w, 's, T: SystemParam> {
2197///     field: T,
2198///     // Use the lifetimes in this type, or they will be unbound.
2199///     phantom: std::marker::PhantomData<&'w &'s ()>
2200/// }
2201/// # fn check_always_is_system<T: SystemParam + 'static>(){
2202/// #    bevy_ecs::system::assert_is_system(do_thing_generically::<T>);
2203/// # }
2204/// ```
2205pub struct StaticSystemParam<'w, 's, P: SystemParam>(SystemParamItem<'w, 's, P>);
2206
2207impl<'w, 's, P: SystemParam> Deref for StaticSystemParam<'w, 's, P> {
2208    type Target = SystemParamItem<'w, 's, P>;
2209
2210    fn deref(&self) -> &Self::Target {
2211        &self.0
2212    }
2213}
2214
2215impl<'w, 's, P: SystemParam> DerefMut for StaticSystemParam<'w, 's, P> {
2216    fn deref_mut(&mut self) -> &mut Self::Target {
2217        &mut self.0
2218    }
2219}
2220
2221impl<'w, 's, P: SystemParam> StaticSystemParam<'w, 's, P> {
2222    /// Get the value of the parameter
2223    pub fn into_inner(self) -> SystemParamItem<'w, 's, P> {
2224        self.0
2225    }
2226}
2227
2228// SAFETY: This doesn't add any more reads, and the delegated fetch confirms it
2229unsafe impl<'w, 's, P: ReadOnlySystemParam + 'static> ReadOnlySystemParam
2230    for StaticSystemParam<'w, 's, P>
2231{
2232}
2233
2234// SAFETY: all methods are just delegated to `P`'s `SystemParam` implementation
2235unsafe impl<P: SystemParam + 'static> SystemParam for StaticSystemParam<'_, '_, P> {
2236    type State = P::State;
2237    type Item<'world, 'state> = StaticSystemParam<'world, 'state, P>;
2238
2239    fn init_state(world: &mut World) -> Self::State {
2240        P::init_state(world)
2241    }
2242
2243    fn init_access(
2244        state: &Self::State,
2245        system_meta: &mut SystemMeta,
2246        system_access: &mut SystemAccess,
2247        world: &mut World,
2248    ) {
2249        P::init_access(state, system_meta, system_access, world);
2250    }
2251
2252    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
2253        P::apply(state, system_meta, world);
2254    }
2255
2256    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
2257        P::queue(state, system_meta, world);
2258    }
2259
2260    #[inline]
2261    unsafe fn get_param<'world, 'state>(
2262        state: &'state mut Self::State,
2263        system_meta: &SystemMeta,
2264        world: UnsafeWorldCell<'world>,
2265        change_tick: Tick,
2266    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2267        // SAFETY: Defer to the safety of P::SystemParam
2268        unsafe { P::get_param(state, system_meta, world, change_tick) }.map(StaticSystemParam)
2269    }
2270}
2271
2272// SAFETY: No world access.
2273unsafe impl<T: ?Sized> SystemParam for PhantomData<T> {
2274    type State = ();
2275    type Item<'world, 'state> = Self;
2276
2277    fn init_state(_world: &mut World) -> Self::State {}
2278
2279    fn init_access(
2280        _state: &Self::State,
2281        _system_meta: &mut SystemMeta,
2282        _system_access: &mut SystemAccess,
2283        _world: &mut World,
2284    ) {
2285    }
2286
2287    #[inline]
2288    unsafe fn get_param<'world, 'state>(
2289        _state: &'state mut Self::State,
2290        _system_meta: &SystemMeta,
2291        _world: UnsafeWorldCell<'world>,
2292        _change_tick: Tick,
2293    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2294        Ok(PhantomData)
2295    }
2296}
2297
2298// SAFETY: No world access.
2299unsafe impl<T: ?Sized> ReadOnlySystemParam for PhantomData<T> {}
2300
2301// SAFETY: No world access.
2302unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam
2303    for &'_ mut QueryState<D, F>
2304{
2305    type State = QueryState<D, F>;
2306    type Item<'world, 'state> = &'state mut QueryState<D, F>;
2307
2308    fn init_state(world: &mut World) -> Self::State {
2309        QueryState::new(world)
2310    }
2311
2312    fn init_access(
2313        _state: &Self::State,
2314        _system_meta: &mut SystemMeta,
2315        _system_access: &mut SystemAccess,
2316        _world: &mut World,
2317    ) {
2318    }
2319
2320    unsafe fn get_param<'world, 'state>(
2321        state: &'state mut Self::State,
2322        _system_meta: &SystemMeta,
2323        _world: UnsafeWorldCell<'world>,
2324        _change_tick: Tick,
2325    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2326        Ok(state)
2327    }
2328}
2329
2330// SAFETY: QueryState does not hold references to the world, so is safe to use as a read-only system parameter.
2331unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
2332    for &'_ mut QueryState<D, F>
2333{
2334}
2335
2336// SAFETY: No world access.
2337unsafe impl<P: SystemParam + 'static> SystemParam for &'_ mut SystemState<P> {
2338    type State = SystemState<P>;
2339    type Item<'world, 'state> = &'state mut SystemState<P>;
2340
2341    fn init_state(world: &mut World) -> Self::State {
2342        SystemState::new(world)
2343    }
2344
2345    fn init_access(
2346        _state: &Self::State,
2347        _system_meta: &mut SystemMeta,
2348        _system_access: &mut SystemAccess,
2349        _world: &mut World,
2350    ) {
2351    }
2352
2353    unsafe fn get_param<'world, 'state>(
2354        state: &'state mut Self::State,
2355        _system_meta: &SystemMeta,
2356        _world: UnsafeWorldCell<'world>,
2357        _change_tick: Tick,
2358    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2359        Ok(state)
2360    }
2361}
2362
2363// SAFETY: SystemState does not hold references to the world, so is safe to use as a read-only system parameter.
2364unsafe impl<P: SystemParam + 'static> ReadOnlySystemParam for &'_ mut SystemState<P> {}
2365
2366/// A [`SystemParam`] with a type that can be configured at runtime.
2367///
2368/// To be useful, this must be configured using a [`DynParamBuilder`](crate::system::DynParamBuilder) to build the system using a [`SystemParamBuilder`](crate::prelude::SystemParamBuilder).
2369///
2370/// # Examples
2371///
2372/// ```
2373/// # use bevy_ecs::{prelude::*, system::*};
2374/// #
2375/// # #[derive(Default, Resource)]
2376/// # struct A;
2377/// #
2378/// # #[derive(Default, Resource)]
2379/// # struct B;
2380/// #
2381/// # let mut world = World::new();
2382/// # world.init_resource::<A>();
2383/// # world.init_resource::<B>();
2384/// #
2385/// // If the inner parameter doesn't require any special building, use `ParamBuilder`.
2386/// // Either specify the type parameter on `DynParamBuilder::new()` ...
2387/// let system = (DynParamBuilder::new::<Res<A>>(ParamBuilder),)
2388///     .build_state(&mut world)
2389///     .build_system(expects_res_a);
2390/// # world.run_system_once(system);
2391///
2392/// // ... or use a factory method on `ParamBuilder` that returns a specific type.
2393/// let system = (DynParamBuilder::new(ParamBuilder::resource::<A>()),)
2394///     .build_state(&mut world)
2395///     .build_system(expects_res_a);
2396/// # world.run_system_once(system);
2397///
2398/// fn expects_res_a(mut param: DynSystemParam) {
2399///     // Use the `downcast` methods to retrieve the inner parameter.
2400///     // They will return `None` if the type does not match.
2401///     assert!(param.is::<Res<A>>());
2402///     assert!(!param.is::<Res<B>>());
2403///     assert!(param.downcast_mut::<Res<B>>().is_none());
2404///     let res = param.downcast_mut::<Res<A>>().unwrap();
2405///     // The type parameter can be left out if it can be determined from use.
2406///     let res: Res<A> = param.downcast().unwrap();
2407/// }
2408///
2409/// let system = (
2410///     // If the inner parameter also requires building,
2411///     // pass the appropriate `SystemParamBuilder`.
2412///     DynParamBuilder::new(LocalBuilder(10usize)),
2413///     // `DynSystemParam` is just an ordinary `SystemParam`,
2414///     // and can be combined with other parameters as usual!
2415///     ParamBuilder::query(),
2416/// )
2417///     .build_state(&mut world)
2418///     .build_system(|param: DynSystemParam, query: Query<()>| {
2419///         let local: Local<usize> = param.downcast::<Local<usize>>().unwrap();
2420///         assert_eq!(*local, 10);
2421///     });
2422/// # world.run_system_once(system);
2423/// ```
2424pub struct DynSystemParam<'w, 's> {
2425    /// A `ParamState<T>` wrapping the state for the underlying system param.
2426    state: &'s mut dyn Any,
2427    world: UnsafeWorldCell<'w>,
2428    system_meta: SystemMeta,
2429    change_tick: Tick,
2430}
2431
2432impl<'w, 's> DynSystemParam<'w, 's> {
2433    /// # Safety
2434    /// - `state` must be a `ParamState<T>` for some inner `T: SystemParam`.
2435    /// - The passed [`UnsafeWorldCell`] must have access to any world data registered
2436    ///   in [`init_state`](SystemParam::init_state) for the inner system param.
2437    /// - `world` must be the same `World` that was used to initialize
2438    ///   [`state`](SystemParam::init_state) for the inner system param.
2439    unsafe fn new(
2440        state: &'s mut dyn Any,
2441        world: UnsafeWorldCell<'w>,
2442        system_meta: SystemMeta,
2443        change_tick: Tick,
2444    ) -> Self {
2445        Self {
2446            state,
2447            world,
2448            system_meta,
2449            change_tick,
2450        }
2451    }
2452
2453    /// Returns `true` if the inner system param is the same as `T`.
2454    pub fn is<T: SystemParam>(&self) -> bool
2455    // See downcast() function for an explanation of the where clause
2456    where
2457        T::Item<'static, 'static>: SystemParam<Item<'w, 's> = T> + 'static,
2458    {
2459        self.state.is::<ParamState<T::Item<'static, 'static>>>()
2460    }
2461
2462    /// Returns the inner system param if it is the correct type.
2463    /// This consumes the dyn param, so the returned param can have its original world and state lifetimes.
2464    pub fn downcast<T: SystemParam>(self) -> Option<T>
2465    // See downcast() function for an explanation of the where clause
2466    where
2467        T::Item<'static, 'static>: SystemParam<Item<'w, 's> = T> + 'static,
2468    {
2469        // SAFETY:
2470        // - `DynSystemParam::new()` ensures `state` is a `ParamState<T>`, that the world matches,
2471        //   and that it has access required by the inner system param.
2472        // - This consumes the `DynSystemParam`, so it is the only use of `world` with this access and it is available for `'w`.
2473        unsafe { downcast::<T>(self.state, &self.system_meta, self.world, self.change_tick) }
2474    }
2475
2476    /// Returns the inner system parameter if it is the correct type.
2477    /// This borrows the dyn param, so the returned param is only valid for the duration of that borrow.
2478    pub fn downcast_mut<'a, T: SystemParam>(&'a mut self) -> Option<T>
2479    // See downcast() function for an explanation of the where clause
2480    where
2481        T::Item<'static, 'static>: SystemParam<Item<'a, 'a> = T> + 'static,
2482    {
2483        // SAFETY:
2484        // - `DynSystemParam::new()` ensures `state` is a `ParamState<T>`, that the world matches,
2485        //   and that it has access required by the inner system param.
2486        // - This exclusively borrows the `DynSystemParam` for `'_`, so it is the only use of `world` with this access for `'_`.
2487        unsafe { downcast::<T>(self.state, &self.system_meta, self.world, self.change_tick) }
2488    }
2489
2490    /// Returns the inner system parameter if it is the correct type.
2491    /// This borrows the dyn param, so the returned param is only valid for the duration of that borrow,
2492    /// but since it only performs read access it can keep the original world lifetime.
2493    /// This can be useful with methods like [`Query::iter_inner()`] or [`Res::into_inner()`]
2494    /// to obtain references with the original world lifetime.
2495    pub fn downcast_mut_inner<'a, T: ReadOnlySystemParam>(&'a mut self) -> Option<T>
2496    // See downcast() function for an explanation of the where clause
2497    where
2498        T::Item<'static, 'static>: SystemParam<Item<'w, 'a> = T> + 'static,
2499    {
2500        // SAFETY:
2501        // - `DynSystemParam::new()` ensures `state` is a `ParamState<T>`, that the world matches,
2502        //   and that it has access required by the inner system param.
2503        // - The inner system param only performs read access, so it's safe to copy that access for the full `'w` lifetime.
2504        unsafe { downcast::<T>(self.state, &self.system_meta, self.world, self.change_tick) }
2505    }
2506}
2507
2508/// # Safety
2509/// - `state` must be a `ParamState<T>` for some inner `T: SystemParam`.
2510/// - The passed [`UnsafeWorldCell`] must have access to any world data registered
2511///   in [`init_state`](SystemParam::init_state) for the inner system param.
2512/// - `world` must be the same `World` that was used to initialize
2513///   [`state`](SystemParam::init_state) for the inner system param.
2514unsafe fn downcast<'w, 's, T: SystemParam>(
2515    state: &'s mut dyn Any,
2516    system_meta: &SystemMeta,
2517    world: UnsafeWorldCell<'w>,
2518    change_tick: Tick,
2519) -> Option<T>
2520// We need a 'static version of the SystemParam to use with `Any::downcast_mut()`,
2521// and we need a <'w, 's> version to actually return.
2522// The type parameter T must be the one we return in order to get type inference from the return value.
2523// So we use `T::Item<'static, 'static>` as the 'static version, and require that it be 'static.
2524// That means the return value will be T::Item<'static, 'static>::Item<'w, 's>,
2525// so we constrain that to be equal to T.
2526// Every actual `SystemParam` implementation has `T::Item == T` up to lifetimes,
2527// so they should all work with this constraint.
2528where
2529    T::Item<'static, 'static>: SystemParam<Item<'w, 's> = T> + 'static,
2530{
2531    state
2532        .downcast_mut::<ParamState<T::Item<'static, 'static>>>()
2533        .and_then(|state| {
2534            // SAFETY:
2535            // - The caller ensures the world has access for the underlying system param,
2536            //   and since the downcast succeeded, the underlying system param is T.
2537            // - The caller ensures the `world` matches.
2538            unsafe { T::Item::get_param(&mut state.0, system_meta, world, change_tick) }.ok()
2539        })
2540}
2541
2542/// The [`SystemParam::State`] for a [`DynSystemParam`].
2543pub struct DynSystemParamState(Box<dyn DynParamState>);
2544
2545impl DynSystemParamState {
2546    pub(crate) fn new<T: SystemParam + 'static>(state: T::State) -> Self {
2547        Self(Box::new(ParamState::<T>(state)))
2548    }
2549}
2550
2551/// Allows a [`SystemParam::State`] to be used as a trait object for implementing [`DynSystemParam`].
2552trait DynParamState: Sync + Send + Any {
2553    /// Applies any deferred mutations stored in this [`SystemParam`]'s state.
2554    /// This is used to apply [`Commands`] during [`ApplyDeferred`](crate::prelude::ApplyDeferred).
2555    ///
2556    /// [`Commands`]: crate::prelude::Commands
2557    fn apply(&mut self, system_meta: &SystemMeta, world: &mut World);
2558
2559    /// Queues any deferred mutations to be applied at the next [`ApplyDeferred`](crate::prelude::ApplyDeferred).
2560    fn queue(&mut self, system_meta: &SystemMeta, world: DeferredWorld);
2561
2562    /// Registers any [`World`] access used by this [`SystemParam`]
2563    fn init_access(
2564        &self,
2565        system_meta: &mut SystemMeta,
2566        system_access: &mut SystemAccess,
2567        world: &mut World,
2568    );
2569
2570    /// Validates the inner parameter by calling [`SystemParam::get_param`] and discarding the value.
2571    ///
2572    /// # Safety
2573    /// Refer to [`SystemParam::get_param`].
2574    unsafe fn validate(
2575        &mut self,
2576        system_meta: &SystemMeta,
2577        world: UnsafeWorldCell,
2578        change_tick: Tick,
2579    ) -> Result<(), SystemParamValidationError>;
2580}
2581
2582/// A wrapper around a [`SystemParam::State`] that can be used as a trait object in a [`DynSystemParam`].
2583struct ParamState<T: SystemParam>(T::State);
2584
2585impl<T: SystemParam + 'static> DynParamState for ParamState<T> {
2586    fn apply(&mut self, system_meta: &SystemMeta, world: &mut World) {
2587        T::apply(&mut self.0, system_meta, world);
2588    }
2589
2590    fn queue(&mut self, system_meta: &SystemMeta, world: DeferredWorld) {
2591        T::queue(&mut self.0, system_meta, world);
2592    }
2593
2594    fn init_access(
2595        &self,
2596        system_meta: &mut SystemMeta,
2597        system_access: &mut SystemAccess,
2598        world: &mut World,
2599    ) {
2600        T::init_access(&self.0, system_meta, system_access, world);
2601    }
2602
2603    unsafe fn validate(
2604        &mut self,
2605        system_meta: &SystemMeta,
2606        world: UnsafeWorldCell,
2607        change_tick: Tick,
2608    ) -> Result<(), SystemParamValidationError> {
2609        // SAFETY: Upheld by caller.
2610        unsafe { T::get_param(&mut self.0, system_meta, world, change_tick) }.map(drop)
2611    }
2612}
2613
2614// SAFETY: Delegates to the wrapped parameter, which ensures the safety requirements are met
2615unsafe impl SystemParam for DynSystemParam<'_, '_> {
2616    type State = DynSystemParamState;
2617
2618    type Item<'world, 'state> = DynSystemParam<'world, 'state>;
2619
2620    fn init_state(_world: &mut World) -> Self::State {
2621        DynSystemParamState::new::<()>(())
2622    }
2623
2624    fn init_access(
2625        state: &Self::State,
2626        system_meta: &mut SystemMeta,
2627        system_access: &mut SystemAccess,
2628        world: &mut World,
2629    ) {
2630        state.0.init_access(system_meta, system_access, world);
2631    }
2632
2633    #[inline]
2634    unsafe fn get_param<'world, 'state>(
2635        state: &'state mut Self::State,
2636        system_meta: &SystemMeta,
2637        world: UnsafeWorldCell<'world>,
2638        change_tick: Tick,
2639    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2640        // Validate the inner parameter eagerly so that systems using DynSystemParam
2641        // are correctly skipped by the executor when the inner param is unavailable.
2642        // SAFETY: Upheld by caller.
2643        unsafe { state.0.validate(system_meta, world, change_tick) }?;
2644        // SAFETY:
2645        // - `state.0` is a boxed `ParamState<T>`.
2646        // - `init_access` calls `DynParamState::init_access`, which calls `init_access` on the inner parameter,
2647        //   so the caller ensures the world has the necessary access.
2648        // - The caller ensures that the provided world is the same and has the required access.
2649        Ok(unsafe {
2650            DynSystemParam::new(state.0.as_mut(), world, system_meta.clone(), change_tick)
2651        })
2652    }
2653
2654    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
2655        state.0.apply(system_meta, world);
2656    }
2657
2658    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
2659        state.0.queue(system_meta, world);
2660    }
2661}
2662
2663// SAFETY: Resource ComponentId access is applied to the access. If this FilteredResources
2664// conflicts with any prior access, a panic will occur.
2665#[expect(deprecated, reason = "`FilteredResources` will be removed.")]
2666unsafe impl SystemParam for FilteredResources<'_, '_> {
2667    type State = Access;
2668
2669    type Item<'world, 'state> = FilteredResources<'world, 'state>;
2670
2671    fn init_state(_world: &mut World) -> Self::State {
2672        Access::new()
2673    }
2674
2675    fn init_access(
2676        access: &Self::State,
2677        system_meta: &mut SystemMeta,
2678        system_access: &mut SystemAccess,
2679        world: &mut World,
2680    ) {
2681        let mut filtered_access = FilteredAccess::default();
2682        filtered_access.access_mut().extend(access);
2683        filtered_access.and_with(IS_RESOURCE);
2684
2685        if let Err(conflicts) = system_access.try_add(filtered_access) {
2686            let accesses = conflicts.format_conflict_list(world.into());
2687            let system_name = &system_meta.name;
2688            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");
2689        }
2690    }
2691
2692    unsafe fn get_param<'world, 'state>(
2693        state: &'state mut Self::State,
2694        system_meta: &SystemMeta,
2695        world: UnsafeWorldCell<'world>,
2696        change_tick: Tick,
2697    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2698        // SAFETY: The caller ensures that `world` has access to anything registered in `init_access`,
2699        // and we registered all resource access in `state``.
2700        Ok(unsafe { FilteredResources::new(world, state, system_meta.last_run, change_tick) })
2701    }
2702}
2703
2704// SAFETY: FilteredResources only reads resources.
2705#[expect(deprecated, reason = "`FilteredResources` will be removed.")]
2706unsafe impl ReadOnlySystemParam for FilteredResources<'_, '_> {}
2707
2708// SAFETY: Resource ComponentId access is applied to the access. If this FilteredResourcesMut
2709// conflicts with any prior access, a panic will occur.
2710#[expect(deprecated, reason = "`FilteredResourcesMut` will be removed.")]
2711unsafe impl SystemParam for FilteredResourcesMut<'_, '_> {
2712    type State = Access;
2713
2714    type Item<'world, 'state> = FilteredResourcesMut<'world, 'state>;
2715
2716    fn init_state(_world: &mut World) -> Self::State {
2717        Access::new()
2718    }
2719
2720    fn init_access(
2721        access: &Self::State,
2722        system_meta: &mut SystemMeta,
2723        system_access: &mut SystemAccess,
2724        world: &mut World,
2725    ) {
2726        let mut filtered_access = FilteredAccess::default();
2727        filtered_access.access_mut().extend(access);
2728        filtered_access.and_with(IS_RESOURCE);
2729
2730        if let Err(conflicts) = system_access.try_add(filtered_access) {
2731            let accesses = conflicts.format_conflict_list(world.into());
2732            let system_name = &system_meta.name;
2733            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");
2734        }
2735    }
2736
2737    unsafe fn get_param<'world, 'state>(
2738        state: &'state mut Self::State,
2739        system_meta: &SystemMeta,
2740        world: UnsafeWorldCell<'world>,
2741        change_tick: Tick,
2742    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2743        // SAFETY: The caller ensures that `world` has access to anything registered in `init_access`,
2744        // and we registered all resource access in `state``.
2745        Ok(unsafe { FilteredResourcesMut::new(world, state, system_meta.last_run, change_tick) })
2746    }
2747}
2748
2749/// An error that occurs when a system parameter is not valid,
2750/// used by system executors to determine what to do with a system.
2751///
2752/// Returned as an error from [`SystemParam::get_param`],
2753/// and handled using the unified error handling mechanisms defined in [`bevy_ecs::error`].
2754#[derive(Debug, PartialEq, Eq, Clone, Error)]
2755pub struct SystemParamValidationError {
2756    /// Whether the system should be skipped.
2757    ///
2758    /// If `false`, the error should be handled.
2759    /// By default, this will result in a panic. See [`error`](`crate::error`) for more information.
2760    ///
2761    /// This is the default behavior, and is suitable for system params that should *always* be valid,
2762    /// either because sensible fallback behavior exists (like [`Query`]) or because
2763    /// failures in validation should be considered a bug in the user's logic that must be immediately addressed (like [`Res`]).
2764    ///
2765    /// If `true`, the system should be skipped.
2766    /// This is set by wrapping the system param in [`If`],
2767    /// and indicates that the system is intended to only operate in certain application states.
2768    pub skipped: bool,
2769
2770    /// A message describing the validation error.
2771    pub message: Cow<'static, str>,
2772
2773    /// A string identifying the invalid parameter.
2774    /// This is usually the type name of the parameter.
2775    pub param: DebugName,
2776
2777    /// A string identifying the field within a parameter using `#[derive(SystemParam)]`.
2778    /// This will be an empty string for other parameters.
2779    ///
2780    /// This will be printed after `param` in the `Display` impl, and should include a `::` prefix if non-empty.
2781    pub field: Cow<'static, str>,
2782}
2783
2784impl SystemParamValidationError {
2785    /// Constructs a `SystemParamValidationError` that skips the system.
2786    /// The parameter name is initialized to the type name of `T`, so a `SystemParam` should usually pass `Self`.
2787    pub fn skipped<T>(message: impl Into<Cow<'static, str>>) -> Self {
2788        Self::new::<T>(true, message, Cow::Borrowed(""))
2789    }
2790
2791    /// Constructs a `SystemParamValidationError` for an invalid parameter that should be treated as an error.
2792    /// The parameter name is initialized to the type name of `T`, so a `SystemParam` should usually pass `Self`.
2793    pub fn invalid<T>(message: impl Into<Cow<'static, str>>) -> Self {
2794        Self::new::<T>(false, message, Cow::Borrowed(""))
2795    }
2796
2797    /// Constructs a `SystemParamValidationError` for an invalid parameter.
2798    /// The parameter name is initialized to the type name of `T`, so a `SystemParam` should usually pass `Self`.
2799    pub fn new<T>(
2800        skipped: bool,
2801        message: impl Into<Cow<'static, str>>,
2802        field: impl Into<Cow<'static, str>>,
2803    ) -> Self {
2804        Self {
2805            skipped,
2806            message: message.into(),
2807            param: DebugName::type_name::<T>(),
2808            field: field.into(),
2809        }
2810    }
2811
2812    pub(crate) const EMPTY: Self = Self {
2813        skipped: false,
2814        message: Cow::Borrowed(""),
2815        param: DebugName::borrowed(""),
2816        field: Cow::Borrowed(""),
2817    };
2818}
2819
2820impl Display for SystemParamValidationError {
2821    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
2822        write!(
2823            fmt,
2824            "Parameter `{}{}` failed validation: {}",
2825            self.param.shortname(),
2826            self.field,
2827            self.message
2828        )?;
2829        if !self.skipped {
2830            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.")?;
2831        }
2832        Ok(())
2833    }
2834}
2835
2836#[cfg(test)]
2837mod tests {
2838    use bevy_ecs_macros::Component;
2839
2840    use super::*;
2841    use crate::query::Without;
2842    use crate::resource::IsResource;
2843    use crate::schedule::Schedule;
2844    use crate::system::{assert_is_system, Commands, IntoSystem, System};
2845    use crate::world::EntityMut;
2846    use core::cell::RefCell;
2847
2848    #[test]
2849    #[should_panic]
2850    fn non_send_alias() {
2851        #[derive(Resource)]
2852        struct A(usize);
2853        fn my_system(mut res0: NonSendMut<A>, mut res1: NonSendMut<A>) {
2854            res0.0 += 1;
2855            res1.0 += 1;
2856        }
2857        let mut world = World::new();
2858        world.insert_non_send(A(42));
2859        let mut schedule = Schedule::default();
2860        schedule.add_systems(my_system);
2861        schedule.run(&mut world);
2862    }
2863
2864    #[test]
2865    #[should_panic]
2866    fn non_send_and_entities() {
2867        #[derive(Resource)]
2868        struct A(usize);
2869        fn my_system(mut ns: NonSendMut<A>, _: Query<EntityMut>) {
2870            ns.0 += 1;
2871        }
2872        assert_is_system(my_system);
2873    }
2874
2875    #[test]
2876    #[should_panic]
2877    fn res_and_entities() {
2878        #[derive(Resource)]
2879        struct A(usize);
2880        fn my_system(mut res: ResMut<A>, _: Query<EntityMut>) {
2881            res.0 += 1;
2882        }
2883        assert_is_system(my_system);
2884    }
2885
2886    #[test]
2887    fn res_and_entities_filtered() {
2888        #[derive(Resource)]
2889        struct A(usize);
2890        fn res_system(mut res: ResMut<A>, _: Query<EntityMut, Without<IsResource>>) {
2891            res.0 += 1;
2892        }
2893        assert_is_system(res_system);
2894
2895        fn non_send_system(mut ns: NonSendMut<A>, _: Query<EntityMut, Without<A>>) {
2896            ns.0 += 1;
2897        }
2898
2899        assert_is_system(non_send_system);
2900    }
2901
2902    // Compile test for https://github.com/bevyengine/bevy/pull/2838.
2903    #[test]
2904    fn system_param_generic_bounds() {
2905        #[derive(SystemParam)]
2906        pub struct SpecialQuery<
2907            'w,
2908            's,
2909            D: QueryData + Send + Sync + 'static,
2910            F: QueryFilter + Send + Sync + 'static = (),
2911        > {
2912            _query: Query<'w, 's, D, F>,
2913        }
2914
2915        fn my_system(_: SpecialQuery<(), ()>) {}
2916        assert_is_system(my_system);
2917    }
2918
2919    // Compile tests for https://github.com/bevyengine/bevy/pull/6694.
2920    #[test]
2921    fn system_param_flexibility() {
2922        #[derive(SystemParam)]
2923        pub struct SpecialRes<'w, T: Resource> {
2924            _res: Res<'w, T>,
2925        }
2926
2927        #[derive(SystemParam)]
2928        pub struct SpecialLocal<'s, T: FromWorld + Send + 'static> {
2929            _local: Local<'s, T>,
2930        }
2931
2932        #[derive(Resource)]
2933        struct R;
2934
2935        fn my_system(_: SpecialRes<R>, _: SpecialLocal<u32>) {}
2936        assert_is_system(my_system);
2937    }
2938
2939    #[derive(Resource)]
2940    pub struct R<const I: usize>;
2941
2942    // Compile test for https://github.com/bevyengine/bevy/pull/7001.
2943    #[test]
2944    fn system_param_const_generics() {
2945        #[expect(
2946            dead_code,
2947            reason = "This struct is used to ensure that const generics are supported as a SystemParam; thus, the inner value never needs to be read."
2948        )]
2949        #[derive(SystemParam)]
2950        pub struct ConstGenericParam<'w, const I: usize>(Res<'w, R<I>>);
2951
2952        fn my_system(_: ConstGenericParam<0>, _: ConstGenericParam<1000>) {}
2953        assert_is_system(my_system);
2954    }
2955
2956    // Compile test for https://github.com/bevyengine/bevy/pull/6867.
2957    #[test]
2958    fn system_param_field_limit() {
2959        #[derive(SystemParam)]
2960        pub struct LongParam<'w> {
2961            // Each field should be a distinct type so there will
2962            // be an error if the derive messes up the field order.
2963            _r0: Res<'w, R<0>>,
2964            _r1: Res<'w, R<1>>,
2965            _r2: Res<'w, R<2>>,
2966            _r3: Res<'w, R<3>>,
2967            _r4: Res<'w, R<4>>,
2968            _r5: Res<'w, R<5>>,
2969            _r6: Res<'w, R<6>>,
2970            _r7: Res<'w, R<7>>,
2971            _r8: Res<'w, R<8>>,
2972            _r9: Res<'w, R<9>>,
2973            _r10: Res<'w, R<10>>,
2974            _r11: Res<'w, R<11>>,
2975            _r12: Res<'w, R<12>>,
2976            _r13: Res<'w, R<13>>,
2977            _r14: Res<'w, R<14>>,
2978            _r15: Res<'w, R<15>>,
2979            _r16: Res<'w, R<16>>,
2980        }
2981
2982        fn long_system(_: LongParam) {}
2983        assert_is_system(long_system);
2984    }
2985
2986    // Compile test for https://github.com/bevyengine/bevy/pull/6919.
2987    // Regression test for https://github.com/bevyengine/bevy/issues/7447.
2988    #[test]
2989    fn system_param_phantom_data() {
2990        #[derive(SystemParam)]
2991        struct PhantomParam<'w, T: Resource, Marker: 'static> {
2992            _foo: Res<'w, T>,
2993            marker: PhantomData<&'w Marker>,
2994        }
2995
2996        fn my_system(_: PhantomParam<R<0>, ()>) {}
2997        assert_is_system(my_system);
2998    }
2999
3000    // Compile tests for https://github.com/bevyengine/bevy/pull/6957.
3001    #[test]
3002    fn system_param_struct_variants() {
3003        #[derive(SystemParam)]
3004        pub struct UnitParam;
3005
3006        #[expect(
3007            dead_code,
3008            reason = "This struct is used to ensure that tuple structs are supported as a SystemParam; thus, the inner values never need to be read."
3009        )]
3010        #[derive(SystemParam)]
3011        pub struct TupleParam<'w, 's, R: Resource, L: FromWorld + Send + 'static>(
3012            Res<'w, R>,
3013            Local<'s, L>,
3014        );
3015
3016        fn my_system(_: UnitParam, _: TupleParam<R<0>, u32>) {}
3017        assert_is_system(my_system);
3018    }
3019
3020    // Regression test for https://github.com/bevyengine/bevy/issues/4200.
3021    #[test]
3022    fn system_param_private_fields() {
3023        #[derive(Resource)]
3024        struct PrivateResource;
3025
3026        #[expect(
3027            dead_code,
3028            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."
3029        )]
3030        #[derive(SystemParam)]
3031        pub struct EncapsulatedParam<'w>(Res<'w, PrivateResource>);
3032
3033        fn my_system(_: EncapsulatedParam) {}
3034        assert_is_system(my_system);
3035    }
3036
3037    // Regression test for https://github.com/bevyengine/bevy/issues/7103.
3038    #[test]
3039    fn system_param_where_clause() {
3040        #[derive(SystemParam)]
3041        pub struct WhereParam<'w, 's, D>
3042        where
3043            D: 'static + QueryData,
3044        {
3045            _q: Query<'w, 's, D, ()>,
3046        }
3047
3048        fn my_system(_: WhereParam<()>) {}
3049        assert_is_system(my_system);
3050    }
3051
3052    // Regression test for https://github.com/bevyengine/bevy/issues/1727.
3053    #[test]
3054    fn system_param_name_collision() {
3055        #[derive(Resource)]
3056        pub struct FetchState;
3057
3058        #[derive(SystemParam)]
3059        pub struct Collide<'w> {
3060            _x: Res<'w, FetchState>,
3061        }
3062
3063        fn my_system(_: Collide) {}
3064        assert_is_system(my_system);
3065    }
3066
3067    // Regression test for https://github.com/bevyengine/bevy/issues/8192.
3068    #[test]
3069    fn system_param_invariant_lifetime() {
3070        #[derive(SystemParam)]
3071        pub struct InvariantParam<'w, 's> {
3072            _set: ParamSet<'w, 's, (Query<'w, 's, ()>,)>,
3073        }
3074
3075        fn my_system(_: InvariantParam) {}
3076        assert_is_system(my_system);
3077    }
3078
3079    // Compile test for https://github.com/bevyengine/bevy/pull/9589.
3080    #[test]
3081    fn non_sync_local() {
3082        fn non_sync_system(cell: Local<RefCell<u8>>) {
3083            assert_eq!(*cell.borrow(), 0);
3084        }
3085
3086        let mut world = World::new();
3087        let mut schedule = Schedule::default();
3088        schedule.add_systems(non_sync_system);
3089        schedule.run(&mut world);
3090    }
3091
3092    // Regression test for https://github.com/bevyengine/bevy/issues/10207.
3093    #[test]
3094    fn param_set_non_send_first() {
3095        fn non_send_param_set(mut p: ParamSet<(NonSend<*mut u8>, ())>) {
3096            let _ = p.p0();
3097            p.p1();
3098        }
3099
3100        let mut world = World::new();
3101        world.insert_non_send(core::ptr::null_mut::<u8>());
3102        let mut schedule = Schedule::default();
3103        schedule.add_systems((non_send_param_set, non_send_param_set, non_send_param_set));
3104        schedule.run(&mut world);
3105    }
3106
3107    // Regression test for https://github.com/bevyengine/bevy/issues/10207.
3108    #[test]
3109    fn param_set_non_send_second() {
3110        fn non_send_param_set(mut p: ParamSet<((), NonSendMut<*mut u8>)>) {
3111            p.p0();
3112            let _ = p.p1();
3113        }
3114
3115        let mut world = World::new();
3116        world.insert_non_send(core::ptr::null_mut::<u8>());
3117        let mut schedule = Schedule::default();
3118        schedule.add_systems((non_send_param_set, non_send_param_set, non_send_param_set));
3119        schedule.run(&mut world);
3120    }
3121
3122    fn _dyn_system_param_type_inference(mut p: DynSystemParam) {
3123        // Make sure the downcast() methods are able to infer their type parameters from the use of the return type.
3124        // This is just a compilation test, so there is nothing to run.
3125        let _query: Query<()> = p.downcast_mut().unwrap();
3126        let _query: Query<()> = p.downcast_mut_inner().unwrap();
3127        let _query: Query<()> = p.downcast().unwrap();
3128    }
3129
3130    #[test]
3131    #[should_panic]
3132    fn missing_resource_error() {
3133        #[derive(Resource)]
3134        pub struct MissingResource;
3135
3136        let mut schedule = Schedule::default();
3137        schedule.add_systems(res_system);
3138        let mut world = World::new();
3139        schedule.run(&mut world);
3140
3141        fn res_system(_: Res<MissingResource>) {}
3142    }
3143
3144    #[test]
3145    #[should_panic]
3146    fn missing_message_error() {
3147        use crate::prelude::{Message, MessageReader};
3148
3149        #[derive(Message)]
3150        pub struct MissingEvent;
3151
3152        let mut schedule = Schedule::default();
3153        schedule.add_systems(message_system);
3154        let mut world = World::new();
3155        schedule.run(&mut world);
3156
3157        fn message_system(_: MessageReader<MissingEvent>) {}
3158    }
3159
3160    #[test]
3161    fn test_exclusive_system_params() {
3162        #[derive(Resource, Default)]
3163        struct Res {
3164            test_value: u32,
3165        }
3166
3167        fn my_system(world: &mut World, mut local: Local<u32>, _phantom: PhantomData<Vec<u32>>) {
3168            assert_eq!(world.resource::<Res>().test_value, *local);
3169            *local += 1;
3170            world.resource_mut::<Res>().test_value += 1;
3171        }
3172
3173        let mut schedule = Schedule::default();
3174        schedule.add_systems(my_system);
3175
3176        let mut world = World::default();
3177        world.init_resource::<Res>();
3178
3179        schedule.run(&mut world);
3180        schedule.run(&mut world);
3181
3182        assert_eq!(2, world.get_resource::<Res>().unwrap().test_value);
3183    }
3184
3185    #[test]
3186    #[should_panic(expected = "World")]
3187    fn mutable_world_conflicts_with_commands_first() {
3188        fn system(_: Commands, _: &mut World) {}
3189        assert_is_system(system);
3190    }
3191
3192    #[test]
3193    #[should_panic(expected = "Entities")]
3194    fn mutable_world_conflicts_with_commands_second() {
3195        fn system(_: &mut World, _: Commands) {}
3196        assert_is_system(system);
3197    }
3198
3199    #[test]
3200    #[should_panic(expected = "World")]
3201    fn mutable_world_conflicts_with_entities_first() {
3202        fn system(_: &Entities, _: &mut World) {}
3203        assert_is_system(system);
3204    }
3205
3206    #[test]
3207    #[should_panic(expected = "Entities")]
3208    fn mutable_world_conflicts_with_entities_second() {
3209        fn system(_: &mut World, _: &Entities) {}
3210        assert_is_system(system);
3211    }
3212
3213    #[test]
3214    #[should_panic(expected = "Archetypes")]
3215    fn mutable_world_conflicts_with_archetypes() {
3216        fn system(_: &mut World, _: &Archetypes) {}
3217        assert_is_system(system);
3218    }
3219
3220    #[test]
3221    #[should_panic(expected = "Components")]
3222    fn mutable_world_conflicts_with_components() {
3223        fn system(_: &mut World, _: &Components) {}
3224        assert_is_system(system);
3225    }
3226
3227    #[test]
3228    #[should_panic(expected = "EntityAllocator")]
3229    fn mutable_world_conflicts_with_entity_allocator() {
3230        fn system(_: &mut World, _: &EntityAllocator) {}
3231        assert_is_system(system);
3232    }
3233
3234    #[test]
3235    #[should_panic(expected = "Bundles")]
3236    fn mutable_world_conflicts_with_bundles() {
3237        fn system(_: &mut World, _: &Bundles) {}
3238        assert_is_system(system);
3239    }
3240
3241    #[test]
3242    #[should_panic(expected = "World")]
3243    fn mutable_world_conflicts_with_immutable_world() {
3244        fn system(_: &mut World, _: &World) {}
3245        assert_is_system(system);
3246    }
3247
3248    #[test]
3249    #[should_panic(expected = "DeferredWorld")]
3250    fn mutable_world_conflicts_with_deferred_world() {
3251        fn system(_: &mut World, _: DeferredWorld) {}
3252        assert_is_system(system);
3253    }
3254
3255    #[test]
3256    fn mutable_world_with_query_and_system_state_works() {
3257        fn system(_: &mut World, _: &mut QueryState<()>, _: &mut SystemState<()>) {}
3258        assert_is_system(system);
3259    }
3260
3261    #[test]
3262    fn mutable_world_param_set_works() {
3263        fn system(_: ParamSet<(&mut World, &mut World, &Entities)>) {}
3264        assert_is_system(system);
3265    }
3266
3267    #[test]
3268    #[should_panic(expected = "World")]
3269    fn mutable_world_param_set_conflicts_outside() {
3270        fn system(_: &Entities, _: ParamSet<(&mut World, &Entities)>) {}
3271        assert_is_system(system);
3272    }
3273
3274    #[test]
3275    #[should_panic(expected = "Entities")]
3276    fn mutable_world_param_set_conflicts_outside_reverse() {
3277        fn system(_: ParamSet<(&mut World, &Entities)>, _: &Entities) {}
3278        assert_is_system(system);
3279    }
3280
3281    #[test]
3282    #[should_panic(expected = "Entities")]
3283    fn mutable_world_conflicts_with_optional_entities() {
3284        fn system(_: &mut World, _: Option<&Entities>) {}
3285        assert_is_system(system);
3286    }
3287
3288    #[test]
3289    #[should_panic(expected = "error[B0002]")]
3290    fn mutable_world_conflicts_with_optional_query() {
3291        #[derive(Component)]
3292        struct A;
3293        fn system(_: &mut World, _: Option<Query<&mut A>>) {}
3294        assert_is_system(system);
3295    }
3296
3297    #[test]
3298    #[should_panic(expected = "error[B0002]")]
3299    fn mutable_world_conflicts_with_query() {
3300        #[derive(Component)]
3301        struct A;
3302        fn system(_: &mut World, _: Query<&mut A>) {}
3303        assert_is_system(system);
3304    }
3305
3306    #[test]
3307    #[should_panic(expected = "error[B0002]")]
3308    fn mutable_world_conflicts_with_empty_query() {
3309        fn system(_: &mut World, _: Query<()>) {}
3310        assert_is_system(system);
3311    }
3312
3313    #[test]
3314    fn metadata_readers_work() {
3315        fn system1(
3316            _: &World,
3317            _: &Entities,
3318            _: &Archetypes,
3319            _: &Components,
3320            _: &EntityAllocator,
3321            _: &Bundles,
3322            _: Commands,
3323        ) {
3324        }
3325        assert_is_system(system1);
3326
3327        fn system2(
3328            _: DeferredWorld,
3329            _: &Entities,
3330            _: &Archetypes,
3331            _: &Components,
3332            _: &EntityAllocator,
3333            _: &Bundles,
3334            _: Commands,
3335        ) {
3336        }
3337        assert_is_system(system2);
3338    }
3339
3340    #[test]
3341    fn query_and_query_state_works() {
3342        #[derive(Component)]
3343        struct A;
3344        #[derive(Component)]
3345        struct B;
3346
3347        fn system1(_: &mut QueryState<&mut A>, _: Query<&mut B>) {}
3348        assert_is_system(system1);
3349
3350        fn system2(_: &mut QueryState<&mut A>, _: Query<&mut A>) {}
3351        assert_is_system(system2);
3352    }
3353
3354    #[test]
3355    fn exclusive_systems_are_non_send() {
3356        fn test_system(_: &mut World) {}
3357
3358        let mut world = World::new();
3359        let mut system = IntoSystem::into_system(test_system);
3360        system.initialize(&mut world);
3361
3362        assert!(!system.is_send());
3363    }
3364}