bevy_ecs/query/
state.rs

1use crate::{
2    archetype::{Archetype, ArchetypeComponentId, ArchetypeGeneration, ArchetypeId},
3    batching::BatchingStrategy,
4    component::{ComponentId, Components, Tick},
5    entity::Entity,
6    prelude::FromWorld,
7    query::{
8        Access, DebugCheckedUnwrap, FilteredAccess, QueryCombinationIter, QueryIter, QueryParIter,
9    },
10    storage::{SparseSetIndex, TableId},
11    world::{unsafe_world_cell::UnsafeWorldCell, World, WorldId},
12};
13use bevy_utils::tracing::warn;
14#[cfg(feature = "trace")]
15use bevy_utils::tracing::Span;
16use fixedbitset::FixedBitSet;
17use std::{borrow::Borrow, fmt, mem::MaybeUninit, ptr};
18
19use super::{
20    NopWorldQuery, QueryBuilder, QueryData, QueryEntityError, QueryFilter, QueryManyIter,
21    QuerySingleError, ROQueryItem,
22};
23
24/// An ID for either a table or an archetype. Used for Query iteration.
25///
26/// Query iteration is exclusively dense (over tables) or archetypal (over archetypes) based on whether
27/// both `D::IS_DENSE` and `F::IS_DENSE` are true or not.
28///
29/// This is a union instead of an enum as the usage is determined at compile time, as all [`StorageId`]s for
30/// a [`QueryState`] will be all [`TableId`]s or all [`ArchetypeId`]s, and not a mixture of both. This
31/// removes the need for discriminator to minimize memory usage and branching during iteration, but requires
32/// a safety invariant be verified when disambiguating them.
33///
34/// # Safety
35/// Must be initialized and accessed as a [`TableId`], if both generic parameters to the query are dense.
36/// Must be initialized and accessed as an [`ArchetypeId`] otherwise.
37#[derive(Clone, Copy)]
38pub(super) union StorageId {
39    pub(super) table_id: TableId,
40    pub(super) archetype_id: ArchetypeId,
41}
42
43/// Provides scoped access to a [`World`] state according to a given [`QueryData`] and [`QueryFilter`].
44///
45/// This data is cached between system runs, and is used to:
46/// - store metadata about which [`Table`] or [`Archetype`] are matched by the query. "Matched" means
47/// that the query will iterate over the data in the matched table/archetype.
48/// - cache the [`State`] needed to compute the [`Fetch`] struct used to retrieve data
49/// from a specific [`Table`] or [`Archetype`]
50/// - build iterators that can iterate over the query results
51///
52/// [`State`]: crate::query::world_query::WorldQuery::State
53/// [`Fetch`]: crate::query::world_query::WorldQuery::Fetch
54/// [`Table`]: crate::storage::Table
55#[repr(C)]
56// SAFETY NOTE:
57// Do not add any new fields that use the `D` or `F` generic parameters as this may
58// make `QueryState::as_transmuted_state` unsound if not done with care.
59pub struct QueryState<D: QueryData, F: QueryFilter = ()> {
60    world_id: WorldId,
61    pub(crate) archetype_generation: ArchetypeGeneration,
62    /// Metadata about the [`Table`](crate::storage::Table)s matched by this query.
63    pub(crate) matched_tables: FixedBitSet,
64    /// Metadata about the [`Archetype`]s matched by this query.
65    pub(crate) matched_archetypes: FixedBitSet,
66    /// [`FilteredAccess`] computed by combining the `D` and `F` access. Used to check which other queries
67    /// this query can run in parallel with.
68    pub(crate) component_access: FilteredAccess<ComponentId>,
69    // NOTE: we maintain both a bitset and a vec because iterating the vec is faster
70    pub(super) matched_storage_ids: Vec<StorageId>,
71    pub(crate) fetch_state: D::State,
72    pub(crate) filter_state: F::State,
73    #[cfg(feature = "trace")]
74    par_iter_span: Span,
75}
76
77impl<D: QueryData, F: QueryFilter> fmt::Debug for QueryState<D, F> {
78    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79        f.debug_struct("QueryState")
80            .field("world_id", &self.world_id)
81            .field("matched_table_count", &self.matched_tables.count_ones(..))
82            .field(
83                "matched_archetype_count",
84                &self.matched_archetypes.count_ones(..),
85            )
86            .finish_non_exhaustive()
87    }
88}
89
90impl<D: QueryData, F: QueryFilter> FromWorld for QueryState<D, F> {
91    fn from_world(world: &mut World) -> Self {
92        world.query_filtered()
93    }
94}
95
96impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
97    /// Converts this `QueryState` reference to a `QueryState` that does not access anything mutably.
98    pub fn as_readonly(&self) -> &QueryState<D::ReadOnly, F> {
99        // SAFETY: invariant on `WorldQuery` trait upholds that `D::ReadOnly` and `F::ReadOnly`
100        // have a subset of the access, and match the exact same archetypes/tables as `D`/`F` respectively.
101        unsafe { self.as_transmuted_state::<D::ReadOnly, F>() }
102    }
103
104    /// Converts this `QueryState` reference to a `QueryState` that does not return any data
105    /// which can be faster.
106    ///
107    /// This doesn't use `NopWorldQuery` as it loses filter functionality, for example
108    /// `NopWorldQuery<Changed<T>>` is functionally equivalent to `With<T>`.
109    pub(crate) fn as_nop(&self) -> &QueryState<NopWorldQuery<D>, F> {
110        // SAFETY: `NopWorldQuery` doesn't have any accesses and defers to
111        // `D` for table/archetype matching
112        unsafe { self.as_transmuted_state::<NopWorldQuery<D>, F>() }
113    }
114
115    /// Converts this `QueryState` reference to any other `QueryState` with
116    /// the same `WorldQuery::State` associated types.
117    ///
118    /// Consider using `as_readonly` or `as_nop` instead which are safe functions.
119    ///
120    /// # SAFETY
121    ///
122    /// `NewD` must have a subset of the access that `D` does and match the exact same archetypes/tables
123    /// `NewF` must have a subset of the access that `F` does and match the exact same archetypes/tables
124    pub(crate) unsafe fn as_transmuted_state<
125        NewD: QueryData<State = D::State>,
126        NewF: QueryFilter<State = F::State>,
127    >(
128        &self,
129    ) -> &QueryState<NewD, NewF> {
130        &*ptr::from_ref(self).cast::<QueryState<NewD, NewF>>()
131    }
132
133    /// Returns the components accessed by this query.
134    pub fn component_access(&self) -> &FilteredAccess<ComponentId> {
135        &self.component_access
136    }
137
138    /// Returns the tables matched by this query.
139    pub fn matched_tables(&self) -> impl Iterator<Item = TableId> + '_ {
140        self.matched_tables.ones().map(TableId::from_usize)
141    }
142
143    /// Returns the archetypes matched by this query.
144    pub fn matched_archetypes(&self) -> impl Iterator<Item = ArchetypeId> + '_ {
145        self.matched_archetypes.ones().map(ArchetypeId::new)
146    }
147}
148
149impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
150    /// Creates a new [`QueryState`] from a given [`World`] and inherits the result of `world.id()`.
151    pub fn new(world: &mut World) -> Self {
152        let mut state = Self::new_uninitialized(world);
153        state.update_archetypes(world);
154        state
155    }
156
157    /// Identical to `new`, but it populates the provided `access` with the matched results.
158    pub(crate) fn new_with_access(
159        world: &mut World,
160        access: &mut Access<ArchetypeComponentId>,
161    ) -> Self {
162        let mut state = Self::new_uninitialized(world);
163        for archetype in world.archetypes.iter() {
164            // SAFETY: The state was just initialized from the `world` above, and the archetypes being added
165            // come directly from the same world.
166            unsafe {
167                if state.new_archetype_internal(archetype) {
168                    state.update_archetype_component_access(archetype, access);
169                }
170            }
171        }
172        state.archetype_generation = world.archetypes.generation();
173        state
174    }
175
176    /// Creates a new [`QueryState`] but does not populate it with the matched results from the World yet
177    ///
178    /// `new_archetype` and its variants must be called on all of the World's archetypes before the
179    /// state can return valid query results.
180    fn new_uninitialized(world: &mut World) -> Self {
181        let fetch_state = D::init_state(world);
182        let filter_state = F::init_state(world);
183
184        let mut component_access = FilteredAccess::default();
185        D::update_component_access(&fetch_state, &mut component_access);
186
187        // Use a temporary empty FilteredAccess for filters. This prevents them from conflicting with the
188        // main Query's `fetch_state` access. Filters are allowed to conflict with the main query fetch
189        // because they are evaluated *before* a specific reference is constructed.
190        let mut filter_component_access = FilteredAccess::default();
191        F::update_component_access(&filter_state, &mut filter_component_access);
192
193        // Merge the temporary filter access with the main access. This ensures that filter access is
194        // properly considered in a global "cross-query" context (both within systems and across systems).
195        component_access.extend(&filter_component_access);
196
197        Self {
198            world_id: world.id(),
199            archetype_generation: ArchetypeGeneration::initial(),
200            matched_storage_ids: Vec::new(),
201            fetch_state,
202            filter_state,
203            component_access,
204            matched_tables: Default::default(),
205            matched_archetypes: Default::default(),
206            #[cfg(feature = "trace")]
207            par_iter_span: bevy_utils::tracing::info_span!(
208                "par_for_each",
209                query = std::any::type_name::<D>(),
210                filter = std::any::type_name::<F>(),
211            ),
212        }
213    }
214
215    /// Creates a new [`QueryState`] from a given [`QueryBuilder`] and inherits its [`FilteredAccess`].
216    pub fn from_builder(builder: &mut QueryBuilder<D, F>) -> Self {
217        let mut fetch_state = D::init_state(builder.world_mut());
218        let filter_state = F::init_state(builder.world_mut());
219        D::set_access(&mut fetch_state, builder.access());
220
221        let mut state = Self {
222            world_id: builder.world().id(),
223            archetype_generation: ArchetypeGeneration::initial(),
224            matched_storage_ids: Vec::new(),
225            fetch_state,
226            filter_state,
227            component_access: builder.access().clone(),
228            matched_tables: Default::default(),
229            matched_archetypes: Default::default(),
230            #[cfg(feature = "trace")]
231            par_iter_span: bevy_utils::tracing::info_span!(
232                "par_for_each",
233                data = std::any::type_name::<D>(),
234                filter = std::any::type_name::<F>(),
235            ),
236        };
237        state.update_archetypes(builder.world());
238        state
239    }
240
241    /// Checks if the query is empty for the given [`World`], where the last change and current tick are given.
242    ///
243    /// This is equivalent to `self.iter().next().is_none()`, and thus the worst case runtime will be `O(n)`
244    /// where `n` is the number of *potential* matches. This can be notably expensive for queries that rely
245    /// on non-archetypal filters such as [`Added`] or [`Changed`] which must individually check each query
246    /// result for a match.
247    ///
248    /// # Panics
249    ///
250    /// If `world` does not match the one used to call `QueryState::new` for this instance.
251    ///
252    /// [`Added`]: crate::query::Added
253    /// [`Changed`]: crate::query::Changed
254    #[inline]
255    pub fn is_empty(&self, world: &World, last_run: Tick, this_run: Tick) -> bool {
256        self.validate_world(world.id());
257        // SAFETY:
258        // - We have read-only access to the entire world.
259        // - The world has been validated.
260        unsafe {
261            self.is_empty_unsafe_world_cell(
262                world.as_unsafe_world_cell_readonly(),
263                last_run,
264                this_run,
265            )
266        }
267    }
268
269    /// Returns `true` if the given [`Entity`] matches the query.
270    ///
271    /// This is always guaranteed to run in `O(1)` time.
272    #[inline]
273    pub fn contains(&self, entity: Entity, world: &World, last_run: Tick, this_run: Tick) -> bool {
274        // SAFETY: NopFetch does not access any members while &self ensures no one has exclusive access
275        unsafe {
276            self.as_nop()
277                .get_unchecked_manual(
278                    world.as_unsafe_world_cell_readonly(),
279                    entity,
280                    last_run,
281                    this_run,
282                )
283                .is_ok()
284        }
285    }
286
287    /// Checks if the query is empty for the given [`UnsafeWorldCell`].
288    ///
289    /// # Safety
290    ///
291    /// - `world` must have permission to read any components required by this instance's `F` [`QueryFilter`].
292    /// - `world` must match the one used to create this [`QueryState`].
293    #[inline]
294    pub(crate) unsafe fn is_empty_unsafe_world_cell(
295        &self,
296        world: UnsafeWorldCell,
297        last_run: Tick,
298        this_run: Tick,
299    ) -> bool {
300        // SAFETY:
301        // - The caller ensures that `world` has permission to access any data used by the filter.
302        // - The caller ensures that the world matches.
303        unsafe {
304            self.as_nop()
305                .iter_unchecked_manual(world, last_run, this_run)
306                .next()
307                .is_none()
308        }
309    }
310
311    /// Updates the state's internal view of the [`World`]'s archetypes. If this is not called before querying data,
312    /// the results may not accurately reflect what is in the `world`.
313    ///
314    /// This is only required if a `manual` method (such as [`Self::get_manual`]) is being called, and it only needs to
315    /// be called if the `world` has been structurally mutated (i.e. added/removed a component or resource). Users using
316    /// non-`manual` methods such as [`QueryState::get`] do not need to call this as it will be automatically called for them.
317    ///
318    /// If you have an [`UnsafeWorldCell`] instead of `&World`, consider using [`QueryState::update_archetypes_unsafe_world_cell`].
319    ///
320    /// # Panics
321    ///
322    /// If `world` does not match the one used to call `QueryState::new` for this instance.
323    #[inline]
324    pub fn update_archetypes(&mut self, world: &World) {
325        self.update_archetypes_unsafe_world_cell(world.as_unsafe_world_cell_readonly());
326    }
327
328    /// Updates the state's internal view of the `world`'s archetypes. If this is not called before querying data,
329    /// the results may not accurately reflect what is in the `world`.
330    ///
331    /// This is only required if a `manual` method (such as [`Self::get_manual`]) is being called, and it only needs to
332    /// be called if the `world` has been structurally mutated (i.e. added/removed a component or resource). Users using
333    /// non-`manual` methods such as [`QueryState::get`] do not need to call this as it will be automatically called for them.
334    ///
335    /// # Note
336    ///
337    /// This method only accesses world metadata.
338    ///
339    /// # Panics
340    ///
341    /// If `world` does not match the one used to call `QueryState::new` for this instance.
342    pub fn update_archetypes_unsafe_world_cell(&mut self, world: UnsafeWorldCell) {
343        self.validate_world(world.id());
344        let archetypes = world.archetypes();
345        let old_generation =
346            std::mem::replace(&mut self.archetype_generation, archetypes.generation());
347
348        for archetype in &archetypes[old_generation..] {
349            // SAFETY: The validate_world call ensures that the world is the same the QueryState
350            // was initialized from.
351            unsafe {
352                self.new_archetype_internal(archetype);
353            }
354        }
355    }
356
357    /// # Panics
358    ///
359    /// If `world_id` does not match the [`World`] used to call `QueryState::new` for this instance.
360    ///
361    /// Many unsafe query methods require the world to match for soundness. This function is the easiest
362    /// way of ensuring that it matches.
363    #[inline]
364    #[track_caller]
365    pub fn validate_world(&self, world_id: WorldId) {
366        #[inline(never)]
367        #[track_caller]
368        #[cold]
369        fn panic_mismatched(this: WorldId, other: WorldId) -> ! {
370            panic!("Encountered a mismatched World. This QueryState was created from {this:?}, but a method was called using {other:?}.");
371        }
372
373        if self.world_id != world_id {
374            panic_mismatched(self.world_id, world_id);
375        }
376    }
377
378    /// Update the current [`QueryState`] with information from the provided [`Archetype`]
379    /// (if applicable, i.e. if the archetype has any intersecting [`ComponentId`] with the current [`QueryState`]).
380    ///
381    /// The passed in `access` will be updated with any new accesses introduced by the new archetype.
382    ///
383    /// # Safety
384    /// `archetype` must be from the `World` this state was initialized from.
385    pub unsafe fn new_archetype(
386        &mut self,
387        archetype: &Archetype,
388        access: &mut Access<ArchetypeComponentId>,
389    ) {
390        // SAFETY: The caller ensures that `archetype` is from the World the state was initialized from.
391        let matches = unsafe { self.new_archetype_internal(archetype) };
392        if matches {
393            // SAFETY: The caller ensures that `archetype` is from the World the state was initialized from.
394            unsafe { self.update_archetype_component_access(archetype, access) };
395        }
396    }
397
398    /// Process the given [`Archetype`] to update internal metadata about the [`Table`](crate::storage::Table)s
399    /// and [`Archetype`]s that are matched by this query.
400    ///
401    /// Returns `true` if the given `archetype` matches the query. Otherwise, returns `false`.
402    /// If there is no match, then there is no need to update the query's [`FilteredAccess`].
403    ///
404    /// # Safety
405    /// `archetype` must be from the `World` this state was initialized from.
406    unsafe fn new_archetype_internal(&mut self, archetype: &Archetype) -> bool {
407        if D::matches_component_set(&self.fetch_state, &|id| archetype.contains(id))
408            && F::matches_component_set(&self.filter_state, &|id| archetype.contains(id))
409            && self.matches_component_set(&|id| archetype.contains(id))
410        {
411            let archetype_index = archetype.id().index();
412            if !self.matched_archetypes.contains(archetype_index) {
413                self.matched_archetypes.grow_and_insert(archetype_index);
414                if !D::IS_DENSE || !F::IS_DENSE {
415                    self.matched_storage_ids.push(StorageId {
416                        archetype_id: archetype.id(),
417                    });
418                }
419            }
420            let table_index = archetype.table_id().as_usize();
421            if !self.matched_tables.contains(table_index) {
422                self.matched_tables.grow_and_insert(table_index);
423                if D::IS_DENSE && F::IS_DENSE {
424                    self.matched_storage_ids.push(StorageId {
425                        table_id: archetype.table_id(),
426                    });
427                }
428            }
429            true
430        } else {
431            false
432        }
433    }
434
435    /// Returns `true` if this query matches a set of components. Otherwise, returns `false`.
436    pub fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool {
437        self.component_access.filter_sets.iter().any(|set| {
438            set.with
439                .ones()
440                .all(|index| set_contains_id(ComponentId::get_sparse_set_index(index)))
441                && set
442                    .without
443                    .ones()
444                    .all(|index| !set_contains_id(ComponentId::get_sparse_set_index(index)))
445        })
446    }
447
448    /// For the given `archetype`, adds any component accessed used by this query's underlying [`FilteredAccess`] to `access`.
449    ///
450    /// The passed in `access` will be updated with any new accesses introduced by the new archetype.
451    ///
452    /// # Safety
453    /// `archetype` must be from the `World` this state was initialized from.
454    pub unsafe fn update_archetype_component_access(
455        &mut self,
456        archetype: &Archetype,
457        access: &mut Access<ArchetypeComponentId>,
458    ) {
459        self.component_access.access.reads().for_each(|id| {
460            if let Some(id) = archetype.get_archetype_component_id(id) {
461                access.add_read(id);
462            }
463        });
464        self.component_access.access.writes().for_each(|id| {
465            if let Some(id) = archetype.get_archetype_component_id(id) {
466                access.add_write(id);
467            }
468        });
469    }
470
471    /// Use this to transform a [`QueryState`] into a more generic [`QueryState`].
472    /// This can be useful for passing to another function that might take the more general form.
473    /// See [`Query::transmute_lens`](crate::system::Query::transmute_lens) for more details.
474    ///
475    /// You should not call [`update_archetypes`](Self::update_archetypes) on the returned [`QueryState`] as the result will be unpredictable.
476    /// You might end up with a mix of archetypes that only matched the original query + archetypes that only match
477    /// the new [`QueryState`]. Most of the safe methods on [`QueryState`] call [`QueryState::update_archetypes`] internally, so this
478    /// best used through a [`Query`](crate::system::Query).
479    pub fn transmute<NewD: QueryData>(&self, components: &Components) -> QueryState<NewD> {
480        self.transmute_filtered::<NewD, ()>(components)
481    }
482
483    /// Creates a new [`QueryState`] with the same underlying [`FilteredAccess`], matched tables and archetypes
484    /// as self but with a new type signature.
485    ///
486    /// Panics if `NewD` or `NewF` require accesses that this query does not have.
487    pub fn transmute_filtered<NewD: QueryData, NewF: QueryFilter>(
488        &self,
489        components: &Components,
490    ) -> QueryState<NewD, NewF> {
491        let mut component_access = FilteredAccess::default();
492        let mut fetch_state = NewD::get_state(components).expect("Could not create fetch_state, Please initialize all referenced components before transmuting.");
493        let filter_state = NewF::get_state(components).expect("Could not create filter_state, Please initialize all referenced components before transmuting.");
494
495        NewD::set_access(&mut fetch_state, &self.component_access);
496        NewD::update_component_access(&fetch_state, &mut component_access);
497
498        let mut filter_component_access = FilteredAccess::default();
499        NewF::update_component_access(&filter_state, &mut filter_component_access);
500
501        component_access.extend(&filter_component_access);
502        assert!(
503            component_access.is_subset(&self.component_access),
504            "Transmuted state for {} attempts to access terms that are not allowed by original state {}.",
505            std::any::type_name::<(NewD, NewF)>(), std::any::type_name::<(D, F)>()
506        );
507
508        QueryState {
509            world_id: self.world_id,
510            archetype_generation: self.archetype_generation,
511            matched_storage_ids: self.matched_storage_ids.clone(),
512            fetch_state,
513            filter_state,
514            component_access: self.component_access.clone(),
515            matched_tables: self.matched_tables.clone(),
516            matched_archetypes: self.matched_archetypes.clone(),
517            #[cfg(feature = "trace")]
518            par_iter_span: bevy_utils::tracing::info_span!(
519                "par_for_each",
520                query = std::any::type_name::<NewD>(),
521                filter = std::any::type_name::<NewF>(),
522            ),
523        }
524    }
525
526    /// Use this to combine two queries. The data accessed will be the intersection
527    /// of archetypes included in both queries. This can be useful for accessing a
528    /// subset of the entities between two queries.
529    ///
530    /// You should not call `update_archetypes` on the returned `QueryState` as the result
531    /// could be unpredictable. You might end up with a mix of archetypes that only matched
532    /// the original query + archetypes that only match the new `QueryState`. Most of the
533    /// safe methods on `QueryState` call [`QueryState::update_archetypes`] internally, so
534    /// this is best used through a `Query`.
535    ///
536    /// ## Performance
537    ///
538    /// This will have similar performance as constructing a new `QueryState` since much of internal state
539    /// needs to be reconstructed. But it will be a little faster as it only needs to compare the intersection
540    /// of matching archetypes rather than iterating over all archetypes.
541    ///
542    /// ## Panics
543    ///
544    /// Will panic if `NewD` contains accesses not in `Q` or `OtherQ`.
545    pub fn join<OtherD: QueryData, NewD: QueryData>(
546        &self,
547        components: &Components,
548        other: &QueryState<OtherD>,
549    ) -> QueryState<NewD, ()> {
550        self.join_filtered::<_, (), NewD, ()>(components, other)
551    }
552
553    /// Use this to combine two queries. The data accessed will be the intersection
554    /// of archetypes included in both queries.
555    ///
556    /// ## Panics
557    ///
558    /// Will panic if `NewD` or `NewF` requires accesses not in `Q` or `OtherQ`.
559    pub fn join_filtered<
560        OtherD: QueryData,
561        OtherF: QueryFilter,
562        NewD: QueryData,
563        NewF: QueryFilter,
564    >(
565        &self,
566        components: &Components,
567        other: &QueryState<OtherD, OtherF>,
568    ) -> QueryState<NewD, NewF> {
569        if self.world_id != other.world_id {
570            panic!("Joining queries initialized on different worlds is not allowed.");
571        }
572
573        let mut component_access = FilteredAccess::default();
574        let mut new_fetch_state = NewD::get_state(components)
575            .expect("Could not create fetch_state, Please initialize all referenced components before transmuting.");
576        let new_filter_state = NewF::get_state(components)
577            .expect("Could not create filter_state, Please initialize all referenced components before transmuting.");
578
579        NewD::set_access(&mut new_fetch_state, &self.component_access);
580        NewD::update_component_access(&new_fetch_state, &mut component_access);
581
582        let mut new_filter_component_access = FilteredAccess::default();
583        NewF::update_component_access(&new_filter_state, &mut new_filter_component_access);
584
585        component_access.extend(&new_filter_component_access);
586
587        let mut joined_component_access = self.component_access.clone();
588        joined_component_access.extend(&other.component_access);
589
590        assert!(
591            component_access.is_subset(&joined_component_access),
592            "Joined state for {} attempts to access terms that are not allowed by state {} joined with {}.",
593            std::any::type_name::<(NewD, NewF)>(), std::any::type_name::<(D, F)>(), std::any::type_name::<(OtherD, OtherF)>()
594        );
595
596        if self.archetype_generation != other.archetype_generation {
597            warn!("You have tried to join queries with different archetype_generations. This could lead to unpredictable results.");
598        }
599
600        // take the intersection of the matched ids
601        let mut matched_tables = self.matched_tables.clone();
602        let mut matched_archetypes = self.matched_archetypes.clone();
603        matched_tables.intersect_with(&other.matched_tables);
604        matched_archetypes.intersect_with(&other.matched_archetypes);
605        let matched_storage_ids = if NewD::IS_DENSE && NewF::IS_DENSE {
606            matched_tables
607                .ones()
608                .map(|id| StorageId {
609                    table_id: TableId::from_usize(id),
610                })
611                .collect()
612        } else {
613            matched_archetypes
614                .ones()
615                .map(|id| StorageId {
616                    archetype_id: ArchetypeId::new(id),
617                })
618                .collect()
619        };
620
621        QueryState {
622            world_id: self.world_id,
623            archetype_generation: self.archetype_generation,
624            matched_storage_ids,
625            fetch_state: new_fetch_state,
626            filter_state: new_filter_state,
627            component_access: joined_component_access,
628            matched_tables,
629            matched_archetypes,
630            #[cfg(feature = "trace")]
631            par_iter_span: bevy_utils::tracing::info_span!(
632                "par_for_each",
633                query = std::any::type_name::<NewD>(),
634                filter = std::any::type_name::<NewF>(),
635            ),
636        }
637    }
638
639    /// Gets the query result for the given [`World`] and [`Entity`].
640    ///
641    /// This can only be called for read-only queries, see [`Self::get_mut`] for write-queries.
642    ///
643    /// This is always guaranteed to run in `O(1)` time.
644    #[inline]
645    pub fn get<'w>(
646        &mut self,
647        world: &'w World,
648        entity: Entity,
649    ) -> Result<ROQueryItem<'w, D>, QueryEntityError> {
650        self.update_archetypes(world);
651        // SAFETY: query is read only
652        unsafe {
653            self.as_readonly().get_unchecked_manual(
654                world.as_unsafe_world_cell_readonly(),
655                entity,
656                world.last_change_tick(),
657                world.read_change_tick(),
658            )
659        }
660    }
661
662    /// Returns the read-only query results for the given array of [`Entity`].
663    ///
664    /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is
665    /// returned instead.
666    ///
667    /// Note that the unlike [`QueryState::get_many_mut`], the entities passed in do not need to be unique.
668    ///
669    /// # Examples
670    ///
671    /// ```
672    /// use bevy_ecs::prelude::*;
673    /// use bevy_ecs::query::QueryEntityError;
674    ///
675    /// #[derive(Component, PartialEq, Debug)]
676    /// struct A(usize);
677    ///
678    /// let mut world = World::new();
679    /// let entity_vec: Vec<Entity> = (0..3).map(|i|world.spawn(A(i)).id()).collect();
680    /// let entities: [Entity; 3] = entity_vec.try_into().unwrap();
681    ///
682    /// world.spawn(A(73));
683    ///
684    /// let mut query_state = world.query::<&A>();
685    ///
686    /// let component_values = query_state.get_many(&world, entities).unwrap();
687    ///
688    /// assert_eq!(component_values, [&A(0), &A(1), &A(2)]);
689    ///
690    /// let wrong_entity = Entity::from_raw(365);
691    ///
692    /// assert_eq!(query_state.get_many(&world, [wrong_entity]), Err(QueryEntityError::NoSuchEntity(wrong_entity)));
693    /// ```
694    #[inline]
695    pub fn get_many<'w, const N: usize>(
696        &mut self,
697        world: &'w World,
698        entities: [Entity; N],
699    ) -> Result<[ROQueryItem<'w, D>; N], QueryEntityError> {
700        self.update_archetypes(world);
701
702        // SAFETY:
703        // - We have read-only access to the entire world.
704        // - `update_archetypes` validates that the `World` matches.
705        unsafe {
706            self.get_many_read_only_manual(
707                world.as_unsafe_world_cell_readonly(),
708                entities,
709                world.last_change_tick(),
710                world.read_change_tick(),
711            )
712        }
713    }
714
715    /// Gets the query result for the given [`World`] and [`Entity`].
716    ///
717    /// This is always guaranteed to run in `O(1)` time.
718    #[inline]
719    pub fn get_mut<'w>(
720        &mut self,
721        world: &'w mut World,
722        entity: Entity,
723    ) -> Result<D::Item<'w>, QueryEntityError> {
724        self.update_archetypes(world);
725        let change_tick = world.change_tick();
726        let last_change_tick = world.last_change_tick();
727        // SAFETY: query has unique world access
728        unsafe {
729            self.get_unchecked_manual(
730                world.as_unsafe_world_cell(),
731                entity,
732                last_change_tick,
733                change_tick,
734            )
735        }
736    }
737
738    /// Returns the query results for the given array of [`Entity`].
739    ///
740    /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is
741    /// returned instead.
742    ///
743    /// ```
744    /// use bevy_ecs::prelude::*;
745    /// use bevy_ecs::query::QueryEntityError;
746    ///
747    /// #[derive(Component, PartialEq, Debug)]
748    /// struct A(usize);
749    ///
750    /// let mut world = World::new();
751    ///
752    /// let entities: Vec<Entity> = (0..3).map(|i|world.spawn(A(i)).id()).collect();
753    /// let entities: [Entity; 3] = entities.try_into().unwrap();
754    ///
755    /// world.spawn(A(73));
756    ///
757    /// let mut query_state = world.query::<&mut A>();
758    ///
759    /// let mut mutable_component_values = query_state.get_many_mut(&mut world, entities).unwrap();
760    ///
761    /// for mut a in &mut mutable_component_values {
762    ///     a.0 += 5;
763    /// }
764    ///
765    /// let component_values = query_state.get_many(&world, entities).unwrap();
766    ///
767    /// assert_eq!(component_values, [&A(5), &A(6), &A(7)]);
768    ///
769    /// let wrong_entity = Entity::from_raw(57);
770    /// let invalid_entity = world.spawn_empty().id();
771    ///
772    /// assert_eq!(query_state.get_many_mut(&mut world, [wrong_entity]).unwrap_err(), QueryEntityError::NoSuchEntity(wrong_entity));
773    /// assert_eq!(query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err(), QueryEntityError::QueryDoesNotMatch(invalid_entity));
774    /// assert_eq!(query_state.get_many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0]));
775    /// ```
776    #[inline]
777    pub fn get_many_mut<'w, const N: usize>(
778        &mut self,
779        world: &'w mut World,
780        entities: [Entity; N],
781    ) -> Result<[D::Item<'w>; N], QueryEntityError> {
782        self.update_archetypes(world);
783
784        let change_tick = world.change_tick();
785        let last_change_tick = world.last_change_tick();
786        // SAFETY: method requires exclusive world access
787        // and world has been validated via update_archetypes
788        unsafe {
789            self.get_many_unchecked_manual(
790                world.as_unsafe_world_cell(),
791                entities,
792                last_change_tick,
793                change_tick,
794            )
795        }
796    }
797
798    /// Gets the query result for the given [`World`] and [`Entity`].
799    ///
800    /// This method is slightly more efficient than [`QueryState::get`] in some situations, since
801    /// it does not update this instance's internal cache. This method will return an error if `entity`
802    /// belongs to an archetype that has not been cached.
803    ///
804    /// To ensure that the cache is up to date, call [`QueryState::update_archetypes`] before this method.
805    /// The cache is also updated in [`QueryState::new`], `QueryState::get`, or any method with mutable
806    /// access to `self`.
807    ///
808    /// This can only be called for read-only queries, see [`Self::get_mut`] for mutable queries.
809    ///
810    /// This is always guaranteed to run in `O(1)` time.
811    #[inline]
812    pub fn get_manual<'w>(
813        &self,
814        world: &'w World,
815        entity: Entity,
816    ) -> Result<ROQueryItem<'w, D>, QueryEntityError> {
817        self.validate_world(world.id());
818        // SAFETY: query is read only and world is validated
819        unsafe {
820            self.as_readonly().get_unchecked_manual(
821                world.as_unsafe_world_cell_readonly(),
822                entity,
823                world.last_change_tick(),
824                world.read_change_tick(),
825            )
826        }
827    }
828
829    /// Gets the query result for the given [`World`] and [`Entity`].
830    ///
831    /// This is always guaranteed to run in `O(1)` time.
832    ///
833    /// # Safety
834    ///
835    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
836    /// have unique access to the components they query.
837    #[inline]
838    pub unsafe fn get_unchecked<'w>(
839        &mut self,
840        world: UnsafeWorldCell<'w>,
841        entity: Entity,
842    ) -> Result<D::Item<'w>, QueryEntityError> {
843        self.update_archetypes_unsafe_world_cell(world);
844        self.get_unchecked_manual(world, entity, world.last_change_tick(), world.change_tick())
845    }
846
847    /// Gets the query result for the given [`World`] and [`Entity`], where the last change and
848    /// the current change tick are given.
849    ///
850    /// This is always guaranteed to run in `O(1)` time.
851    ///
852    /// # Safety
853    ///
854    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
855    /// have unique access to the components they query.
856    ///
857    /// This must be called on the same `World` that the `Query` was generated from:
858    /// use `QueryState::validate_world` to verify this.
859    pub(crate) unsafe fn get_unchecked_manual<'w>(
860        &self,
861        world: UnsafeWorldCell<'w>,
862        entity: Entity,
863        last_run: Tick,
864        this_run: Tick,
865    ) -> Result<D::Item<'w>, QueryEntityError> {
866        let location = world
867            .entities()
868            .get(entity)
869            .ok_or(QueryEntityError::NoSuchEntity(entity))?;
870        if !self
871            .matched_archetypes
872            .contains(location.archetype_id.index())
873        {
874            return Err(QueryEntityError::QueryDoesNotMatch(entity));
875        }
876        let archetype = world
877            .archetypes()
878            .get(location.archetype_id)
879            .debug_checked_unwrap();
880        let mut fetch = D::init_fetch(world, &self.fetch_state, last_run, this_run);
881        let mut filter = F::init_fetch(world, &self.filter_state, last_run, this_run);
882
883        let table = world
884            .storages()
885            .tables
886            .get(location.table_id)
887            .debug_checked_unwrap();
888        D::set_archetype(&mut fetch, &self.fetch_state, archetype, table);
889        F::set_archetype(&mut filter, &self.filter_state, archetype, table);
890
891        if F::filter_fetch(&mut filter, entity, location.table_row) {
892            Ok(D::fetch(&mut fetch, entity, location.table_row))
893        } else {
894            Err(QueryEntityError::QueryDoesNotMatch(entity))
895        }
896    }
897
898    /// Gets the read-only query results for the given [`World`] and array of [`Entity`], where the last change and
899    /// the current change tick are given.
900    ///
901    /// # Safety
902    ///
903    /// * `world` must have permission to read all of the components returned from this call.
904    /// No mutable references may coexist with any of the returned references.
905    /// * This must be called on the same `World` that the `Query` was generated from:
906    /// use `QueryState::validate_world` to verify this.
907    pub(crate) unsafe fn get_many_read_only_manual<'w, const N: usize>(
908        &self,
909        world: UnsafeWorldCell<'w>,
910        entities: [Entity; N],
911        last_run: Tick,
912        this_run: Tick,
913    ) -> Result<[ROQueryItem<'w, D>; N], QueryEntityError> {
914        let mut values = [(); N].map(|_| MaybeUninit::uninit());
915
916        for (value, entity) in std::iter::zip(&mut values, entities) {
917            // SAFETY: fetch is read-only and world must be validated
918            let item = unsafe {
919                self.as_readonly()
920                    .get_unchecked_manual(world, entity, last_run, this_run)?
921            };
922            *value = MaybeUninit::new(item);
923        }
924
925        // SAFETY: Each value has been fully initialized.
926        Ok(values.map(|x| unsafe { x.assume_init() }))
927    }
928
929    /// Gets the query results for the given [`World`] and array of [`Entity`], where the last change and
930    /// the current change tick are given.
931    ///
932    /// This is always guaranteed to run in `O(1)` time.
933    ///
934    /// # Safety
935    ///
936    /// This does not check for unique access to subsets of the entity-component data.
937    /// To be safe, make sure mutable queries have unique access to the components they query.
938    ///
939    /// This must be called on the same `World` that the `Query` was generated from:
940    /// use `QueryState::validate_world` to verify this.
941    pub(crate) unsafe fn get_many_unchecked_manual<'w, const N: usize>(
942        &self,
943        world: UnsafeWorldCell<'w>,
944        entities: [Entity; N],
945        last_run: Tick,
946        this_run: Tick,
947    ) -> Result<[D::Item<'w>; N], QueryEntityError> {
948        // Verify that all entities are unique
949        for i in 0..N {
950            for j in 0..i {
951                if entities[i] == entities[j] {
952                    return Err(QueryEntityError::AliasedMutability(entities[i]));
953                }
954            }
955        }
956
957        let mut values = [(); N].map(|_| MaybeUninit::uninit());
958
959        for (value, entity) in std::iter::zip(&mut values, entities) {
960            let item = self.get_unchecked_manual(world, entity, last_run, this_run)?;
961            *value = MaybeUninit::new(item);
962        }
963
964        // SAFETY: Each value has been fully initialized.
965        Ok(values.map(|x| x.assume_init()))
966    }
967
968    /// Returns an [`Iterator`] over the query results for the given [`World`].
969    ///
970    /// This can only be called for read-only queries, see [`Self::iter_mut`] for write-queries.
971    #[inline]
972    pub fn iter<'w, 's>(&'s mut self, world: &'w World) -> QueryIter<'w, 's, D::ReadOnly, F> {
973        self.update_archetypes(world);
974        // SAFETY: query is read only
975        unsafe {
976            self.as_readonly().iter_unchecked_manual(
977                world.as_unsafe_world_cell_readonly(),
978                world.last_change_tick(),
979                world.read_change_tick(),
980            )
981        }
982    }
983
984    /// Returns an [`Iterator`] over the query results for the given [`World`].
985    ///
986    /// This iterator is always guaranteed to return results from each matching entity once and only once.
987    /// Iteration order is not guaranteed.
988    #[inline]
989    pub fn iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryIter<'w, 's, D, F> {
990        self.update_archetypes(world);
991        let change_tick = world.change_tick();
992        let last_change_tick = world.last_change_tick();
993        // SAFETY: query has unique world access
994        unsafe {
995            self.iter_unchecked_manual(world.as_unsafe_world_cell(), last_change_tick, change_tick)
996        }
997    }
998
999    /// Returns an [`Iterator`] over the query results for the given [`World`] without updating the query's archetypes.
1000    /// Archetypes must be manually updated before by using [`Self::update_archetypes`].
1001    ///
1002    /// This iterator is always guaranteed to return results from each matching entity once and only once.
1003    /// Iteration order is not guaranteed.
1004    ///
1005    /// This can only be called for read-only queries.
1006    #[inline]
1007    pub fn iter_manual<'w, 's>(&'s self, world: &'w World) -> QueryIter<'w, 's, D::ReadOnly, F> {
1008        self.validate_world(world.id());
1009        // SAFETY: query is read only and world is validated
1010        unsafe {
1011            self.as_readonly().iter_unchecked_manual(
1012                world.as_unsafe_world_cell_readonly(),
1013                world.last_change_tick(),
1014                world.read_change_tick(),
1015            )
1016        }
1017    }
1018
1019    /// Returns an [`Iterator`] over all possible combinations of `K` query results without repetition.
1020    /// This can only be called for read-only queries.
1021    ///
1022    /// A combination is an arrangement of a collection of items where order does not matter.
1023    ///
1024    /// `K` is the number of items that make up each subset, and the number of items returned by the iterator.
1025    /// `N` is the number of total entities output by query.
1026    ///
1027    /// For example, given the list [1, 2, 3, 4], where `K` is 2, the combinations without repeats are
1028    /// [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4].
1029    /// And in this case, `N` would be defined as 4 since the size of the input list is 4.
1030    ///
1031    ///  For combinations of size `K` of query taking `N` inputs, you will get:
1032    /// - if `K == N`: one combination of all query results
1033    /// - if `K < N`: all possible `K`-sized combinations of query results, without repetition
1034    /// - if `K > N`: empty set (no `K`-sized combinations exist)
1035    ///
1036    /// The `iter_combinations` method does not guarantee order of iteration.
1037    ///
1038    /// This iterator is always guaranteed to return results from each unique pair of matching entities.
1039    /// Iteration order is not guaranteed.
1040    ///
1041    /// This can only be called for read-only queries, see [`Self::iter_combinations_mut`] for
1042    /// write-queries.
1043    #[inline]
1044    pub fn iter_combinations<'w, 's, const K: usize>(
1045        &'s mut self,
1046        world: &'w World,
1047    ) -> QueryCombinationIter<'w, 's, D::ReadOnly, F, K> {
1048        self.update_archetypes(world);
1049        // SAFETY: query is read only
1050        unsafe {
1051            self.as_readonly().iter_combinations_unchecked_manual(
1052                world.as_unsafe_world_cell_readonly(),
1053                world.last_change_tick(),
1054                world.read_change_tick(),
1055            )
1056        }
1057    }
1058
1059    /// Returns an [`Iterator`] over all possible combinations of `K` query results without repetition.
1060    ///
1061    /// A combination is an arrangement of a collection of items where order does not matter.
1062    ///
1063    /// `K` is the number of items that make up each subset, and the number of items returned by the iterator.
1064    /// `N` is the number of total entities output by query.
1065    ///
1066    /// For example, given the list [1, 2, 3, 4], where `K` is 2, the combinations without repeats are
1067    /// [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4].
1068    /// And in this case, `N` would be defined as 4 since the size of the input list is 4.
1069    ///
1070    ///  For combinations of size `K` of query taking `N` inputs, you will get:
1071    /// - if `K == N`: one combination of all query results
1072    /// - if `K < N`: all possible `K`-sized combinations of query results, without repetition
1073    /// - if `K > N`: empty set (no `K`-sized combinations exist)
1074    ///
1075    /// The `iter_combinations_mut` method does not guarantee order of iteration.
1076    #[inline]
1077    pub fn iter_combinations_mut<'w, 's, const K: usize>(
1078        &'s mut self,
1079        world: &'w mut World,
1080    ) -> QueryCombinationIter<'w, 's, D, F, K> {
1081        self.update_archetypes(world);
1082        let change_tick = world.change_tick();
1083        let last_change_tick = world.last_change_tick();
1084        // SAFETY: query has unique world access
1085        unsafe {
1086            self.iter_combinations_unchecked_manual(
1087                world.as_unsafe_world_cell(),
1088                last_change_tick,
1089                change_tick,
1090            )
1091        }
1092    }
1093
1094    /// Returns an [`Iterator`] over the read-only query items generated from an [`Entity`] list.
1095    ///
1096    /// Items are returned in the order of the list of entities.
1097    /// Entities that don't match the query are skipped.
1098    ///
1099    /// # See also
1100    ///
1101    /// - [`iter_many_mut`](Self::iter_many_mut) to get mutable query items.
1102    #[inline]
1103    pub fn iter_many<'w, 's, EntityList: IntoIterator>(
1104        &'s mut self,
1105        world: &'w World,
1106        entities: EntityList,
1107    ) -> QueryManyIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter>
1108    where
1109        EntityList::Item: Borrow<Entity>,
1110    {
1111        self.update_archetypes(world);
1112        // SAFETY: query is read only
1113        unsafe {
1114            self.as_readonly().iter_many_unchecked_manual(
1115                entities,
1116                world.as_unsafe_world_cell_readonly(),
1117                world.last_change_tick(),
1118                world.read_change_tick(),
1119            )
1120        }
1121    }
1122
1123    /// Returns an [`Iterator`] over the read-only query items generated from an [`Entity`] list.
1124    ///
1125    /// Items are returned in the order of the list of entities.
1126    /// Entities that don't match the query are skipped.
1127    ///
1128    /// If `world` archetypes changed since [`Self::update_archetypes`] was last called,
1129    /// this will skip entities contained in new archetypes.
1130    ///
1131    /// This can only be called for read-only queries.
1132    ///
1133    /// # See also
1134    ///
1135    /// - [`iter_many`](Self::iter_many) to update archetypes.
1136    /// - [`iter_manual`](Self::iter_manual) to iterate over all query items.
1137    #[inline]
1138    pub fn iter_many_manual<'w, 's, EntityList: IntoIterator>(
1139        &'s self,
1140        world: &'w World,
1141        entities: EntityList,
1142    ) -> QueryManyIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter>
1143    where
1144        EntityList::Item: Borrow<Entity>,
1145    {
1146        self.validate_world(world.id());
1147        // SAFETY: query is read only, world id is validated
1148        unsafe {
1149            self.as_readonly().iter_many_unchecked_manual(
1150                entities,
1151                world.as_unsafe_world_cell_readonly(),
1152                world.last_change_tick(),
1153                world.read_change_tick(),
1154            )
1155        }
1156    }
1157
1158    /// Returns an iterator over the query items generated from an [`Entity`] list.
1159    ///
1160    /// Items are returned in the order of the list of entities.
1161    /// Entities that don't match the query are skipped.
1162    #[inline]
1163    pub fn iter_many_mut<'w, 's, EntityList: IntoIterator>(
1164        &'s mut self,
1165        world: &'w mut World,
1166        entities: EntityList,
1167    ) -> QueryManyIter<'w, 's, D, F, EntityList::IntoIter>
1168    where
1169        EntityList::Item: Borrow<Entity>,
1170    {
1171        self.update_archetypes(world);
1172        let change_tick = world.change_tick();
1173        let last_change_tick = world.last_change_tick();
1174        // SAFETY: Query has unique world access.
1175        unsafe {
1176            self.iter_many_unchecked_manual(
1177                entities,
1178                world.as_unsafe_world_cell(),
1179                last_change_tick,
1180                change_tick,
1181            )
1182        }
1183    }
1184
1185    /// Returns an [`Iterator`] over the query results for the given [`World`].
1186    ///
1187    /// This iterator is always guaranteed to return results from each matching entity once and only once.
1188    /// Iteration order is not guaranteed.
1189    ///
1190    /// # Safety
1191    ///
1192    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
1193    /// have unique access to the components they query.
1194    #[inline]
1195    pub unsafe fn iter_unchecked<'w, 's>(
1196        &'s mut self,
1197        world: UnsafeWorldCell<'w>,
1198    ) -> QueryIter<'w, 's, D, F> {
1199        self.update_archetypes_unsafe_world_cell(world);
1200        self.iter_unchecked_manual(world, world.last_change_tick(), world.change_tick())
1201    }
1202
1203    /// Returns an [`Iterator`] over all possible combinations of `K` query results for the
1204    /// given [`World`] without repetition.
1205    /// This can only be called for read-only queries.
1206    ///
1207    /// This iterator is always guaranteed to return results from each unique pair of matching entities.
1208    /// Iteration order is not guaranteed.
1209    ///
1210    /// # Safety
1211    ///
1212    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
1213    /// have unique access to the components they query.
1214    #[inline]
1215    pub unsafe fn iter_combinations_unchecked<'w, 's, const K: usize>(
1216        &'s mut self,
1217        world: UnsafeWorldCell<'w>,
1218    ) -> QueryCombinationIter<'w, 's, D, F, K> {
1219        self.update_archetypes_unsafe_world_cell(world);
1220        self.iter_combinations_unchecked_manual(
1221            world,
1222            world.last_change_tick(),
1223            world.change_tick(),
1224        )
1225    }
1226
1227    /// Returns an [`Iterator`] for the given [`World`], where the last change and
1228    /// the current change tick are given.
1229    ///
1230    /// This iterator is always guaranteed to return results from each matching entity once and only once.
1231    /// Iteration order is not guaranteed.
1232    ///
1233    /// # Safety
1234    ///
1235    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
1236    /// have unique access to the components they query.
1237    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
1238    /// with a mismatched [`WorldId`] is unsound.
1239    #[inline]
1240    pub(crate) unsafe fn iter_unchecked_manual<'w, 's>(
1241        &'s self,
1242        world: UnsafeWorldCell<'w>,
1243        last_run: Tick,
1244        this_run: Tick,
1245    ) -> QueryIter<'w, 's, D, F> {
1246        QueryIter::new(world, self, last_run, this_run)
1247    }
1248
1249    /// Returns an [`Iterator`] for the given [`World`] and list of [`Entity`]'s, where the last change and
1250    /// the current change tick are given.
1251    ///
1252    /// This iterator is always guaranteed to return results from each unique pair of matching entities.
1253    /// Iteration order is not guaranteed.
1254    ///
1255    /// # Safety
1256    ///
1257    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
1258    /// have unique access to the components they query.
1259    /// This does not check for entity uniqueness
1260    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
1261    /// with a mismatched [`WorldId`] is unsound.
1262    #[inline]
1263    pub(crate) unsafe fn iter_many_unchecked_manual<'w, 's, EntityList: IntoIterator>(
1264        &'s self,
1265        entities: EntityList,
1266        world: UnsafeWorldCell<'w>,
1267        last_run: Tick,
1268        this_run: Tick,
1269    ) -> QueryManyIter<'w, 's, D, F, EntityList::IntoIter>
1270    where
1271        EntityList::Item: Borrow<Entity>,
1272    {
1273        QueryManyIter::new(world, self, entities, last_run, this_run)
1274    }
1275
1276    /// Returns an [`Iterator`] over all possible combinations of `K` query results for the
1277    /// given [`World`] without repetition.
1278    /// This can only be called for read-only queries.
1279    ///
1280    /// This iterator is always guaranteed to return results from each unique pair of matching entities.
1281    /// Iteration order is not guaranteed.
1282    ///
1283    /// # Safety
1284    ///
1285    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
1286    /// have unique access to the components they query.
1287    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
1288    /// with a mismatched [`WorldId`] is unsound.
1289    #[inline]
1290    pub(crate) unsafe fn iter_combinations_unchecked_manual<'w, 's, const K: usize>(
1291        &'s self,
1292        world: UnsafeWorldCell<'w>,
1293        last_run: Tick,
1294        this_run: Tick,
1295    ) -> QueryCombinationIter<'w, 's, D, F, K> {
1296        QueryCombinationIter::new(world, self, last_run, this_run)
1297    }
1298
1299    /// Returns a parallel iterator over the query results for the given [`World`].
1300    ///
1301    /// This can only be called for read-only queries, see [`par_iter_mut`] for write-queries.
1302    ///
1303    /// Note that you must use the `for_each` method to iterate over the
1304    /// results, see [`par_iter_mut`] for an example.
1305    ///
1306    /// [`par_iter_mut`]: Self::par_iter_mut
1307    #[inline]
1308    pub fn par_iter<'w, 's>(
1309        &'s mut self,
1310        world: &'w World,
1311    ) -> QueryParIter<'w, 's, D::ReadOnly, F> {
1312        self.update_archetypes(world);
1313        QueryParIter {
1314            world: world.as_unsafe_world_cell_readonly(),
1315            state: self.as_readonly(),
1316            last_run: world.last_change_tick(),
1317            this_run: world.read_change_tick(),
1318            batching_strategy: BatchingStrategy::new(),
1319        }
1320    }
1321
1322    /// Returns a parallel iterator over the query results for the given [`World`].
1323    ///
1324    /// This can only be called for mutable queries, see [`par_iter`] for read-only-queries.
1325    ///
1326    /// # Examples
1327    ///
1328    /// ```
1329    /// use bevy_ecs::prelude::*;
1330    /// use bevy_ecs::query::QueryEntityError;
1331    ///
1332    /// #[derive(Component, PartialEq, Debug)]
1333    /// struct A(usize);
1334    ///
1335    /// # bevy_tasks::ComputeTaskPool::get_or_init(|| bevy_tasks::TaskPool::new());
1336    ///
1337    /// let mut world = World::new();
1338    ///
1339    /// # let entities: Vec<Entity> = (0..3).map(|i| world.spawn(A(i)).id()).collect();
1340    /// # let entities: [Entity; 3] = entities.try_into().unwrap();
1341    ///
1342    /// let mut query_state = world.query::<&mut A>();
1343    ///
1344    /// query_state.par_iter_mut(&mut world).for_each(|mut a| {
1345    ///     a.0 += 5;
1346    /// });
1347    ///
1348    /// # let component_values = query_state.get_many(&world, entities).unwrap();
1349    ///
1350    /// # assert_eq!(component_values, [&A(5), &A(6), &A(7)]);
1351    ///
1352    /// # let wrong_entity = Entity::from_raw(57);
1353    /// # let invalid_entity = world.spawn_empty().id();
1354    ///
1355    /// # assert_eq!(query_state.get_many_mut(&mut world, [wrong_entity]).unwrap_err(), QueryEntityError::NoSuchEntity(wrong_entity));
1356    /// # assert_eq!(query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err(), QueryEntityError::QueryDoesNotMatch(invalid_entity));
1357    /// # assert_eq!(query_state.get_many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0]));
1358    /// ```
1359    ///
1360    /// # Panics
1361    /// The [`ComputeTaskPool`] is not initialized. If using this from a query that is being
1362    /// initialized and run from the ECS scheduler, this should never panic.
1363    ///
1364    /// [`par_iter`]: Self::par_iter
1365    /// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
1366    #[inline]
1367    pub fn par_iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryParIter<'w, 's, D, F> {
1368        self.update_archetypes(world);
1369        let this_run = world.change_tick();
1370        let last_run = world.last_change_tick();
1371        QueryParIter {
1372            world: world.as_unsafe_world_cell(),
1373            state: self,
1374            last_run,
1375            this_run,
1376            batching_strategy: BatchingStrategy::new(),
1377        }
1378    }
1379
1380    /// Runs `func` on each query result in parallel for the given [`World`], where the last change and
1381    /// the current change tick are given. This is faster than the equivalent
1382    /// `iter()` method, but cannot be chained like a normal [`Iterator`].
1383    ///
1384    /// # Panics
1385    /// The [`ComputeTaskPool`] is not initialized. If using this from a query that is being
1386    /// initialized and run from the ECS scheduler, this should never panic.
1387    ///
1388    /// # Safety
1389    ///
1390    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
1391    /// have unique access to the components they query.
1392    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
1393    /// with a mismatched [`WorldId`] is unsound.
1394    ///
1395    /// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
1396    #[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]
1397    pub(crate) unsafe fn par_fold_init_unchecked_manual<'w, T, FN, INIT>(
1398        &self,
1399        init_accum: INIT,
1400        world: UnsafeWorldCell<'w>,
1401        batch_size: usize,
1402        func: FN,
1403        last_run: Tick,
1404        this_run: Tick,
1405    ) where
1406        FN: Fn(T, D::Item<'w>) -> T + Send + Sync + Clone,
1407        INIT: Fn() -> T + Sync + Send + Clone,
1408    {
1409        // NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
1410        // QueryIter, QueryIterationCursor, QueryManyIter, QueryCombinationIter,QueryState::par_fold_init_unchecked_manual
1411        use arrayvec::ArrayVec;
1412
1413        bevy_tasks::ComputeTaskPool::get().scope(|scope| {
1414            // SAFETY: We only access table data that has been registered in `self.archetype_component_access`.
1415            let tables = unsafe { &world.storages().tables };
1416            let archetypes = world.archetypes();
1417            let mut batch_queue = ArrayVec::new();
1418            let mut queue_entity_count = 0;
1419
1420            // submit a list of storages which smaller than batch_size as single task
1421            let submit_batch_queue = |queue: &mut ArrayVec<StorageId, 128>| {
1422                if queue.is_empty() {
1423                    return;
1424                }
1425                let queue = std::mem::take(queue);
1426                let mut func = func.clone();
1427                let init_accum = init_accum.clone();
1428                scope.spawn(async move {
1429                    #[cfg(feature = "trace")]
1430                    let _span = self.par_iter_span.enter();
1431                    let mut iter = self.iter_unchecked_manual(world, last_run, this_run);
1432                    let mut accum = init_accum();
1433                    for storage_id in queue {
1434                        if D::IS_DENSE && F::IS_DENSE {
1435                            let id = storage_id.table_id;
1436                            let table = &world.storages().tables.get(id).debug_checked_unwrap();
1437                            accum = iter.fold_over_table_range(
1438                                accum,
1439                                &mut func,
1440                                table,
1441                                0..table.entity_count(),
1442                            );
1443                        } else {
1444                            let id = storage_id.archetype_id;
1445                            let archetype = world.archetypes().get(id).debug_checked_unwrap();
1446                            accum = iter.fold_over_archetype_range(
1447                                accum,
1448                                &mut func,
1449                                archetype,
1450                                0..archetype.len(),
1451                            );
1452                        }
1453                    }
1454                });
1455            };
1456
1457            // submit single storage larger than batch_size
1458            let submit_single = |count, storage_id: StorageId| {
1459                for offset in (0..count).step_by(batch_size) {
1460                    let mut func = func.clone();
1461                    let init_accum = init_accum.clone();
1462                    let len = batch_size.min(count - offset);
1463                    let batch = offset..offset + len;
1464                    scope.spawn(async move {
1465                        #[cfg(feature = "trace")]
1466                        let _span = self.par_iter_span.enter();
1467                        let accum = init_accum();
1468                        if D::IS_DENSE && F::IS_DENSE {
1469                            let id = storage_id.table_id;
1470                            let table = world.storages().tables.get(id).debug_checked_unwrap();
1471                            self.iter_unchecked_manual(world, last_run, this_run)
1472                                .fold_over_table_range(accum, &mut func, table, batch);
1473                        } else {
1474                            let id = storage_id.archetype_id;
1475                            let archetype = world.archetypes().get(id).debug_checked_unwrap();
1476                            self.iter_unchecked_manual(world, last_run, this_run)
1477                                .fold_over_archetype_range(accum, &mut func, archetype, batch);
1478                        }
1479                    });
1480                }
1481            };
1482
1483            let storage_entity_count = |storage_id: StorageId| -> usize {
1484                if D::IS_DENSE && F::IS_DENSE {
1485                    tables[storage_id.table_id].entity_count()
1486                } else {
1487                    archetypes[storage_id.archetype_id].len()
1488                }
1489            };
1490
1491            for storage_id in &self.matched_storage_ids {
1492                let count = storage_entity_count(*storage_id);
1493
1494                // skip empty storage
1495                if count == 0 {
1496                    continue;
1497                }
1498                // immediately submit large storage
1499                if count >= batch_size {
1500                    submit_single(count, *storage_id);
1501                    continue;
1502                }
1503                // merge small storage
1504                batch_queue.push(*storage_id);
1505                queue_entity_count += count;
1506
1507                // submit batch_queue
1508                if queue_entity_count >= batch_size || batch_queue.is_full() {
1509                    submit_batch_queue(&mut batch_queue);
1510                    queue_entity_count = 0;
1511                }
1512            }
1513            submit_batch_queue(&mut batch_queue);
1514        });
1515    }
1516
1517    /// Returns a single immutable query result when there is exactly one entity matching
1518    /// the query.
1519    ///
1520    /// This can only be called for read-only queries,
1521    /// see [`single_mut`](Self::single_mut) for write-queries.
1522    ///
1523    /// # Panics
1524    ///
1525    /// Panics if the number of query results is not exactly one. Use
1526    /// [`get_single`](Self::get_single) to return a `Result` instead of panicking.
1527    #[track_caller]
1528    #[inline]
1529    pub fn single<'w>(&mut self, world: &'w World) -> ROQueryItem<'w, D> {
1530        match self.get_single(world) {
1531            Ok(items) => items,
1532            Err(error) => panic!("Cannot get single mutable query result: {error}"),
1533        }
1534    }
1535
1536    /// Returns a single immutable query result when there is exactly one entity matching
1537    /// the query.
1538    ///
1539    /// This can only be called for read-only queries,
1540    /// see [`get_single_mut`](Self::get_single_mut) for write-queries.
1541    ///
1542    /// If the number of query results is not exactly one, a [`QuerySingleError`] is returned
1543    /// instead.
1544    #[inline]
1545    pub fn get_single<'w>(
1546        &mut self,
1547        world: &'w World,
1548    ) -> Result<ROQueryItem<'w, D>, QuerySingleError> {
1549        self.update_archetypes(world);
1550
1551        // SAFETY: query is read only
1552        unsafe {
1553            self.as_readonly().get_single_unchecked_manual(
1554                world.as_unsafe_world_cell_readonly(),
1555                world.last_change_tick(),
1556                world.read_change_tick(),
1557            )
1558        }
1559    }
1560
1561    /// Returns a single mutable query result when there is exactly one entity matching
1562    /// the query.
1563    ///
1564    /// # Panics
1565    ///
1566    /// Panics if the number of query results is not exactly one. Use
1567    /// [`get_single_mut`](Self::get_single_mut) to return a `Result` instead of panicking.
1568    #[track_caller]
1569    #[inline]
1570    pub fn single_mut<'w>(&mut self, world: &'w mut World) -> D::Item<'w> {
1571        // SAFETY: query has unique world access
1572        match self.get_single_mut(world) {
1573            Ok(items) => items,
1574            Err(error) => panic!("Cannot get single query result: {error}"),
1575        }
1576    }
1577
1578    /// Returns a single mutable query result when there is exactly one entity matching
1579    /// the query.
1580    ///
1581    /// If the number of query results is not exactly one, a [`QuerySingleError`] is returned
1582    /// instead.
1583    #[inline]
1584    pub fn get_single_mut<'w>(
1585        &mut self,
1586        world: &'w mut World,
1587    ) -> Result<D::Item<'w>, QuerySingleError> {
1588        self.update_archetypes(world);
1589
1590        let change_tick = world.change_tick();
1591        let last_change_tick = world.last_change_tick();
1592        // SAFETY: query has unique world access
1593        unsafe {
1594            self.get_single_unchecked_manual(
1595                world.as_unsafe_world_cell(),
1596                last_change_tick,
1597                change_tick,
1598            )
1599        }
1600    }
1601
1602    /// Returns a query result when there is exactly one entity matching the query.
1603    ///
1604    /// If the number of query results is not exactly one, a [`QuerySingleError`] is returned
1605    /// instead.
1606    ///
1607    /// # Safety
1608    ///
1609    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
1610    /// have unique access to the components they query.
1611    #[inline]
1612    pub unsafe fn get_single_unchecked<'w>(
1613        &mut self,
1614        world: UnsafeWorldCell<'w>,
1615    ) -> Result<D::Item<'w>, QuerySingleError> {
1616        self.update_archetypes_unsafe_world_cell(world);
1617        self.get_single_unchecked_manual(world, world.last_change_tick(), world.change_tick())
1618    }
1619
1620    /// Returns a query result when there is exactly one entity matching the query,
1621    /// where the last change and the current change tick are given.
1622    ///
1623    /// If the number of query results is not exactly one, a [`QuerySingleError`] is returned
1624    /// instead.
1625    ///
1626    /// # Safety
1627    ///
1628    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
1629    /// have unique access to the components they query.
1630    #[inline]
1631    pub unsafe fn get_single_unchecked_manual<'w>(
1632        &self,
1633        world: UnsafeWorldCell<'w>,
1634        last_run: Tick,
1635        this_run: Tick,
1636    ) -> Result<D::Item<'w>, QuerySingleError> {
1637        let mut query = self.iter_unchecked_manual(world, last_run, this_run);
1638        let first = query.next();
1639        let extra = query.next().is_some();
1640
1641        match (first, extra) {
1642            (Some(r), false) => Ok(r),
1643            (None, _) => Err(QuerySingleError::NoEntities(std::any::type_name::<Self>())),
1644            (Some(_), _) => Err(QuerySingleError::MultipleEntities(std::any::type_name::<
1645                Self,
1646            >())),
1647        }
1648    }
1649}
1650
1651impl<D: QueryData, F: QueryFilter> From<QueryBuilder<'_, D, F>> for QueryState<D, F> {
1652    fn from(mut value: QueryBuilder<D, F>) -> Self {
1653        QueryState::from_builder(&mut value)
1654    }
1655}
1656
1657#[cfg(test)]
1658mod tests {
1659    use crate as bevy_ecs;
1660    use crate::world::FilteredEntityRef;
1661    use crate::{component::Component, prelude::*, query::QueryEntityError};
1662
1663    #[test]
1664    fn get_many_unchecked_manual_uniqueness() {
1665        let mut world = World::new();
1666
1667        let entities: Vec<Entity> = (0..10).map(|_| world.spawn_empty().id()).collect();
1668
1669        let query_state = world.query::<Entity>();
1670
1671        // These don't matter for the test
1672        let last_change_tick = world.last_change_tick();
1673        let change_tick = world.change_tick();
1674
1675        // It's best to test get_many_unchecked_manual directly,
1676        // as it is shared and unsafe
1677        // We don't care about aliased mutability for the read-only equivalent
1678
1679        // SAFETY: Query does not access world data.
1680        assert!(unsafe {
1681            query_state
1682                .get_many_unchecked_manual::<10>(
1683                    world.as_unsafe_world_cell_readonly(),
1684                    entities.clone().try_into().unwrap(),
1685                    last_change_tick,
1686                    change_tick,
1687                )
1688                .is_ok()
1689        });
1690
1691        assert_eq!(
1692            // SAFETY: Query does not access world data.
1693            unsafe {
1694                query_state
1695                    .get_many_unchecked_manual(
1696                        world.as_unsafe_world_cell_readonly(),
1697                        [entities[0], entities[0]],
1698                        last_change_tick,
1699                        change_tick,
1700                    )
1701                    .unwrap_err()
1702            },
1703            QueryEntityError::AliasedMutability(entities[0])
1704        );
1705
1706        assert_eq!(
1707            // SAFETY: Query does not access world data.
1708            unsafe {
1709                query_state
1710                    .get_many_unchecked_manual(
1711                        world.as_unsafe_world_cell_readonly(),
1712                        [entities[0], entities[1], entities[0]],
1713                        last_change_tick,
1714                        change_tick,
1715                    )
1716                    .unwrap_err()
1717            },
1718            QueryEntityError::AliasedMutability(entities[0])
1719        );
1720
1721        assert_eq!(
1722            // SAFETY: Query does not access world data.
1723            unsafe {
1724                query_state
1725                    .get_many_unchecked_manual(
1726                        world.as_unsafe_world_cell_readonly(),
1727                        [entities[9], entities[9]],
1728                        last_change_tick,
1729                        change_tick,
1730                    )
1731                    .unwrap_err()
1732            },
1733            QueryEntityError::AliasedMutability(entities[9])
1734        );
1735    }
1736
1737    #[test]
1738    #[should_panic]
1739    fn right_world_get() {
1740        let mut world_1 = World::new();
1741        let world_2 = World::new();
1742
1743        let mut query_state = world_1.query::<Entity>();
1744        let _panics = query_state.get(&world_2, Entity::from_raw(0));
1745    }
1746
1747    #[test]
1748    #[should_panic]
1749    fn right_world_get_many() {
1750        let mut world_1 = World::new();
1751        let world_2 = World::new();
1752
1753        let mut query_state = world_1.query::<Entity>();
1754        let _panics = query_state.get_many(&world_2, []);
1755    }
1756
1757    #[test]
1758    #[should_panic]
1759    fn right_world_get_many_mut() {
1760        let mut world_1 = World::new();
1761        let mut world_2 = World::new();
1762
1763        let mut query_state = world_1.query::<Entity>();
1764        let _panics = query_state.get_many_mut(&mut world_2, []);
1765    }
1766
1767    #[derive(Component, PartialEq, Debug)]
1768    struct A(usize);
1769
1770    #[derive(Component, PartialEq, Debug)]
1771    struct B(usize);
1772
1773    #[derive(Component, PartialEq, Debug)]
1774    struct C(usize);
1775
1776    #[test]
1777    fn can_transmute_to_more_general() {
1778        let mut world = World::new();
1779        world.spawn((A(1), B(0)));
1780
1781        let query_state = world.query::<(&A, &B)>();
1782        let mut new_query_state = query_state.transmute::<&A>(world.components());
1783        assert_eq!(new_query_state.iter(&world).len(), 1);
1784        let a = new_query_state.single(&world);
1785
1786        assert_eq!(a.0, 1);
1787    }
1788
1789    #[test]
1790    fn cannot_get_data_not_in_original_query() {
1791        let mut world = World::new();
1792        world.spawn((A(0), B(0)));
1793        world.spawn((A(1), B(0), C(0)));
1794
1795        let query_state = world.query_filtered::<(&A, &B), Without<C>>();
1796        let mut new_query_state = query_state.transmute::<&A>(world.components());
1797        // even though we change the query to not have Without<C>, we do not get the component with C.
1798        let a = new_query_state.single(&world);
1799
1800        assert_eq!(a.0, 0);
1801    }
1802
1803    #[test]
1804    fn can_transmute_empty_tuple() {
1805        let mut world = World::new();
1806        world.init_component::<A>();
1807        let entity = world.spawn(A(10)).id();
1808
1809        let q = world.query::<()>();
1810        let mut q = q.transmute::<Entity>(world.components());
1811        assert_eq!(q.single(&world), entity);
1812    }
1813
1814    #[test]
1815    fn can_transmute_immut_fetch() {
1816        let mut world = World::new();
1817        world.spawn(A(10));
1818
1819        let q = world.query::<&A>();
1820        let mut new_q = q.transmute::<Ref<A>>(world.components());
1821        assert!(new_q.single(&world).is_added());
1822
1823        let q = world.query::<Ref<A>>();
1824        let _ = q.transmute::<&A>(world.components());
1825    }
1826
1827    #[test]
1828    fn can_transmute_mut_fetch() {
1829        let mut world = World::new();
1830        world.spawn(A(0));
1831
1832        let q = world.query::<&mut A>();
1833        let _ = q.transmute::<Ref<A>>(world.components());
1834        let _ = q.transmute::<&A>(world.components());
1835    }
1836
1837    #[test]
1838    fn can_transmute_entity_mut() {
1839        let mut world = World::new();
1840        world.spawn(A(0));
1841
1842        let q: QueryState<EntityMut<'_>> = world.query::<EntityMut>();
1843        let _ = q.transmute::<EntityRef>(world.components());
1844    }
1845
1846    #[test]
1847    fn can_generalize_with_option() {
1848        let mut world = World::new();
1849        world.spawn((A(0), B(0)));
1850
1851        let query_state = world.query::<(Option<&A>, &B)>();
1852        let _ = query_state.transmute::<Option<&A>>(world.components());
1853        let _ = query_state.transmute::<&B>(world.components());
1854    }
1855
1856    #[test]
1857    #[should_panic(
1858        expected = "Transmuted state for ((&bevy_ecs::query::state::tests::A, &bevy_ecs::query::state::tests::B), ()) attempts to access terms that are not allowed by original state (&bevy_ecs::query::state::tests::A, ())."
1859    )]
1860    fn cannot_transmute_to_include_data_not_in_original_query() {
1861        let mut world = World::new();
1862        world.init_component::<A>();
1863        world.init_component::<B>();
1864        world.spawn(A(0));
1865
1866        let query_state = world.query::<&A>();
1867        let mut _new_query_state = query_state.transmute::<(&A, &B)>(world.components());
1868    }
1869
1870    #[test]
1871    #[should_panic(
1872        expected = "Transmuted state for (&mut bevy_ecs::query::state::tests::A, ()) attempts to access terms that are not allowed by original state (&bevy_ecs::query::state::tests::A, ())."
1873    )]
1874    fn cannot_transmute_immut_to_mut() {
1875        let mut world = World::new();
1876        world.spawn(A(0));
1877
1878        let query_state = world.query::<&A>();
1879        let mut _new_query_state = query_state.transmute::<&mut A>(world.components());
1880    }
1881
1882    #[test]
1883    #[should_panic(
1884        expected = "Transmuted state for (&bevy_ecs::query::state::tests::A, ()) attempts to access terms that are not allowed by original state (core::option::Option<&bevy_ecs::query::state::tests::A>, ())."
1885    )]
1886    fn cannot_transmute_option_to_immut() {
1887        let mut world = World::new();
1888        world.spawn(C(0));
1889
1890        let query_state = world.query::<Option<&A>>();
1891        let mut new_query_state = query_state.transmute::<&A>(world.components());
1892        let x = new_query_state.single(&world);
1893        assert_eq!(x.0, 1234);
1894    }
1895
1896    #[test]
1897    #[should_panic(
1898        expected = "Transmuted state for (&bevy_ecs::query::state::tests::A, ()) attempts to access terms that are not allowed by original state (bevy_ecs::world::entity_ref::EntityRef, ())."
1899    )]
1900    fn cannot_transmute_entity_ref() {
1901        let mut world = World::new();
1902        world.init_component::<A>();
1903
1904        let q = world.query::<EntityRef>();
1905        let _ = q.transmute::<&A>(world.components());
1906    }
1907
1908    #[test]
1909    fn can_transmute_filtered_entity() {
1910        let mut world = World::new();
1911        let entity = world.spawn((A(0), B(1))).id();
1912        let query = QueryState::<(Entity, &A, &B)>::new(&mut world)
1913            .transmute::<FilteredEntityRef>(world.components());
1914
1915        let mut query = query;
1916        // Our result is completely untyped
1917        let entity_ref = query.single(&world);
1918
1919        assert_eq!(entity, entity_ref.id());
1920        assert_eq!(0, entity_ref.get::<A>().unwrap().0);
1921        assert_eq!(1, entity_ref.get::<B>().unwrap().0);
1922    }
1923
1924    #[test]
1925    fn can_transmute_added() {
1926        let mut world = World::new();
1927        let entity_a = world.spawn(A(0)).id();
1928
1929        let mut query = QueryState::<(Entity, &A, Has<B>)>::new(&mut world)
1930            .transmute_filtered::<(Entity, Has<B>), Added<A>>(world.components());
1931
1932        assert_eq!((entity_a, false), query.single(&world));
1933
1934        world.clear_trackers();
1935
1936        let entity_b = world.spawn((A(0), B(0))).id();
1937        assert_eq!((entity_b, true), query.single(&world));
1938
1939        world.clear_trackers();
1940
1941        assert!(query.get_single(&world).is_err());
1942    }
1943
1944    #[test]
1945    fn can_transmute_changed() {
1946        let mut world = World::new();
1947        let entity_a = world.spawn(A(0)).id();
1948
1949        let mut detection_query = QueryState::<(Entity, &A)>::new(&mut world)
1950            .transmute_filtered::<Entity, Changed<A>>(world.components());
1951
1952        let mut change_query = QueryState::<&mut A>::new(&mut world);
1953        assert_eq!(entity_a, detection_query.single(&world));
1954
1955        world.clear_trackers();
1956
1957        assert!(detection_query.get_single(&world).is_err());
1958
1959        change_query.single_mut(&mut world).0 = 1;
1960
1961        assert_eq!(entity_a, detection_query.single(&world));
1962    }
1963
1964    #[test]
1965    #[should_panic(
1966        expected = "Transmuted state for (bevy_ecs::entity::Entity, bevy_ecs::query::filter::Changed<bevy_ecs::query::state::tests::B>) attempts to access terms that are not allowed by original state (&bevy_ecs::query::state::tests::A, ())."
1967    )]
1968    fn cannot_transmute_changed_without_access() {
1969        let mut world = World::new();
1970        world.init_component::<A>();
1971        world.init_component::<B>();
1972        let query = QueryState::<&A>::new(&mut world);
1973        let _new_query = query.transmute_filtered::<Entity, Changed<B>>(world.components());
1974    }
1975
1976    #[test]
1977    fn join() {
1978        let mut world = World::new();
1979        world.spawn(A(0));
1980        world.spawn(B(1));
1981        let entity_ab = world.spawn((A(2), B(3))).id();
1982        world.spawn((A(4), B(5), C(6)));
1983
1984        let query_1 = QueryState::<&A, Without<C>>::new(&mut world);
1985        let query_2 = QueryState::<&B, Without<C>>::new(&mut world);
1986        let mut new_query: QueryState<Entity, ()> =
1987            query_1.join_filtered(world.components(), &query_2);
1988
1989        assert_eq!(new_query.single(&world), entity_ab);
1990    }
1991
1992    #[test]
1993    fn join_with_get() {
1994        let mut world = World::new();
1995        world.spawn(A(0));
1996        world.spawn(B(1));
1997        let entity_ab = world.spawn((A(2), B(3))).id();
1998        let entity_abc = world.spawn((A(4), B(5), C(6))).id();
1999
2000        let query_1 = QueryState::<&A>::new(&mut world);
2001        let query_2 = QueryState::<&B, Without<C>>::new(&mut world);
2002        let mut new_query: QueryState<Entity, ()> =
2003            query_1.join_filtered(world.components(), &query_2);
2004
2005        assert!(new_query.get(&world, entity_ab).is_ok());
2006        // should not be able to get entity with c.
2007        assert!(new_query.get(&world, entity_abc).is_err());
2008    }
2009
2010    #[test]
2011    #[should_panic(expected = "Joined state for (&bevy_ecs::query::state::tests::C, ()) \
2012            attempts to access terms that are not allowed by state \
2013            (&bevy_ecs::query::state::tests::A, ()) joined with (&bevy_ecs::query::state::tests::B, ()).")]
2014    fn cannot_join_wrong_fetch() {
2015        let mut world = World::new();
2016        world.init_component::<C>();
2017        let query_1 = QueryState::<&A>::new(&mut world);
2018        let query_2 = QueryState::<&B>::new(&mut world);
2019        let _query: QueryState<&C> = query_1.join(world.components(), &query_2);
2020    }
2021
2022    #[test]
2023    #[should_panic(
2024        expected = "Joined state for (bevy_ecs::entity::Entity, bevy_ecs::query::filter::Changed<bevy_ecs::query::state::tests::C>) \
2025            attempts to access terms that are not allowed by state \
2026            (&bevy_ecs::query::state::tests::A, bevy_ecs::query::filter::Without<bevy_ecs::query::state::tests::C>) \
2027            joined with (&bevy_ecs::query::state::tests::B, bevy_ecs::query::filter::Without<bevy_ecs::query::state::tests::C>)."
2028    )]
2029    fn cannot_join_wrong_filter() {
2030        let mut world = World::new();
2031        let query_1 = QueryState::<&A, Without<C>>::new(&mut world);
2032        let query_2 = QueryState::<&B, Without<C>>::new(&mut world);
2033        let _: QueryState<Entity, Changed<C>> = query_1.join_filtered(world.components(), &query_2);
2034    }
2035}