remove QF generics from all Query/State methods and types (#5170)
				
					
				
			# Objective remove `QF` generics from a bunch of types and methods on query related items. this has a few benefits: - simplifies type signatures `fn iter(&self) -> QueryIter<'_, 's, Q::ReadOnly, F::ReadOnly>` is (imo) conceptually simpler than `fn iter(&self) -> QueryIter<'_, 's, Q, ROQueryFetch<'_, Q>, F>` - `Fetch` is mostly an implementation detail but previously we had to expose it on every `iter` `get` etc method - Allows us to potentially in the future simplify the `WorldQuery` trait hierarchy by removing the `Fetch` trait ## Solution remove the `QF` generic and add a way to (unsafely) turn `&QueryState<Q1, F1>` into `&QueryState<Q2, F2>` --- ## Changelog/Migration Guide The `QF` generic was removed from various `Query` iterator types and some methods, you should update your code to use the type of the corresponding worldquery of the fetch type that was being used, or call `as_readonly`/`as_nop` to convert a querystate to the appropriate type. For example: `.get_single_unchecked_manual::<ROQueryFetch<Q>>(..)` -> `.as_readonly().get_single_unchecked_manual(..)` `my_field: QueryIter<'w, 's, Q, ROQueryFetch<'w, Q>, F>` -> `my_field: QueryIter<'w, 's, Q::ReadOnly, F::ReadOnly>`
This commit is contained in:
		
							parent
							
								
									4affc8cd93
								
							
						
					
					
						commit
						1ac8a476cf
					
				@ -318,7 +318,8 @@ use std::{cell::UnsafeCell, marker::PhantomData};
 | 
				
			|||||||
/// ```
 | 
					/// ```
 | 
				
			||||||
/// # Safety
 | 
					/// # Safety
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// component access of `ROQueryFetch<Self>` should be a subset of `QueryFetch<Self>`
 | 
					/// component access of `ROQueryFetch<Self>` must be a subset of `QueryFetch<Self>`
 | 
				
			||||||
 | 
					/// and `ROQueryFetch<Self>` must match exactly the same archetypes/tables as `QueryFetch<Self>`
 | 
				
			||||||
pub unsafe trait WorldQuery: for<'w> WorldQueryGats<'w, _State = Self::State> {
 | 
					pub unsafe trait WorldQuery: for<'w> WorldQueryGats<'w, _State = Self::State> {
 | 
				
			||||||
    type ReadOnly: ReadOnlyWorldQuery<State = Self::State>;
 | 
					    type ReadOnly: ReadOnlyWorldQuery<State = Self::State>;
 | 
				
			||||||
    type State: FetchState;
 | 
					    type State: FetchState;
 | 
				
			||||||
@ -1608,6 +1609,25 @@ macro_rules! impl_anytuple_fetch {
 | 
				
			|||||||
all_tuples!(impl_tuple_fetch, 0, 15, F, S);
 | 
					all_tuples!(impl_tuple_fetch, 0, 15, F, S);
 | 
				
			||||||
all_tuples!(impl_anytuple_fetch, 0, 15, F, S);
 | 
					all_tuples!(impl_anytuple_fetch, 0, 15, F, S);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// [`WorldQuery`] used to nullify queries by turning `Query<Q>` into `Query<NopWorldQuery<Q>>`
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// This will rarely be useful to consumers of `bevy_ecs`.
 | 
				
			||||||
 | 
					pub struct NopWorldQuery<Q: WorldQuery>(PhantomData<Q>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// SAFETY: `Self::ReadOnly` is `Self`
 | 
				
			||||||
 | 
					unsafe impl<Q: WorldQuery> WorldQuery for NopWorldQuery<Q> {
 | 
				
			||||||
 | 
					    type ReadOnly = Self;
 | 
				
			||||||
 | 
					    type State = Q::State;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn shrink<'wlong: 'wshort, 'wshort>(_: ()) {}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					impl<'a, Q: WorldQuery> WorldQueryGats<'a> for NopWorldQuery<Q> {
 | 
				
			||||||
 | 
					    type Fetch = NopFetch<QueryFetch<'a, Q>>;
 | 
				
			||||||
 | 
					    type _State = <Q as WorldQueryGats<'a>>::_State;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					/// SAFETY: `NopFetch` never accesses any data
 | 
				
			||||||
 | 
					unsafe impl<Q: WorldQuery> ReadOnlyWorldQuery for NopWorldQuery<Q> {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// [`Fetch`] that does not actually fetch anything
 | 
					/// [`Fetch`] that does not actually fetch anything
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// Mostly useful when something is generic over the Fetch and you don't want to fetch as you will discard the result
 | 
					/// Mostly useful when something is generic over the Fetch and you don't want to fetch as you will discard the result
 | 
				
			||||||
@ -1616,18 +1636,18 @@ pub struct NopFetch<State> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SAFETY: NopFetch doesnt access anything
 | 
					// SAFETY: NopFetch doesnt access anything
 | 
				
			||||||
unsafe impl<'w, State: FetchState> Fetch<'w> for NopFetch<State> {
 | 
					unsafe impl<'w, F: Fetch<'w>> Fetch<'w> for NopFetch<F> {
 | 
				
			||||||
    type Item = ();
 | 
					    type Item = ();
 | 
				
			||||||
    type State = State;
 | 
					    type State = F::State;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const IS_DENSE: bool = true;
 | 
					    const IS_DENSE: bool = F::IS_DENSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const IS_ARCHETYPAL: bool = true;
 | 
					    const IS_ARCHETYPAL: bool = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline(always)]
 | 
					    #[inline(always)]
 | 
				
			||||||
    unsafe fn init(
 | 
					    unsafe fn init(
 | 
				
			||||||
        _world: &'w World,
 | 
					        _world: &'w World,
 | 
				
			||||||
        _state: &State,
 | 
					        _state: &F::State,
 | 
				
			||||||
        _last_change_tick: u32,
 | 
					        _last_change_tick: u32,
 | 
				
			||||||
        _change_tick: u32,
 | 
					        _change_tick: u32,
 | 
				
			||||||
    ) -> Self {
 | 
					    ) -> Self {
 | 
				
			||||||
 | 
				
			|||||||
@ -13,17 +13,14 @@ use super::{QueryFetch, QueryItem, ReadOnlyWorldQuery};
 | 
				
			|||||||
///
 | 
					///
 | 
				
			||||||
/// This struct is created by the [`Query::iter`](crate::system::Query::iter) and
 | 
					/// This struct is created by the [`Query::iter`](crate::system::Query::iter) and
 | 
				
			||||||
/// [`Query::iter_mut`](crate::system::Query::iter_mut) methods.
 | 
					/// [`Query::iter_mut`](crate::system::Query::iter_mut) methods.
 | 
				
			||||||
pub struct QueryIter<'w, 's, Q: WorldQuery, QF: Fetch<'w, State = Q::State>, F: WorldQuery> {
 | 
					pub struct QueryIter<'w, 's, Q: WorldQuery, F: WorldQuery> {
 | 
				
			||||||
    tables: &'w Tables,
 | 
					    tables: &'w Tables,
 | 
				
			||||||
    archetypes: &'w Archetypes,
 | 
					    archetypes: &'w Archetypes,
 | 
				
			||||||
    query_state: &'s QueryState<Q, F>,
 | 
					    query_state: &'s QueryState<Q, F>,
 | 
				
			||||||
    cursor: QueryIterationCursor<'w, 's, Q, QF, F>,
 | 
					    cursor: QueryIterationCursor<'w, 's, Q, F>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'w, 's, Q: WorldQuery, QF, F: WorldQuery> QueryIter<'w, 's, Q, QF, F>
 | 
					impl<'w, 's, Q: WorldQuery, F: WorldQuery> QueryIter<'w, 's, Q, F> {
 | 
				
			||||||
where
 | 
					 | 
				
			||||||
    QF: Fetch<'w, State = Q::State>,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    /// # Safety
 | 
					    /// # Safety
 | 
				
			||||||
    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
 | 
					    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
 | 
				
			||||||
    /// have unique access to the components they query.
 | 
					    /// have unique access to the components they query.
 | 
				
			||||||
@ -44,11 +41,8 @@ where
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'w, 's, Q: WorldQuery, QF, F: WorldQuery> Iterator for QueryIter<'w, 's, Q, QF, F>
 | 
					impl<'w, 's, Q: WorldQuery, F: WorldQuery> Iterator for QueryIter<'w, 's, Q, F> {
 | 
				
			||||||
where
 | 
					    type Item = QueryItem<'w, Q>;
 | 
				
			||||||
    QF: Fetch<'w, State = Q::State>,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    type Item = QF::Item;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline(always)]
 | 
					    #[inline(always)]
 | 
				
			||||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
					    fn next(&mut self) -> Option<Self::Item> {
 | 
				
			||||||
@ -69,42 +63,32 @@ where
 | 
				
			|||||||
            .map(|id| self.archetypes[*id].len())
 | 
					            .map(|id| self.archetypes[*id].len())
 | 
				
			||||||
            .sum();
 | 
					            .sum();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let archetype_query = F::Fetch::IS_ARCHETYPAL && QF::IS_ARCHETYPAL;
 | 
					        let archetype_query = Q::Fetch::IS_ARCHETYPAL && F::Fetch::IS_ARCHETYPAL;
 | 
				
			||||||
        let min_size = if archetype_query { max_size } else { 0 };
 | 
					        let min_size = if archetype_query { max_size } else { 0 };
 | 
				
			||||||
        (min_size, Some(max_size))
 | 
					        (min_size, Some(max_size))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This is correct as [`QueryIter`] always returns `None` once exhausted.
 | 
					// This is correct as [`QueryIter`] always returns `None` once exhausted.
 | 
				
			||||||
impl<'w, 's, Q: WorldQuery, QF, F: WorldQuery> FusedIterator for QueryIter<'w, 's, Q, QF, F> where
 | 
					impl<'w, 's, Q: WorldQuery, F: WorldQuery> FusedIterator for QueryIter<'w, 's, Q, F> {}
 | 
				
			||||||
    QF: Fetch<'w, State = Q::State>
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// An [`Iterator`] over query results of a [`Query`](crate::system::Query).
 | 
					/// An [`Iterator`] over query results of a [`Query`](crate::system::Query).
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// This struct is created by the [`Query::iter_many`](crate::system::Query::iter_many) method.
 | 
					/// This struct is created by the [`Query::iter_many`](crate::system::Query::iter_many) method.
 | 
				
			||||||
pub struct QueryManyIter<
 | 
					pub struct QueryManyIter<'w, 's, Q: WorldQuery, F: WorldQuery, I: Iterator>
 | 
				
			||||||
    'w,
 | 
					where
 | 
				
			||||||
    's,
 | 
					 | 
				
			||||||
    Q: WorldQuery,
 | 
					 | 
				
			||||||
    QF: Fetch<'w, State = Q::State>,
 | 
					 | 
				
			||||||
    F: WorldQuery,
 | 
					 | 
				
			||||||
    I: Iterator,
 | 
					 | 
				
			||||||
> where
 | 
					 | 
				
			||||||
    I::Item: Borrow<Entity>,
 | 
					    I::Item: Borrow<Entity>,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    entity_iter: I,
 | 
					    entity_iter: I,
 | 
				
			||||||
    entities: &'w Entities,
 | 
					    entities: &'w Entities,
 | 
				
			||||||
    tables: &'w Tables,
 | 
					    tables: &'w Tables,
 | 
				
			||||||
    archetypes: &'w Archetypes,
 | 
					    archetypes: &'w Archetypes,
 | 
				
			||||||
    fetch: QF,
 | 
					    fetch: QueryFetch<'w, Q>,
 | 
				
			||||||
    filter: QueryFetch<'w, F>,
 | 
					    filter: QueryFetch<'w, F>,
 | 
				
			||||||
    query_state: &'s QueryState<Q, F>,
 | 
					    query_state: &'s QueryState<Q, F>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'w, 's, Q: WorldQuery, QF: Fetch<'w, State = Q::State>, F: WorldQuery, I: Iterator>
 | 
					impl<'w, 's, Q: WorldQuery, F: WorldQuery, I: Iterator> QueryManyIter<'w, 's, Q, F, I>
 | 
				
			||||||
    QueryManyIter<'w, 's, Q, QF, F, I>
 | 
					 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    I::Item: Borrow<Entity>,
 | 
					    I::Item: Borrow<Entity>,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -119,14 +103,14 @@ where
 | 
				
			|||||||
        entity_list: EntityList,
 | 
					        entity_list: EntityList,
 | 
				
			||||||
        last_change_tick: u32,
 | 
					        last_change_tick: u32,
 | 
				
			||||||
        change_tick: u32,
 | 
					        change_tick: u32,
 | 
				
			||||||
    ) -> QueryManyIter<'w, 's, Q, QF, F, I> {
 | 
					    ) -> QueryManyIter<'w, 's, Q, F, I> {
 | 
				
			||||||
        let fetch = QF::init(
 | 
					        let fetch = Q::Fetch::init(
 | 
				
			||||||
            world,
 | 
					            world,
 | 
				
			||||||
            &query_state.fetch_state,
 | 
					            &query_state.fetch_state,
 | 
				
			||||||
            last_change_tick,
 | 
					            last_change_tick,
 | 
				
			||||||
            change_tick,
 | 
					            change_tick,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        let filter = QueryFetch::<F>::init(
 | 
					        let filter = F::Fetch::init(
 | 
				
			||||||
            world,
 | 
					            world,
 | 
				
			||||||
            &query_state.filter_state,
 | 
					            &query_state.filter_state,
 | 
				
			||||||
            last_change_tick,
 | 
					            last_change_tick,
 | 
				
			||||||
@ -144,12 +128,11 @@ where
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'w, 's, Q: WorldQuery, QF: Fetch<'w, State = Q::State>, F: WorldQuery, I: Iterator> Iterator
 | 
					impl<'w, 's, Q: WorldQuery, F: WorldQuery, I: Iterator> Iterator for QueryManyIter<'w, 's, Q, F, I>
 | 
				
			||||||
    for QueryManyIter<'w, 's, Q, QF, F, I>
 | 
					 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    I::Item: Borrow<Entity>,
 | 
					    I::Item: Borrow<Entity>,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    type Item = QF::Item;
 | 
					    type Item = QueryItem<'w, Q>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[inline(always)]
 | 
					    #[inline(always)]
 | 
				
			||||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
					    fn next(&mut self) -> Option<Self::Item> {
 | 
				
			||||||
@ -201,7 +184,7 @@ pub struct QueryCombinationIter<'w, 's, Q: WorldQuery, F: WorldQuery, const K: u
 | 
				
			|||||||
    tables: &'w Tables,
 | 
					    tables: &'w Tables,
 | 
				
			||||||
    archetypes: &'w Archetypes,
 | 
					    archetypes: &'w Archetypes,
 | 
				
			||||||
    query_state: &'s QueryState<Q, F>,
 | 
					    query_state: &'s QueryState<Q, F>,
 | 
				
			||||||
    cursors: [QueryIterationCursor<'w, 's, Q, QueryFetch<'w, Q>, F>; K],
 | 
					    cursors: [QueryIterationCursor<'w, 's, Q, F>; K],
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'w, 's, Q: WorldQuery, F: WorldQuery, const K: usize> QueryCombinationIter<'w, 's, Q, F, K> {
 | 
					impl<'w, 's, Q: WorldQuery, F: WorldQuery, const K: usize> QueryCombinationIter<'w, 's, Q, F, K> {
 | 
				
			||||||
@ -219,11 +202,10 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery, const K: usize> QueryCombinationIter<
 | 
				
			|||||||
        // Initialize array with cursors.
 | 
					        // Initialize array with cursors.
 | 
				
			||||||
        // There is no FromIterator on arrays, so instead initialize it manually with MaybeUninit
 | 
					        // There is no FromIterator on arrays, so instead initialize it manually with MaybeUninit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut array: MaybeUninit<[QueryIterationCursor<'w, 's, Q, QueryFetch<'w, Q>, F>; K]> =
 | 
					        let mut array: MaybeUninit<[QueryIterationCursor<'w, 's, Q, F>; K]> = MaybeUninit::uninit();
 | 
				
			||||||
            MaybeUninit::uninit();
 | 
					 | 
				
			||||||
        let ptr = array
 | 
					        let ptr = array
 | 
				
			||||||
            .as_mut_ptr()
 | 
					            .as_mut_ptr()
 | 
				
			||||||
            .cast::<QueryIterationCursor<'w, 's, Q, QueryFetch<'w, Q>, F>>();
 | 
					            .cast::<QueryIterationCursor<'w, 's, Q, F>>();
 | 
				
			||||||
        if K != 0 {
 | 
					        if K != 0 {
 | 
				
			||||||
            ptr.write(QueryIterationCursor::init(
 | 
					            ptr.write(QueryIterationCursor::init(
 | 
				
			||||||
                world,
 | 
					                world,
 | 
				
			||||||
@ -367,10 +349,9 @@ where
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'w, 's, Q: WorldQuery, QF, F> ExactSizeIterator for QueryIter<'w, 's, Q, QF, F>
 | 
					impl<'w, 's, Q: WorldQuery, F: WorldQuery> ExactSizeIterator for QueryIter<'w, 's, Q, F>
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    QF: Fetch<'w, State = Q::State>,
 | 
					    F: ArchetypeFilter,
 | 
				
			||||||
    F: WorldQuery + ArchetypeFilter,
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    fn len(&self) -> usize {
 | 
					    fn len(&self) -> usize {
 | 
				
			||||||
        self.query_state
 | 
					        self.query_state
 | 
				
			||||||
@ -405,21 +386,21 @@ where
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct QueryIterationCursor<'w, 's, Q: WorldQuery, QF: Fetch<'w, State = Q::State>, F: WorldQuery> {
 | 
					struct QueryIterationCursor<'w, 's, Q: WorldQuery, F: WorldQuery> {
 | 
				
			||||||
    table_id_iter: std::slice::Iter<'s, TableId>,
 | 
					    table_id_iter: std::slice::Iter<'s, TableId>,
 | 
				
			||||||
    archetype_id_iter: std::slice::Iter<'s, ArchetypeId>,
 | 
					    archetype_id_iter: std::slice::Iter<'s, ArchetypeId>,
 | 
				
			||||||
    fetch: QF,
 | 
					    fetch: QueryFetch<'w, Q>,
 | 
				
			||||||
    filter: QueryFetch<'w, F>,
 | 
					    filter: QueryFetch<'w, F>,
 | 
				
			||||||
    // length of the table table or length of the archetype, depending on whether both `Q`'s and `F`'s fetches are dense
 | 
					    // length of the table table or length of the archetype, depending on whether both `Q`'s and `F`'s fetches are dense
 | 
				
			||||||
    current_len: usize,
 | 
					    current_len: usize,
 | 
				
			||||||
    // either table row or archetype index, depending on whether both `Q`'s and `F`'s fetches are dense
 | 
					    // either table row or archetype index, depending on whether both `Q`'s and `F`'s fetches are dense
 | 
				
			||||||
    current_index: usize,
 | 
					    current_index: usize,
 | 
				
			||||||
    phantom: PhantomData<(&'w (), Q)>,
 | 
					    phantom: PhantomData<Q>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'w, 's, Q: WorldQuery, QF, F: WorldQuery> Clone for QueryIterationCursor<'w, 's, Q, QF, F>
 | 
					impl<'w, 's, Q: WorldQuery, F: WorldQuery> Clone for QueryIterationCursor<'w, 's, Q, F>
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    QF: Fetch<'w, State = Q::State> + Clone,
 | 
					    QueryFetch<'w, Q>: Clone,
 | 
				
			||||||
    QueryFetch<'w, F>: Clone,
 | 
					    QueryFetch<'w, F>: Clone,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    fn clone(&self) -> Self {
 | 
					    fn clone(&self) -> Self {
 | 
				
			||||||
@ -435,11 +416,8 @@ where
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'w, 's, Q: WorldQuery, QF, F: WorldQuery> QueryIterationCursor<'w, 's, Q, QF, F>
 | 
					impl<'w, 's, Q: WorldQuery, F: WorldQuery> QueryIterationCursor<'w, 's, Q, F> {
 | 
				
			||||||
where
 | 
					    const IS_DENSE: bool = Q::Fetch::IS_DENSE && F::Fetch::IS_DENSE;
 | 
				
			||||||
    QF: Fetch<'w, State = Q::State>,
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    const IS_DENSE: bool = QF::IS_DENSE && <QueryFetch<'static, F>>::IS_DENSE;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe fn init_empty(
 | 
					    unsafe fn init_empty(
 | 
				
			||||||
        world: &'w World,
 | 
					        world: &'w World,
 | 
				
			||||||
@ -460,13 +438,13 @@ where
 | 
				
			|||||||
        last_change_tick: u32,
 | 
					        last_change_tick: u32,
 | 
				
			||||||
        change_tick: u32,
 | 
					        change_tick: u32,
 | 
				
			||||||
    ) -> Self {
 | 
					    ) -> Self {
 | 
				
			||||||
        let fetch = QF::init(
 | 
					        let fetch = Q::Fetch::init(
 | 
				
			||||||
            world,
 | 
					            world,
 | 
				
			||||||
            &query_state.fetch_state,
 | 
					            &query_state.fetch_state,
 | 
				
			||||||
            last_change_tick,
 | 
					            last_change_tick,
 | 
				
			||||||
            change_tick,
 | 
					            change_tick,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        let filter = QueryFetch::<F>::init(
 | 
					        let filter = F::Fetch::init(
 | 
				
			||||||
            world,
 | 
					            world,
 | 
				
			||||||
            &query_state.filter_state,
 | 
					            &query_state.filter_state,
 | 
				
			||||||
            last_change_tick,
 | 
					            last_change_tick,
 | 
				
			||||||
@ -485,7 +463,7 @@ where
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// retrieve item returned from most recent `next` call again.
 | 
					    /// retrieve item returned from most recent `next` call again.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    unsafe fn peek_last(&mut self) -> Option<QF::Item> {
 | 
					    unsafe fn peek_last(&mut self) -> Option<QueryItem<'w, Q>> {
 | 
				
			||||||
        if self.current_index > 0 {
 | 
					        if self.current_index > 0 {
 | 
				
			||||||
            if Self::IS_DENSE {
 | 
					            if Self::IS_DENSE {
 | 
				
			||||||
                Some(self.fetch.table_fetch(self.current_index - 1))
 | 
					                Some(self.fetch.table_fetch(self.current_index - 1))
 | 
				
			||||||
@ -509,7 +487,7 @@ where
 | 
				
			|||||||
        tables: &'w Tables,
 | 
					        tables: &'w Tables,
 | 
				
			||||||
        archetypes: &'w Archetypes,
 | 
					        archetypes: &'w Archetypes,
 | 
				
			||||||
        query_state: &'s QueryState<Q, F>,
 | 
					        query_state: &'s QueryState<Q, F>,
 | 
				
			||||||
    ) -> Option<QF::Item> {
 | 
					    ) -> Option<QueryItem<'w, Q>> {
 | 
				
			||||||
        if Self::IS_DENSE {
 | 
					        if Self::IS_DENSE {
 | 
				
			||||||
            loop {
 | 
					            loop {
 | 
				
			||||||
                // we are on the beginning of the query, or finished processing a table, so skip to the next
 | 
					                // we are on the beginning of the query, or finished processing a table, so skip to the next
 | 
				
			||||||
 | 
				
			|||||||
@ -21,8 +21,8 @@ pub(crate) unsafe fn debug_checked_unreachable() -> ! {
 | 
				
			|||||||
mod tests {
 | 
					mod tests {
 | 
				
			||||||
    use super::WorldQuery;
 | 
					    use super::WorldQuery;
 | 
				
			||||||
    use crate::prelude::{AnyOf, Entity, Or, QueryState, With, Without};
 | 
					    use crate::prelude::{AnyOf, Entity, Or, QueryState, With, Without};
 | 
				
			||||||
    use crate::query::{ArchetypeFilter, QueryCombinationIter, QueryFetch, ReadOnlyWorldQuery};
 | 
					    use crate::query::{ArchetypeFilter, QueryCombinationIter, QueryFetch};
 | 
				
			||||||
    use crate::system::{IntoSystem, Query, System};
 | 
					    use crate::system::{IntoSystem, Query, System, SystemState};
 | 
				
			||||||
    use crate::{self as bevy_ecs, component::Component, world::World};
 | 
					    use crate::{self as bevy_ecs, component::Component, world::World};
 | 
				
			||||||
    use std::any::type_name;
 | 
					    use std::any::type_name;
 | 
				
			||||||
    use std::collections::HashSet;
 | 
					    use std::collections::HashSet;
 | 
				
			||||||
@ -67,10 +67,11 @@ mod tests {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        fn assert_combination<Q, F, const K: usize>(world: &mut World, expected_size: usize)
 | 
					        fn assert_combination<Q, F, const K: usize>(world: &mut World, expected_size: usize)
 | 
				
			||||||
        where
 | 
					        where
 | 
				
			||||||
            Q: ReadOnlyWorldQuery,
 | 
					            Q: WorldQuery,
 | 
				
			||||||
            F: ReadOnlyWorldQuery + ArchetypeFilter,
 | 
					            F: WorldQuery,
 | 
				
			||||||
            for<'w> QueryFetch<'w, Q>: Clone,
 | 
					            F::ReadOnly: ArchetypeFilter,
 | 
				
			||||||
            for<'w> QueryFetch<'w, F>: Clone,
 | 
					            for<'w> QueryFetch<'w, Q::ReadOnly>: Clone,
 | 
				
			||||||
 | 
					            for<'w> QueryFetch<'w, F::ReadOnly>: Clone,
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            let mut query = world.query_filtered::<Q, F>();
 | 
					            let mut query = world.query_filtered::<Q, F>();
 | 
				
			||||||
            let iter = query.iter_combinations::<K>(world);
 | 
					            let iter = query.iter_combinations::<K>(world);
 | 
				
			||||||
@ -79,10 +80,11 @@ mod tests {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        fn assert_all_sizes_equal<Q, F>(world: &mut World, expected_size: usize)
 | 
					        fn assert_all_sizes_equal<Q, F>(world: &mut World, expected_size: usize)
 | 
				
			||||||
        where
 | 
					        where
 | 
				
			||||||
            Q: ReadOnlyWorldQuery,
 | 
					            Q: WorldQuery,
 | 
				
			||||||
            F: ReadOnlyWorldQuery + ArchetypeFilter,
 | 
					            F: WorldQuery,
 | 
				
			||||||
            for<'w> QueryFetch<'w, Q>: Clone,
 | 
					            F::ReadOnly: ArchetypeFilter,
 | 
				
			||||||
            for<'w> QueryFetch<'w, F>: Clone,
 | 
					            for<'w> QueryFetch<'w, Q::ReadOnly>: Clone,
 | 
				
			||||||
 | 
					            for<'w> QueryFetch<'w, F::ReadOnly>: Clone,
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            let mut query = world.query_filtered::<Q, F>();
 | 
					            let mut query = world.query_filtered::<Q, F>();
 | 
				
			||||||
            let iter = query.iter(world);
 | 
					            let iter = query.iter(world);
 | 
				
			||||||
@ -653,4 +655,42 @@ count():       {count}"#
 | 
				
			|||||||
            system.run((), &mut world);
 | 
					            system.run((), &mut world);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn mut_to_immut_query_methods_have_immut_item() {
 | 
				
			||||||
 | 
					        #[derive(Component)]
 | 
				
			||||||
 | 
					        struct Foo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut world = World::new();
 | 
				
			||||||
 | 
					        let e = world.spawn().insert(Foo).id();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // state
 | 
				
			||||||
 | 
					        let mut q = world.query::<&mut Foo>();
 | 
				
			||||||
 | 
					        let _: Option<&Foo> = q.iter(&world).next();
 | 
				
			||||||
 | 
					        let _: Option<[&Foo; 2]> = q.iter_combinations::<2>(&world).next();
 | 
				
			||||||
 | 
					        let _: Option<&Foo> = q.iter_manual(&world).next();
 | 
				
			||||||
 | 
					        let _: Option<&Foo> = q.iter_many(&world, [e]).next();
 | 
				
			||||||
 | 
					        q.for_each(&world, |_: &Foo| ());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let _: Option<&Foo> = q.get(&world, e).ok();
 | 
				
			||||||
 | 
					        let _: Option<&Foo> = q.get_manual(&world, e).ok();
 | 
				
			||||||
 | 
					        let _: Option<[&Foo; 1]> = q.get_many(&world, [e]).ok();
 | 
				
			||||||
 | 
					        let _: Option<&Foo> = q.get_single(&world).ok();
 | 
				
			||||||
 | 
					        let _: &Foo = q.single(&world);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // system param
 | 
				
			||||||
 | 
					        let mut q = SystemState::<Query<&mut Foo>>::new(&mut world);
 | 
				
			||||||
 | 
					        let q = q.get_mut(&mut world);
 | 
				
			||||||
 | 
					        let _: Option<&Foo> = q.iter().next();
 | 
				
			||||||
 | 
					        let _: Option<[&Foo; 2]> = q.iter_combinations::<2>().next();
 | 
				
			||||||
 | 
					        let _: Option<&Foo> = q.iter_many([e]).next();
 | 
				
			||||||
 | 
					        q.for_each(|_: &Foo| ());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let _: Option<&Foo> = q.get(e).ok();
 | 
				
			||||||
 | 
					        let _: Option<&Foo> = q.get_component(e).ok();
 | 
				
			||||||
 | 
					        let _: Option<[&Foo; 1]> = q.get_many([e]).ok();
 | 
				
			||||||
 | 
					        let _: Option<&Foo> = q.get_single().ok();
 | 
				
			||||||
 | 
					        let _: [&Foo; 1] = q.many([e]);
 | 
				
			||||||
 | 
					        let _: &Foo = q.single();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,8 +4,7 @@ use crate::{
 | 
				
			|||||||
    entity::Entity,
 | 
					    entity::Entity,
 | 
				
			||||||
    prelude::FromWorld,
 | 
					    prelude::FromWorld,
 | 
				
			||||||
    query::{
 | 
					    query::{
 | 
				
			||||||
        Access, Fetch, FetchState, FilteredAccess, NopFetch, QueryCombinationIter, QueryIter,
 | 
					        Access, Fetch, FetchState, FilteredAccess, QueryCombinationIter, QueryIter, WorldQuery,
 | 
				
			||||||
        WorldQuery,
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    storage::TableId,
 | 
					    storage::TableId,
 | 
				
			||||||
    world::{World, WorldId},
 | 
					    world::{World, WorldId},
 | 
				
			||||||
@ -16,9 +15,13 @@ use bevy_utils::tracing::Instrument;
 | 
				
			|||||||
use fixedbitset::FixedBitSet;
 | 
					use fixedbitset::FixedBitSet;
 | 
				
			||||||
use std::{borrow::Borrow, fmt};
 | 
					use std::{borrow::Borrow, fmt};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::{QueryFetch, QueryItem, QueryManyIter, ROQueryFetch, ROQueryItem};
 | 
					use super::{NopWorldQuery, QueryFetch, QueryItem, QueryManyIter, ROQueryItem};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Provides scoped access to a [`World`] state according to a given [`WorldQuery`] and query filter.
 | 
					/// Provides scoped access to a [`World`] state according to a given [`WorldQuery`] and query filter.
 | 
				
			||||||
 | 
					#[repr(C)]
 | 
				
			||||||
 | 
					// SAFETY NOTE:
 | 
				
			||||||
 | 
					// Do not add any new fields that use the `Q` or `F` generic parameters as this may
 | 
				
			||||||
 | 
					// make `QueryState::as_transmuted_state` unsound if not done with care.
 | 
				
			||||||
pub struct QueryState<Q: WorldQuery, F: WorldQuery = ()> {
 | 
					pub struct QueryState<Q: WorldQuery, F: WorldQuery = ()> {
 | 
				
			||||||
    world_id: WorldId,
 | 
					    world_id: WorldId,
 | 
				
			||||||
    pub(crate) archetype_generation: ArchetypeGeneration,
 | 
					    pub(crate) archetype_generation: ArchetypeGeneration,
 | 
				
			||||||
@ -40,6 +43,44 @@ impl<Q: WorldQuery, F: WorldQuery> FromWorld for QueryState<Q, F> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			||||||
 | 
					    /// Converts this `QueryState` reference to a `QueryState` that does not access anything mutably.
 | 
				
			||||||
 | 
					    pub fn as_readonly(&self) -> &QueryState<Q::ReadOnly, F::ReadOnly> {
 | 
				
			||||||
 | 
					        // SAFETY: invariant on `WorldQuery` trait upholds that `Q::ReadOnly` and `F::ReadOnly`
 | 
				
			||||||
 | 
					        // have a subset of the access, and match the exact same archetypes/tables as `Q`/`F` respectively.
 | 
				
			||||||
 | 
					        unsafe { self.as_transmuted_state::<Q::ReadOnly, F::ReadOnly>() }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Converts this `QueryState` reference to a `QueryState` that does not return any data
 | 
				
			||||||
 | 
					    /// which can be faster.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// This doesn't use `NopWorldQuery` as it loses filter functionality, for example
 | 
				
			||||||
 | 
					    /// `NopWorldQuery<Changed<T>>` is functionally equivelent to `With<T>`.
 | 
				
			||||||
 | 
					    pub fn as_nop(&self) -> &QueryState<NopWorldQuery<Q>, F> {
 | 
				
			||||||
 | 
					        // SAFETY: `NopWorldQuery` doesn't have any accesses and defers to
 | 
				
			||||||
 | 
					        // `Q` for table/archetype matching
 | 
				
			||||||
 | 
					        unsafe { self.as_transmuted_state::<NopWorldQuery<Q>, F>() }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Converts this `QueryState` reference to any other `QueryState` with
 | 
				
			||||||
 | 
					    /// the same `WorldQuery::State` associated types.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// Consider using `as_readonly` or `as_nop` instead which are safe functions.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// # SAFETY
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// `NewQ` must have a subset of the access that `Q` does and match the exact same archetypes/tables
 | 
				
			||||||
 | 
					    /// `NewF` must have a subset of the access that `F` does and match the exact same archetypes/tables
 | 
				
			||||||
 | 
					    pub(crate) unsafe fn as_transmuted_state<
 | 
				
			||||||
 | 
					        NewQ: WorldQuery<State = Q::State>,
 | 
				
			||||||
 | 
					        NewF: WorldQuery<State = F::State>,
 | 
				
			||||||
 | 
					    >(
 | 
				
			||||||
 | 
					        &self,
 | 
				
			||||||
 | 
					    ) -> &QueryState<NewQ, NewF> {
 | 
				
			||||||
 | 
					        &*(self as *const QueryState<Q, F> as *const QueryState<NewQ, NewF>)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
					impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			||||||
    /// Creates a new [`QueryState`] from a given [`World`] and inherits the result of `world.id()`.
 | 
					    /// Creates a new [`QueryState`] from a given [`World`] and inherits the result of `world.id()`.
 | 
				
			||||||
    pub fn new(world: &mut World) -> Self {
 | 
					    pub fn new(world: &mut World) -> Self {
 | 
				
			||||||
@ -83,7 +124,8 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
    pub fn is_empty(&self, world: &World, last_change_tick: u32, change_tick: u32) -> bool {
 | 
					    pub fn is_empty(&self, world: &World, last_change_tick: u32, change_tick: u32) -> bool {
 | 
				
			||||||
        // SAFETY: NopFetch does not access any members while &self ensures no one has exclusive access
 | 
					        // SAFETY: NopFetch does not access any members while &self ensures no one has exclusive access
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.iter_unchecked_manual::<NopFetch<Q::State>>(world, last_change_tick, change_tick)
 | 
					            self.as_nop()
 | 
				
			||||||
 | 
					                .iter_unchecked_manual(world, last_change_tick, change_tick)
 | 
				
			||||||
                .next()
 | 
					                .next()
 | 
				
			||||||
                .is_none()
 | 
					                .is_none()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -162,7 +204,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        self.update_archetypes(world);
 | 
					        self.update_archetypes(world);
 | 
				
			||||||
        // SAFETY: query is read only
 | 
					        // SAFETY: query is read only
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.get_unchecked_manual::<ROQueryFetch<'w, Q>>(
 | 
					            self.as_readonly().get_unchecked_manual(
 | 
				
			||||||
                world,
 | 
					                world,
 | 
				
			||||||
                entity,
 | 
					                entity,
 | 
				
			||||||
                world.last_change_tick(),
 | 
					                world.last_change_tick(),
 | 
				
			||||||
@ -232,7 +274,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        self.update_archetypes(world);
 | 
					        self.update_archetypes(world);
 | 
				
			||||||
        // SAFETY: query has unique world access
 | 
					        // SAFETY: query has unique world access
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.get_unchecked_manual::<QueryFetch<'w, Q>>(
 | 
					            self.get_unchecked_manual(
 | 
				
			||||||
                world,
 | 
					                world,
 | 
				
			||||||
                entity,
 | 
					                entity,
 | 
				
			||||||
                world.last_change_tick(),
 | 
					                world.last_change_tick(),
 | 
				
			||||||
@ -308,7 +350,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        self.validate_world(world);
 | 
					        self.validate_world(world);
 | 
				
			||||||
        // SAFETY: query is read only and world is validated
 | 
					        // SAFETY: query is read only and world is validated
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.get_unchecked_manual::<ROQueryFetch<'w, Q>>(
 | 
					            self.as_readonly().get_unchecked_manual(
 | 
				
			||||||
                world,
 | 
					                world,
 | 
				
			||||||
                entity,
 | 
					                entity,
 | 
				
			||||||
                world.last_change_tick(),
 | 
					                world.last_change_tick(),
 | 
				
			||||||
@ -330,7 +372,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        entity: Entity,
 | 
					        entity: Entity,
 | 
				
			||||||
    ) -> Result<QueryItem<'w, Q>, QueryEntityError> {
 | 
					    ) -> Result<QueryItem<'w, Q>, QueryEntityError> {
 | 
				
			||||||
        self.update_archetypes(world);
 | 
					        self.update_archetypes(world);
 | 
				
			||||||
        self.get_unchecked_manual::<QueryFetch<'w, Q>>(
 | 
					        self.get_unchecked_manual(
 | 
				
			||||||
            world,
 | 
					            world,
 | 
				
			||||||
            entity,
 | 
					            entity,
 | 
				
			||||||
            world.last_change_tick(),
 | 
					            world.last_change_tick(),
 | 
				
			||||||
@ -348,13 +390,13 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// This must be called on the same `World` that the `Query` was generated from:
 | 
					    /// This must be called on the same `World` that the `Query` was generated from:
 | 
				
			||||||
    /// use `QueryState::validate_world` to verify this.
 | 
					    /// use `QueryState::validate_world` to verify this.
 | 
				
			||||||
    pub(crate) unsafe fn get_unchecked_manual<'w, QF: Fetch<'w, State = Q::State>>(
 | 
					    pub(crate) unsafe fn get_unchecked_manual<'w>(
 | 
				
			||||||
        &self,
 | 
					        &self,
 | 
				
			||||||
        world: &'w World,
 | 
					        world: &'w World,
 | 
				
			||||||
        entity: Entity,
 | 
					        entity: Entity,
 | 
				
			||||||
        last_change_tick: u32,
 | 
					        last_change_tick: u32,
 | 
				
			||||||
        change_tick: u32,
 | 
					        change_tick: u32,
 | 
				
			||||||
    ) -> Result<QF::Item, QueryEntityError> {
 | 
					    ) -> Result<QueryItem<'w, Q>, QueryEntityError> {
 | 
				
			||||||
        let location = world
 | 
					        let location = world
 | 
				
			||||||
            .entities
 | 
					            .entities
 | 
				
			||||||
            .get(entity)
 | 
					            .get(entity)
 | 
				
			||||||
@ -366,7 +408,8 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
            return Err(QueryEntityError::QueryDoesNotMatch(entity));
 | 
					            return Err(QueryEntityError::QueryDoesNotMatch(entity));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        let archetype = &world.archetypes[location.archetype_id];
 | 
					        let archetype = &world.archetypes[location.archetype_id];
 | 
				
			||||||
        let mut fetch = QF::init(world, &self.fetch_state, last_change_tick, change_tick);
 | 
					        let mut fetch =
 | 
				
			||||||
 | 
					            <QueryFetch<Q> as Fetch>::init(world, &self.fetch_state, last_change_tick, change_tick);
 | 
				
			||||||
        let mut filter = <QueryFetch<F> as Fetch>::init(
 | 
					        let mut filter = <QueryFetch<F> as Fetch>::init(
 | 
				
			||||||
            world,
 | 
					            world,
 | 
				
			||||||
            &self.filter_state,
 | 
					            &self.filter_state,
 | 
				
			||||||
@ -400,12 +443,8 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        // SAFETY: fetch is read-only
 | 
					        // SAFETY: fetch is read-only
 | 
				
			||||||
        // and world must be validated
 | 
					        // and world must be validated
 | 
				
			||||||
        let array_of_results = entities.map(|entity| {
 | 
					        let array_of_results = entities.map(|entity| {
 | 
				
			||||||
            self.get_unchecked_manual::<ROQueryFetch<'w, Q>>(
 | 
					            self.as_readonly()
 | 
				
			||||||
                world,
 | 
					                .get_unchecked_manual(world, entity, last_change_tick, change_tick)
 | 
				
			||||||
                entity,
 | 
					 | 
				
			||||||
                last_change_tick,
 | 
					 | 
				
			||||||
                change_tick,
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // TODO: Replace with TryMap once https://github.com/rust-lang/rust/issues/79711 is stabilized
 | 
					        // TODO: Replace with TryMap once https://github.com/rust-lang/rust/issues/79711 is stabilized
 | 
				
			||||||
@ -447,14 +486,8 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let array_of_results = entities.map(|entity| {
 | 
					        let array_of_results = entities
 | 
				
			||||||
            self.get_unchecked_manual::<QueryFetch<'w, Q>>(
 | 
					            .map(|entity| self.get_unchecked_manual(world, entity, last_change_tick, change_tick));
 | 
				
			||||||
                world,
 | 
					 | 
				
			||||||
                entity,
 | 
					 | 
				
			||||||
                last_change_tick,
 | 
					 | 
				
			||||||
                change_tick,
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // If any of the get calls failed, bubble up the error
 | 
					        // If any of the get calls failed, bubble up the error
 | 
				
			||||||
        for result in &array_of_results {
 | 
					        for result in &array_of_results {
 | 
				
			||||||
@ -475,20 +508,21 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
    pub fn iter<'w, 's>(
 | 
					    pub fn iter<'w, 's>(
 | 
				
			||||||
        &'s mut self,
 | 
					        &'s mut self,
 | 
				
			||||||
        world: &'w World,
 | 
					        world: &'w World,
 | 
				
			||||||
    ) -> QueryIter<'w, 's, Q, ROQueryFetch<'w, Q>, F> {
 | 
					    ) -> QueryIter<'w, 's, Q::ReadOnly, F::ReadOnly> {
 | 
				
			||||||
        // SAFETY: query is read only
 | 
					        // SAFETY: query is read only
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.update_archetypes(world);
 | 
					            self.update_archetypes(world);
 | 
				
			||||||
            self.iter_unchecked_manual(world, world.last_change_tick(), world.read_change_tick())
 | 
					            self.as_readonly().iter_unchecked_manual(
 | 
				
			||||||
 | 
					                world,
 | 
				
			||||||
 | 
					                world.last_change_tick(),
 | 
				
			||||||
 | 
					                world.read_change_tick(),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Returns an [`Iterator`] over the query results for the given [`World`].
 | 
					    /// Returns an [`Iterator`] over the query results for the given [`World`].
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn iter_mut<'w, 's>(
 | 
					    pub fn iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryIter<'w, 's, Q, F> {
 | 
				
			||||||
        &'s mut self,
 | 
					 | 
				
			||||||
        world: &'w mut World,
 | 
					 | 
				
			||||||
    ) -> QueryIter<'w, 's, Q, QueryFetch<'w, Q>, F> {
 | 
					 | 
				
			||||||
        // SAFETY: query has unique world access
 | 
					        // SAFETY: query has unique world access
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.update_archetypes(world);
 | 
					            self.update_archetypes(world);
 | 
				
			||||||
@ -504,11 +538,15 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
    pub fn iter_manual<'w, 's>(
 | 
					    pub fn iter_manual<'w, 's>(
 | 
				
			||||||
        &'s self,
 | 
					        &'s self,
 | 
				
			||||||
        world: &'w World,
 | 
					        world: &'w World,
 | 
				
			||||||
    ) -> QueryIter<'w, 's, Q, ROQueryFetch<'w, Q>, F> {
 | 
					    ) -> QueryIter<'w, 's, Q::ReadOnly, F::ReadOnly> {
 | 
				
			||||||
        self.validate_world(world);
 | 
					        self.validate_world(world);
 | 
				
			||||||
        // SAFETY: query is read only and world is validated
 | 
					        // SAFETY: query is read only and world is validated
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.iter_unchecked_manual(world, world.last_change_tick(), world.read_change_tick())
 | 
					            self.as_readonly().iter_unchecked_manual(
 | 
				
			||||||
 | 
					                world,
 | 
				
			||||||
 | 
					                world.last_change_tick(),
 | 
				
			||||||
 | 
					                world.read_change_tick(),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -526,11 +564,11 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
    pub fn iter_combinations<'w, 's, const K: usize>(
 | 
					    pub fn iter_combinations<'w, 's, const K: usize>(
 | 
				
			||||||
        &'s mut self,
 | 
					        &'s mut self,
 | 
				
			||||||
        world: &'w World,
 | 
					        world: &'w World,
 | 
				
			||||||
    ) -> QueryCombinationIter<'w, 's, Q, F, K> {
 | 
					    ) -> QueryCombinationIter<'w, 's, Q::ReadOnly, F::ReadOnly, K> {
 | 
				
			||||||
        // SAFETY: query is read only
 | 
					        // SAFETY: query is read only
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.update_archetypes(world);
 | 
					            self.update_archetypes(world);
 | 
				
			||||||
            self.iter_combinations_unchecked_manual(
 | 
					            self.as_readonly().iter_combinations_unchecked_manual(
 | 
				
			||||||
                world,
 | 
					                world,
 | 
				
			||||||
                world.last_change_tick(),
 | 
					                world.last_change_tick(),
 | 
				
			||||||
                world.read_change_tick(),
 | 
					                world.read_change_tick(),
 | 
				
			||||||
@ -571,14 +609,14 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        &'s mut self,
 | 
					        &'s mut self,
 | 
				
			||||||
        world: &'w World,
 | 
					        world: &'w World,
 | 
				
			||||||
        entities: EntityList,
 | 
					        entities: EntityList,
 | 
				
			||||||
    ) -> QueryManyIter<'w, 's, Q, ROQueryFetch<'w, Q>, F, EntityList::IntoIter>
 | 
					    ) -> QueryManyIter<'w, 's, Q::ReadOnly, F::ReadOnly, EntityList::IntoIter>
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        EntityList::Item: Borrow<Entity>,
 | 
					        EntityList::Item: Borrow<Entity>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // SAFETY: query is read only
 | 
					        // SAFETY: query is read only
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.update_archetypes(world);
 | 
					            self.update_archetypes(world);
 | 
				
			||||||
            self.iter_many_unchecked_manual(
 | 
					            self.as_readonly().iter_many_unchecked_manual(
 | 
				
			||||||
                entities,
 | 
					                entities,
 | 
				
			||||||
                world,
 | 
					                world,
 | 
				
			||||||
                world.last_change_tick(),
 | 
					                world.last_change_tick(),
 | 
				
			||||||
@ -597,7 +635,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
    pub unsafe fn iter_unchecked<'w, 's>(
 | 
					    pub unsafe fn iter_unchecked<'w, 's>(
 | 
				
			||||||
        &'s mut self,
 | 
					        &'s mut self,
 | 
				
			||||||
        world: &'w World,
 | 
					        world: &'w World,
 | 
				
			||||||
    ) -> QueryIter<'w, 's, Q, QueryFetch<'w, Q>, F> {
 | 
					    ) -> QueryIter<'w, 's, Q, F> {
 | 
				
			||||||
        self.update_archetypes(world);
 | 
					        self.update_archetypes(world);
 | 
				
			||||||
        self.iter_unchecked_manual(world, world.last_change_tick(), world.read_change_tick())
 | 
					        self.iter_unchecked_manual(world, world.last_change_tick(), world.read_change_tick())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -633,12 +671,12 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
 | 
					    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
 | 
				
			||||||
    /// with a mismatched [`WorldId`] is unsound.
 | 
					    /// with a mismatched [`WorldId`] is unsound.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub(crate) unsafe fn iter_unchecked_manual<'w, 's, QF: Fetch<'w, State = Q::State>>(
 | 
					    pub(crate) unsafe fn iter_unchecked_manual<'w, 's>(
 | 
				
			||||||
        &'s self,
 | 
					        &'s self,
 | 
				
			||||||
        world: &'w World,
 | 
					        world: &'w World,
 | 
				
			||||||
        last_change_tick: u32,
 | 
					        last_change_tick: u32,
 | 
				
			||||||
        change_tick: u32,
 | 
					        change_tick: u32,
 | 
				
			||||||
    ) -> QueryIter<'w, 's, Q, QF, F> {
 | 
					    ) -> QueryIter<'w, 's, Q, F> {
 | 
				
			||||||
        QueryIter::new(world, self, last_change_tick, change_tick)
 | 
					        QueryIter::new(world, self, last_change_tick, change_tick)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -649,22 +687,17 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
 | 
					    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
 | 
				
			||||||
    /// have unique access to the components they query.
 | 
					    /// have unique access to the components they query.
 | 
				
			||||||
    /// this does not check for entity uniqueness
 | 
					    /// This does not check for entity uniqueness
 | 
				
			||||||
    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
 | 
					    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
 | 
				
			||||||
    /// with a mismatched [`WorldId`] is unsound.
 | 
					    /// with a mismatched [`WorldId`] is unsound.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub(crate) unsafe fn iter_many_unchecked_manual<
 | 
					    pub(crate) unsafe fn iter_many_unchecked_manual<'w, 's, EntityList: IntoIterator>(
 | 
				
			||||||
        'w,
 | 
					 | 
				
			||||||
        's,
 | 
					 | 
				
			||||||
        QF: Fetch<'w, State = Q::State>,
 | 
					 | 
				
			||||||
        EntityList: IntoIterator,
 | 
					 | 
				
			||||||
    >(
 | 
					 | 
				
			||||||
        &'s self,
 | 
					        &'s self,
 | 
				
			||||||
        entities: EntityList,
 | 
					        entities: EntityList,
 | 
				
			||||||
        world: &'w World,
 | 
					        world: &'w World,
 | 
				
			||||||
        last_change_tick: u32,
 | 
					        last_change_tick: u32,
 | 
				
			||||||
        change_tick: u32,
 | 
					        change_tick: u32,
 | 
				
			||||||
    ) -> QueryManyIter<'w, 's, Q, QF, F, EntityList::IntoIter>
 | 
					    ) -> QueryManyIter<'w, 's, Q, F, EntityList::IntoIter>
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        EntityList::Item: Borrow<Entity>,
 | 
					        EntityList::Item: Borrow<Entity>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -700,7 +733,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        // SAFETY: query is read only
 | 
					        // SAFETY: query is read only
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.update_archetypes(world);
 | 
					            self.update_archetypes(world);
 | 
				
			||||||
            self.for_each_unchecked_manual::<ROQueryFetch<Q>, FN>(
 | 
					            self.as_readonly().for_each_unchecked_manual(
 | 
				
			||||||
                world,
 | 
					                world,
 | 
				
			||||||
                func,
 | 
					                func,
 | 
				
			||||||
                world.last_change_tick(),
 | 
					                world.last_change_tick(),
 | 
				
			||||||
@ -720,7 +753,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        // SAFETY: query has unique world access
 | 
					        // SAFETY: query has unique world access
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.update_archetypes(world);
 | 
					            self.update_archetypes(world);
 | 
				
			||||||
            self.for_each_unchecked_manual::<QueryFetch<Q>, FN>(
 | 
					            self.for_each_unchecked_manual(
 | 
				
			||||||
                world,
 | 
					                world,
 | 
				
			||||||
                func,
 | 
					                func,
 | 
				
			||||||
                world.last_change_tick(),
 | 
					                world.last_change_tick(),
 | 
				
			||||||
@ -745,7 +778,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        func: FN,
 | 
					        func: FN,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        self.update_archetypes(world);
 | 
					        self.update_archetypes(world);
 | 
				
			||||||
        self.for_each_unchecked_manual::<QueryFetch<Q>, FN>(
 | 
					        self.for_each_unchecked_manual(
 | 
				
			||||||
            world,
 | 
					            world,
 | 
				
			||||||
            func,
 | 
					            func,
 | 
				
			||||||
            world.last_change_tick(),
 | 
					            world.last_change_tick(),
 | 
				
			||||||
@ -771,7 +804,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        // SAFETY: query is read only
 | 
					        // SAFETY: query is read only
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.update_archetypes(world);
 | 
					            self.update_archetypes(world);
 | 
				
			||||||
            self.par_for_each_unchecked_manual::<ROQueryFetch<Q>, FN>(
 | 
					            self.as_readonly().par_for_each_unchecked_manual(
 | 
				
			||||||
                world,
 | 
					                world,
 | 
				
			||||||
                batch_size,
 | 
					                batch_size,
 | 
				
			||||||
                func,
 | 
					                func,
 | 
				
			||||||
@ -796,7 +829,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        // SAFETY: query has unique world access
 | 
					        // SAFETY: query has unique world access
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.update_archetypes(world);
 | 
					            self.update_archetypes(world);
 | 
				
			||||||
            self.par_for_each_unchecked_manual::<QueryFetch<Q>, FN>(
 | 
					            self.par_for_each_unchecked_manual(
 | 
				
			||||||
                world,
 | 
					                world,
 | 
				
			||||||
                batch_size,
 | 
					                batch_size,
 | 
				
			||||||
                func,
 | 
					                func,
 | 
				
			||||||
@ -826,7 +859,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        func: FN,
 | 
					        func: FN,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        self.update_archetypes(world);
 | 
					        self.update_archetypes(world);
 | 
				
			||||||
        self.par_for_each_unchecked_manual::<QueryFetch<Q>, FN>(
 | 
					        self.par_for_each_unchecked_manual(
 | 
				
			||||||
            world,
 | 
					            world,
 | 
				
			||||||
            batch_size,
 | 
					            batch_size,
 | 
				
			||||||
            func,
 | 
					            func,
 | 
				
			||||||
@ -868,11 +901,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
    /// have unique access to the components they query.
 | 
					    /// have unique access to the components they query.
 | 
				
			||||||
    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
 | 
					    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
 | 
				
			||||||
    /// with a mismatched [`WorldId`] is unsound.
 | 
					    /// with a mismatched [`WorldId`] is unsound.
 | 
				
			||||||
    pub(crate) unsafe fn for_each_unchecked_manual<
 | 
					    pub(crate) unsafe fn for_each_unchecked_manual<'w, FN: FnMut(QueryItem<'w, Q>)>(
 | 
				
			||||||
        'w,
 | 
					 | 
				
			||||||
        QF: Fetch<'w, State = Q::State>,
 | 
					 | 
				
			||||||
        FN: FnMut(QF::Item),
 | 
					 | 
				
			||||||
    >(
 | 
					 | 
				
			||||||
        &self,
 | 
					        &self,
 | 
				
			||||||
        world: &'w World,
 | 
					        world: &'w World,
 | 
				
			||||||
        mut func: FN,
 | 
					        mut func: FN,
 | 
				
			||||||
@ -881,7 +910,8 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        // NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
 | 
					        // NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
 | 
				
			||||||
        // QueryIter, QueryIterationCursor, QueryState::for_each_unchecked_manual, QueryState::many_for_each_unchecked_manual, QueryState::par_for_each_unchecked_manual
 | 
					        // QueryIter, QueryIterationCursor, QueryState::for_each_unchecked_manual, QueryState::many_for_each_unchecked_manual, QueryState::par_for_each_unchecked_manual
 | 
				
			||||||
        let mut fetch = QF::init(world, &self.fetch_state, last_change_tick, change_tick);
 | 
					        let mut fetch =
 | 
				
			||||||
 | 
					            <QueryFetch<Q> as Fetch>::init(world, &self.fetch_state, last_change_tick, change_tick);
 | 
				
			||||||
        let mut filter = <QueryFetch<F> as Fetch>::init(
 | 
					        let mut filter = <QueryFetch<F> as Fetch>::init(
 | 
				
			||||||
            world,
 | 
					            world,
 | 
				
			||||||
            &self.filter_state,
 | 
					            &self.filter_state,
 | 
				
			||||||
@ -938,8 +968,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
    /// with a mismatched [`WorldId`] is unsound.
 | 
					    /// with a mismatched [`WorldId`] is unsound.
 | 
				
			||||||
    pub(crate) unsafe fn par_for_each_unchecked_manual<
 | 
					    pub(crate) unsafe fn par_for_each_unchecked_manual<
 | 
				
			||||||
        'w,
 | 
					        'w,
 | 
				
			||||||
        QF: Fetch<'w, State = Q::State>,
 | 
					        FN: Fn(QueryItem<'w, Q>) + Send + Sync + Clone,
 | 
				
			||||||
        FN: Fn(QF::Item) + Send + Sync + Clone,
 | 
					 | 
				
			||||||
    >(
 | 
					    >(
 | 
				
			||||||
        &self,
 | 
					        &self,
 | 
				
			||||||
        world: &'w World,
 | 
					        world: &'w World,
 | 
				
			||||||
@ -951,7 +980,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        // NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
 | 
					        // NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
 | 
				
			||||||
        // QueryIter, QueryIterationCursor, QueryState::for_each_unchecked_manual, QueryState::many_for_each_unchecked_manual, QueryState::par_for_each_unchecked_manual
 | 
					        // QueryIter, QueryIterationCursor, QueryState::for_each_unchecked_manual, QueryState::many_for_each_unchecked_manual, QueryState::par_for_each_unchecked_manual
 | 
				
			||||||
        ComputeTaskPool::get().scope(|scope| {
 | 
					        ComputeTaskPool::get().scope(|scope| {
 | 
				
			||||||
            if QF::IS_DENSE && <QueryFetch<'static, F>>::IS_DENSE {
 | 
					            if <QueryFetch<'static, Q>>::IS_DENSE && <QueryFetch<'static, F>>::IS_DENSE {
 | 
				
			||||||
                let tables = &world.storages().tables;
 | 
					                let tables = &world.storages().tables;
 | 
				
			||||||
                for table_id in &self.matched_table_ids {
 | 
					                for table_id in &self.matched_table_ids {
 | 
				
			||||||
                    let table = &tables[*table_id];
 | 
					                    let table = &tables[*table_id];
 | 
				
			||||||
@ -960,8 +989,12 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
                        let func = func.clone();
 | 
					                        let func = func.clone();
 | 
				
			||||||
                        let len = batch_size.min(table.len() - offset);
 | 
					                        let len = batch_size.min(table.len() - offset);
 | 
				
			||||||
                        let task = async move {
 | 
					                        let task = async move {
 | 
				
			||||||
                            let mut fetch =
 | 
					                            let mut fetch = <QueryFetch<Q> as Fetch>::init(
 | 
				
			||||||
                                QF::init(world, &self.fetch_state, last_change_tick, change_tick);
 | 
					                                world,
 | 
				
			||||||
 | 
					                                &self.fetch_state,
 | 
				
			||||||
 | 
					                                last_change_tick,
 | 
				
			||||||
 | 
					                                change_tick,
 | 
				
			||||||
 | 
					                            );
 | 
				
			||||||
                            let mut filter = <QueryFetch<F> as Fetch>::init(
 | 
					                            let mut filter = <QueryFetch<F> as Fetch>::init(
 | 
				
			||||||
                                world,
 | 
					                                world,
 | 
				
			||||||
                                &self.filter_state,
 | 
					                                &self.filter_state,
 | 
				
			||||||
@ -1002,8 +1035,12 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
                        let func = func.clone();
 | 
					                        let func = func.clone();
 | 
				
			||||||
                        let len = batch_size.min(archetype.len() - offset);
 | 
					                        let len = batch_size.min(archetype.len() - offset);
 | 
				
			||||||
                        let task = async move {
 | 
					                        let task = async move {
 | 
				
			||||||
                            let mut fetch =
 | 
					                            let mut fetch = <QueryFetch<Q> as Fetch>::init(
 | 
				
			||||||
                                QF::init(world, &self.fetch_state, last_change_tick, change_tick);
 | 
					                                world,
 | 
				
			||||||
 | 
					                                &self.fetch_state,
 | 
				
			||||||
 | 
					                                last_change_tick,
 | 
				
			||||||
 | 
					                                change_tick,
 | 
				
			||||||
 | 
					                            );
 | 
				
			||||||
                            let mut filter = <QueryFetch<F> as Fetch>::init(
 | 
					                            let mut filter = <QueryFetch<F> as Fetch>::init(
 | 
				
			||||||
                                world,
 | 
					                                world,
 | 
				
			||||||
                                &self.filter_state,
 | 
					                                &self.filter_state,
 | 
				
			||||||
@ -1130,7 +1167,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // SAFETY: query is read only
 | 
					        // SAFETY: query is read only
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.get_single_unchecked_manual::<ROQueryFetch<'w, Q>>(
 | 
					            self.as_readonly().get_single_unchecked_manual(
 | 
				
			||||||
                world,
 | 
					                world,
 | 
				
			||||||
                world.last_change_tick(),
 | 
					                world.last_change_tick(),
 | 
				
			||||||
                world.read_change_tick(),
 | 
					                world.read_change_tick(),
 | 
				
			||||||
@ -1166,7 +1203,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // SAFETY: query has unique world access
 | 
					        // SAFETY: query has unique world access
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.get_single_unchecked_manual::<QueryFetch<'w, Q>>(
 | 
					            self.get_single_unchecked_manual(
 | 
				
			||||||
                world,
 | 
					                world,
 | 
				
			||||||
                world.last_change_tick(),
 | 
					                world.last_change_tick(),
 | 
				
			||||||
                world.read_change_tick(),
 | 
					                world.read_change_tick(),
 | 
				
			||||||
@ -1189,12 +1226,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
        world: &'w World,
 | 
					        world: &'w World,
 | 
				
			||||||
    ) -> Result<QueryItem<'w, Q>, QuerySingleError> {
 | 
					    ) -> Result<QueryItem<'w, Q>, QuerySingleError> {
 | 
				
			||||||
        self.update_archetypes(world);
 | 
					        self.update_archetypes(world);
 | 
				
			||||||
 | 
					        self.get_single_unchecked_manual(world, world.last_change_tick(), world.read_change_tick())
 | 
				
			||||||
        self.get_single_unchecked_manual::<QueryFetch<'w, Q>>(
 | 
					 | 
				
			||||||
            world,
 | 
					 | 
				
			||||||
            world.last_change_tick(),
 | 
					 | 
				
			||||||
            world.read_change_tick(),
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Returns a query result when there is exactly one entity matching the query,
 | 
					    /// Returns a query result when there is exactly one entity matching the query,
 | 
				
			||||||
@ -1208,13 +1240,13 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
 | 
				
			|||||||
    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
 | 
					    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
 | 
				
			||||||
    /// have unique access to the components they query.
 | 
					    /// have unique access to the components they query.
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub unsafe fn get_single_unchecked_manual<'w, QF: Fetch<'w, State = Q::State>>(
 | 
					    pub unsafe fn get_single_unchecked_manual<'w>(
 | 
				
			||||||
        &self,
 | 
					        &self,
 | 
				
			||||||
        world: &'w World,
 | 
					        world: &'w World,
 | 
				
			||||||
        last_change_tick: u32,
 | 
					        last_change_tick: u32,
 | 
				
			||||||
        change_tick: u32,
 | 
					        change_tick: u32,
 | 
				
			||||||
    ) -> Result<QF::Item, QuerySingleError> {
 | 
					    ) -> Result<QueryItem<'w, Q>, QuerySingleError> {
 | 
				
			||||||
        let mut query = self.iter_unchecked_manual::<QF>(world, last_change_tick, change_tick);
 | 
					        let mut query = self.iter_unchecked_manual(world, last_change_tick, change_tick);
 | 
				
			||||||
        let first = query.next();
 | 
					        let first = query.next();
 | 
				
			||||||
        let extra = query.next().is_some();
 | 
					        let extra = query.next().is_some();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,9 +2,8 @@ use crate::{
 | 
				
			|||||||
    component::Component,
 | 
					    component::Component,
 | 
				
			||||||
    entity::Entity,
 | 
					    entity::Entity,
 | 
				
			||||||
    query::{
 | 
					    query::{
 | 
				
			||||||
        NopFetch, QueryCombinationIter, QueryEntityError, QueryFetch, QueryItem, QueryIter,
 | 
					        QueryCombinationIter, QueryEntityError, QueryItem, QueryIter, QueryManyIter,
 | 
				
			||||||
        QueryManyIter, QuerySingleError, QueryState, ROQueryFetch, ROQueryItem, ReadOnlyWorldQuery,
 | 
					        QuerySingleError, QueryState, ROQueryItem, ReadOnlyWorldQuery, WorldQuery,
 | 
				
			||||||
        WorldQuery,
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    world::{Mut, World},
 | 
					    world::{Mut, World},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@ -292,12 +291,15 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
    /// # bevy_ecs::system::assert_is_system(report_names_system);
 | 
					    /// # bevy_ecs::system::assert_is_system(report_names_system);
 | 
				
			||||||
    /// ```
 | 
					    /// ```
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn iter(&self) -> QueryIter<'_, 's, Q, ROQueryFetch<'_, Q>, F> {
 | 
					    pub fn iter(&self) -> QueryIter<'_, 's, Q::ReadOnly, F::ReadOnly> {
 | 
				
			||||||
        // SAFETY: system runs without conflicts with other systems.
 | 
					        // SAFETY: system runs without conflicts with other systems.
 | 
				
			||||||
        // same-system queries have runtime borrow checks when they conflict
 | 
					        // same-system queries have runtime borrow checks when they conflict
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.state
 | 
					            self.state.as_readonly().iter_unchecked_manual(
 | 
				
			||||||
                .iter_unchecked_manual(self.world, self.last_change_tick, self.change_tick)
 | 
					                self.world,
 | 
				
			||||||
 | 
					                self.last_change_tick,
 | 
				
			||||||
 | 
					                self.change_tick,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -322,7 +324,7 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
    /// # bevy_ecs::system::assert_is_system(gravity_system);
 | 
					    /// # bevy_ecs::system::assert_is_system(gravity_system);
 | 
				
			||||||
    /// ```
 | 
					    /// ```
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn iter_mut(&mut self) -> QueryIter<'_, '_, Q, QueryFetch<'_, Q>, F> {
 | 
					    pub fn iter_mut(&mut self) -> QueryIter<'_, 's, Q, F> {
 | 
				
			||||||
        // SAFETY: system runs without conflicts with other systems.
 | 
					        // SAFETY: system runs without conflicts with other systems.
 | 
				
			||||||
        // same-system queries have runtime borrow checks when they conflict
 | 
					        // same-system queries have runtime borrow checks when they conflict
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
@ -339,11 +341,13 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
    /// - if `K < N`: all possible `K`-sized combinations of query results, without repetition
 | 
					    /// - if `K < N`: all possible `K`-sized combinations of query results, without repetition
 | 
				
			||||||
    /// - if `K > N`: empty set (no `K`-sized combinations exist)
 | 
					    /// - if `K > N`: empty set (no `K`-sized combinations exist)
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn iter_combinations<const K: usize>(&self) -> QueryCombinationIter<'_, '_, Q, F, K> {
 | 
					    pub fn iter_combinations<const K: usize>(
 | 
				
			||||||
 | 
					        &self,
 | 
				
			||||||
 | 
					    ) -> QueryCombinationIter<'_, '_, Q::ReadOnly, F::ReadOnly, K> {
 | 
				
			||||||
        // SAFETY: system runs without conflicts with other systems.
 | 
					        // SAFETY: system runs without conflicts with other systems.
 | 
				
			||||||
        // same-system queries have runtime borrow checks when they conflict
 | 
					        // same-system queries have runtime borrow checks when they conflict
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.state.iter_combinations_unchecked_manual(
 | 
					            self.state.as_readonly().iter_combinations_unchecked_manual(
 | 
				
			||||||
                self.world,
 | 
					                self.world,
 | 
				
			||||||
                self.last_change_tick,
 | 
					                self.last_change_tick,
 | 
				
			||||||
                self.change_tick,
 | 
					                self.change_tick,
 | 
				
			||||||
@ -422,14 +426,14 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
    pub fn iter_many<EntityList: IntoIterator>(
 | 
					    pub fn iter_many<EntityList: IntoIterator>(
 | 
				
			||||||
        &self,
 | 
					        &self,
 | 
				
			||||||
        entities: EntityList,
 | 
					        entities: EntityList,
 | 
				
			||||||
    ) -> QueryManyIter<'_, '_, Q, ROQueryFetch<'_, Q>, F, EntityList::IntoIter>
 | 
					    ) -> QueryManyIter<'_, '_, Q::ReadOnly, F::ReadOnly, EntityList::IntoIter>
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        EntityList::Item: Borrow<Entity>,
 | 
					        EntityList::Item: Borrow<Entity>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // SAFETY: system runs without conflicts with other systems.
 | 
					        // SAFETY: system runs without conflicts with other systems.
 | 
				
			||||||
        // same-system queries have runtime borrow checks when they conflict
 | 
					        // same-system queries have runtime borrow checks when they conflict
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.state.iter_many_unchecked_manual(
 | 
					            self.state.as_readonly().iter_many_unchecked_manual(
 | 
				
			||||||
                entities,
 | 
					                entities,
 | 
				
			||||||
                self.world,
 | 
					                self.world,
 | 
				
			||||||
                self.last_change_tick,
 | 
					                self.last_change_tick,
 | 
				
			||||||
@ -445,7 +449,7 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
    /// This function makes it possible to violate Rust's aliasing guarantees. You must make sure
 | 
					    /// This function makes it possible to violate Rust's aliasing guarantees. You must make sure
 | 
				
			||||||
    /// this call does not result in multiple mutable references to the same component
 | 
					    /// this call does not result in multiple mutable references to the same component
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub unsafe fn iter_unsafe(&'s self) -> QueryIter<'w, 's, Q, QueryFetch<'w, Q>, F> {
 | 
					    pub unsafe fn iter_unsafe(&'s self) -> QueryIter<'w, 's, Q, F> {
 | 
				
			||||||
        // SEMI-SAFETY: system runs without conflicts with other systems.
 | 
					        // SEMI-SAFETY: system runs without conflicts with other systems.
 | 
				
			||||||
        // same-system queries have runtime borrow checks when they conflict
 | 
					        // same-system queries have runtime borrow checks when they conflict
 | 
				
			||||||
        self.state
 | 
					        self.state
 | 
				
			||||||
@ -482,7 +486,7 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
    pub unsafe fn iter_many_unsafe<EntityList: IntoIterator>(
 | 
					    pub unsafe fn iter_many_unsafe<EntityList: IntoIterator>(
 | 
				
			||||||
        &self,
 | 
					        &self,
 | 
				
			||||||
        entities: EntityList,
 | 
					        entities: EntityList,
 | 
				
			||||||
    ) -> QueryManyIter<'_, '_, Q, QueryFetch<'_, Q>, F, EntityList::IntoIter>
 | 
					    ) -> QueryManyIter<'_, '_, Q, F, EntityList::IntoIter>
 | 
				
			||||||
    where
 | 
					    where
 | 
				
			||||||
        EntityList::Item: Borrow<Entity>,
 | 
					        EntityList::Item: Borrow<Entity>,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -522,7 +526,7 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
        // SAFETY: system runs without conflicts with other systems.
 | 
					        // SAFETY: system runs without conflicts with other systems.
 | 
				
			||||||
        // same-system queries have runtime borrow checks when they conflict
 | 
					        // same-system queries have runtime borrow checks when they conflict
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.state.for_each_unchecked_manual::<ROQueryFetch<Q>, _>(
 | 
					            self.state.as_readonly().for_each_unchecked_manual(
 | 
				
			||||||
                self.world,
 | 
					                self.world,
 | 
				
			||||||
                f,
 | 
					                f,
 | 
				
			||||||
                self.last_change_tick,
 | 
					                self.last_change_tick,
 | 
				
			||||||
@ -557,7 +561,7 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
        // SAFETY: system runs without conflicts with other systems. same-system queries have runtime
 | 
					        // SAFETY: system runs without conflicts with other systems. same-system queries have runtime
 | 
				
			||||||
        // borrow checks when they conflict
 | 
					        // borrow checks when they conflict
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.state.for_each_unchecked_manual::<QueryFetch<Q>, FN>(
 | 
					            self.state.for_each_unchecked_manual(
 | 
				
			||||||
                self.world,
 | 
					                self.world,
 | 
				
			||||||
                f,
 | 
					                f,
 | 
				
			||||||
                self.last_change_tick,
 | 
					                self.last_change_tick,
 | 
				
			||||||
@ -600,14 +604,13 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
        // SAFETY: system runs without conflicts with other systems. same-system queries have runtime
 | 
					        // SAFETY: system runs without conflicts with other systems. same-system queries have runtime
 | 
				
			||||||
        // borrow checks when they conflict
 | 
					        // borrow checks when they conflict
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.state
 | 
					            self.state.as_readonly().par_for_each_unchecked_manual(
 | 
				
			||||||
                .par_for_each_unchecked_manual::<ROQueryFetch<Q>, _>(
 | 
					                self.world,
 | 
				
			||||||
                    self.world,
 | 
					                batch_size,
 | 
				
			||||||
                    batch_size,
 | 
					                f,
 | 
				
			||||||
                    f,
 | 
					                self.last_change_tick,
 | 
				
			||||||
                    self.last_change_tick,
 | 
					                self.change_tick,
 | 
				
			||||||
                    self.change_tick,
 | 
					            );
 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -628,14 +631,13 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
        // SAFETY: system runs without conflicts with other systems. same-system queries have runtime
 | 
					        // SAFETY: system runs without conflicts with other systems. same-system queries have runtime
 | 
				
			||||||
        // borrow checks when they conflict
 | 
					        // borrow checks when they conflict
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.state
 | 
					            self.state.par_for_each_unchecked_manual(
 | 
				
			||||||
                .par_for_each_unchecked_manual::<QueryFetch<Q>, FN>(
 | 
					                self.world,
 | 
				
			||||||
                    self.world,
 | 
					                batch_size,
 | 
				
			||||||
                    batch_size,
 | 
					                f,
 | 
				
			||||||
                    f,
 | 
					                self.last_change_tick,
 | 
				
			||||||
                    self.last_change_tick,
 | 
					                self.change_tick,
 | 
				
			||||||
                    self.change_tick,
 | 
					            );
 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -724,7 +726,7 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
        // SAFETY: system runs without conflicts with other systems.
 | 
					        // SAFETY: system runs without conflicts with other systems.
 | 
				
			||||||
        // same-system queries have runtime borrow checks when they conflict
 | 
					        // same-system queries have runtime borrow checks when they conflict
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.state.get_unchecked_manual::<ROQueryFetch<Q>>(
 | 
					            self.state.as_readonly().get_unchecked_manual(
 | 
				
			||||||
                self.world,
 | 
					                self.world,
 | 
				
			||||||
                entity,
 | 
					                entity,
 | 
				
			||||||
                self.last_change_tick,
 | 
					                self.last_change_tick,
 | 
				
			||||||
@ -826,7 +828,7 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
        // SAFETY: system runs without conflicts with other systems.
 | 
					        // SAFETY: system runs without conflicts with other systems.
 | 
				
			||||||
        // same-system queries have runtime borrow checks when they conflict
 | 
					        // same-system queries have runtime borrow checks when they conflict
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.state.get_unchecked_manual::<QueryFetch<Q>>(
 | 
					            self.state.get_unchecked_manual(
 | 
				
			||||||
                self.world,
 | 
					                self.world,
 | 
				
			||||||
                entity,
 | 
					                entity,
 | 
				
			||||||
                self.last_change_tick,
 | 
					                self.last_change_tick,
 | 
				
			||||||
@ -919,12 +921,8 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
    ) -> Result<QueryItem<'w, Q>, QueryEntityError> {
 | 
					    ) -> Result<QueryItem<'w, Q>, QueryEntityError> {
 | 
				
			||||||
        // SEMI-SAFETY: system runs without conflicts with other systems.
 | 
					        // SEMI-SAFETY: system runs without conflicts with other systems.
 | 
				
			||||||
        // same-system queries have runtime borrow checks when they conflict
 | 
					        // same-system queries have runtime borrow checks when they conflict
 | 
				
			||||||
        self.state.get_unchecked_manual::<QueryFetch<Q>>(
 | 
					        self.state
 | 
				
			||||||
            self.world,
 | 
					            .get_unchecked_manual(self.world, entity, self.last_change_tick, self.change_tick)
 | 
				
			||||||
            entity,
 | 
					 | 
				
			||||||
            self.last_change_tick,
 | 
					 | 
				
			||||||
            self.change_tick,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Returns a reference to the [`Entity`]'s [`Component`] of the given type.
 | 
					    /// Returns a reference to the [`Entity`]'s [`Component`] of the given type.
 | 
				
			||||||
@ -1121,7 +1119,7 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
        // the query ensures that the components it accesses are not mutably accessible somewhere else
 | 
					        // the query ensures that the components it accesses are not mutably accessible somewhere else
 | 
				
			||||||
        // and the query is read only.
 | 
					        // and the query is read only.
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.state.get_single_unchecked_manual::<ROQueryFetch<Q>>(
 | 
					            self.state.as_readonly().get_single_unchecked_manual(
 | 
				
			||||||
                self.world,
 | 
					                self.world,
 | 
				
			||||||
                self.last_change_tick,
 | 
					                self.last_change_tick,
 | 
				
			||||||
                self.change_tick,
 | 
					                self.change_tick,
 | 
				
			||||||
@ -1186,7 +1184,7 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
        // the query ensures mutable access to the components it accesses, and the query
 | 
					        // the query ensures mutable access to the components it accesses, and the query
 | 
				
			||||||
        // is uniquely borrowed
 | 
					        // is uniquely borrowed
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.state.get_single_unchecked_manual::<QueryFetch<Q>>(
 | 
					            self.state.get_single_unchecked_manual(
 | 
				
			||||||
                self.world,
 | 
					                self.world,
 | 
				
			||||||
                self.last_change_tick,
 | 
					                self.last_change_tick,
 | 
				
			||||||
                self.change_tick,
 | 
					                self.change_tick,
 | 
				
			||||||
@ -1247,12 +1245,8 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
        // SAFETY: NopFetch does not access any members while &self ensures no one has exclusive access
 | 
					        // SAFETY: NopFetch does not access any members while &self ensures no one has exclusive access
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.state
 | 
					            self.state
 | 
				
			||||||
                .get_unchecked_manual::<NopFetch<Q::State>>(
 | 
					                .as_nop()
 | 
				
			||||||
                    self.world,
 | 
					                .get_unchecked_manual(self.world, entity, self.last_change_tick, self.change_tick)
 | 
				
			||||||
                    entity,
 | 
					 | 
				
			||||||
                    self.last_change_tick,
 | 
					 | 
				
			||||||
                    self.change_tick,
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                .is_ok()
 | 
					                .is_ok()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -1260,16 +1254,16 @@ impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
impl<'w, 's, Q: WorldQuery, F: WorldQuery> IntoIterator for &'w Query<'_, 's, Q, F> {
 | 
					impl<'w, 's, Q: WorldQuery, F: WorldQuery> IntoIterator for &'w Query<'_, 's, Q, F> {
 | 
				
			||||||
    type Item = ROQueryItem<'w, Q>;
 | 
					    type Item = ROQueryItem<'w, Q>;
 | 
				
			||||||
    type IntoIter = QueryIter<'w, 's, Q, ROQueryFetch<'w, Q>, F>;
 | 
					    type IntoIter = QueryIter<'w, 's, Q::ReadOnly, F::ReadOnly>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn into_iter(self) -> Self::IntoIter {
 | 
					    fn into_iter(self) -> Self::IntoIter {
 | 
				
			||||||
        self.iter()
 | 
					        self.iter()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<'w, Q: WorldQuery, F: WorldQuery> IntoIterator for &'w mut Query<'_, '_, Q, F> {
 | 
					impl<'w, 's, Q: WorldQuery, F: WorldQuery> IntoIterator for &'w mut Query<'_, 's, Q, F> {
 | 
				
			||||||
    type Item = QueryItem<'w, Q>;
 | 
					    type Item = QueryItem<'w, Q>;
 | 
				
			||||||
    type IntoIter = QueryIter<'w, 'w, Q, QueryFetch<'w, Q>, F>;
 | 
					    type IntoIter = QueryIter<'w, 's, Q, F>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn into_iter(self) -> Self::IntoIter {
 | 
					    fn into_iter(self) -> Self::IntoIter {
 | 
				
			||||||
        self.iter_mut()
 | 
					        self.iter_mut()
 | 
				
			||||||
@ -1349,7 +1343,7 @@ impl<'w, 's, Q: ReadOnlyWorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
        // SAFETY: system runs without conflicts with other systems.
 | 
					        // SAFETY: system runs without conflicts with other systems.
 | 
				
			||||||
        // same-system queries have runtime borrow checks when they conflict
 | 
					        // same-system queries have runtime borrow checks when they conflict
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.state.get_unchecked_manual::<ROQueryFetch<'w, Q>>(
 | 
					            self.state.as_readonly().get_unchecked_manual(
 | 
				
			||||||
                self.world,
 | 
					                self.world,
 | 
				
			||||||
                entity,
 | 
					                entity,
 | 
				
			||||||
                self.last_change_tick,
 | 
					                self.last_change_tick,
 | 
				
			||||||
@ -1382,12 +1376,15 @@ impl<'w, 's, Q: ReadOnlyWorldQuery, F: WorldQuery> Query<'w, 's, Q, F> {
 | 
				
			|||||||
    /// # bevy_ecs::system::assert_is_system(report_names_system);
 | 
					    /// # bevy_ecs::system::assert_is_system(report_names_system);
 | 
				
			||||||
    /// ```
 | 
					    /// ```
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    pub fn iter_inner(&'s self) -> QueryIter<'w, 's, Q, ROQueryFetch<'w, Q>, F> {
 | 
					    pub fn iter_inner(&'s self) -> QueryIter<'w, 's, Q::ReadOnly, F::ReadOnly> {
 | 
				
			||||||
        // SAFETY: system runs without conflicts with other systems.
 | 
					        // SAFETY: system runs without conflicts with other systems.
 | 
				
			||||||
        // same-system queries have runtime borrow checks when they conflict
 | 
					        // same-system queries have runtime borrow checks when they conflict
 | 
				
			||||||
        unsafe {
 | 
					        unsafe {
 | 
				
			||||||
            self.state
 | 
					            self.state.as_readonly().iter_unchecked_manual(
 | 
				
			||||||
                .iter_unchecked_manual(self.world, self.last_change_tick, self.change_tick)
 | 
					                self.world,
 | 
				
			||||||
 | 
					                self.last_change_tick,
 | 
				
			||||||
 | 
					                self.change_tick,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@ error[E0277]: the trait bound `bevy_ecs::query::Changed<Foo>: ArchetypeFilter` i
 | 
				
			|||||||
             (F0, F1, F2, F3, F4, F5, F6)
 | 
					             (F0, F1, F2, F3, F4, F5, F6)
 | 
				
			||||||
             (F0, F1, F2, F3, F4, F5, F6, F7)
 | 
					             (F0, F1, F2, F3, F4, F5, F6, F7)
 | 
				
			||||||
           and 26 others
 | 
					           and 26 others
 | 
				
			||||||
   = note: required because of the requirements on the impl of `ExactSizeIterator` for `QueryIter<'_, '_, &Foo, ReadFetch<'_, Foo>, bevy_ecs::query::Changed<Foo>>`
 | 
					   = note: required because of the requirements on the impl of `ExactSizeIterator` for `QueryIter<'_, '_, &Foo, bevy_ecs::query::Changed<Foo>>`
 | 
				
			||||||
note: required by a bound in `is_exact_size_iterator`
 | 
					note: required by a bound in `is_exact_size_iterator`
 | 
				
			||||||
  --> tests/ui/query_exact_sized_iterator_safety.rs:16:30
 | 
					  --> tests/ui/query_exact_sized_iterator_safety.rs:16:30
 | 
				
			||||||
   |
 | 
					   |
 | 
				
			||||||
@ -41,7 +41,7 @@ error[E0277]: the trait bound `bevy_ecs::query::Added<Foo>: ArchetypeFilter` is
 | 
				
			|||||||
             (F0, F1, F2, F3, F4, F5, F6)
 | 
					             (F0, F1, F2, F3, F4, F5, F6)
 | 
				
			||||||
             (F0, F1, F2, F3, F4, F5, F6, F7)
 | 
					             (F0, F1, F2, F3, F4, F5, F6, F7)
 | 
				
			||||||
           and 26 others
 | 
					           and 26 others
 | 
				
			||||||
   = note: required because of the requirements on the impl of `ExactSizeIterator` for `QueryIter<'_, '_, &Foo, ReadFetch<'_, Foo>, bevy_ecs::query::Added<Foo>>`
 | 
					   = note: required because of the requirements on the impl of `ExactSizeIterator` for `QueryIter<'_, '_, &Foo, bevy_ecs::query::Added<Foo>>`
 | 
				
			||||||
note: required by a bound in `is_exact_size_iterator`
 | 
					note: required by a bound in `is_exact_size_iterator`
 | 
				
			||||||
  --> tests/ui/query_exact_sized_iterator_safety.rs:16:30
 | 
					  --> tests/ui/query_exact_sized_iterator_safety.rs:16:30
 | 
				
			||||||
   |
 | 
					   |
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,7 @@ error[E0277]: the trait bound `&'static mut Foo: ReadOnlyWorldQuery` is not sati
 | 
				
			|||||||
             (F0, F1, F2, F3, F4)
 | 
					             (F0, F1, F2, F3, F4)
 | 
				
			||||||
             (F0, F1, F2, F3, F4, F5)
 | 
					             (F0, F1, F2, F3, F4, F5)
 | 
				
			||||||
             (F0, F1, F2, F3, F4, F5, F6)
 | 
					             (F0, F1, F2, F3, F4, F5, F6)
 | 
				
			||||||
           and 48 others
 | 
					           and 49 others
 | 
				
			||||||
   = note: `ReadOnlyWorldQuery` is implemented for `&'static Foo`, but not for `&'static mut Foo`
 | 
					   = note: `ReadOnlyWorldQuery` is implemented for `&'static Foo`, but not for `&'static mut Foo`
 | 
				
			||||||
   = note: required because of the requirements on the impl of `ReadOnlySystemParamFetch` for `QueryState<&'static mut Foo>`
 | 
					   = note: required because of the requirements on the impl of `ReadOnlySystemParamFetch` for `QueryState<&'static mut Foo>`
 | 
				
			||||||
   = note: 2 redundant requirements hidden
 | 
					   = note: 2 redundant requirements hidden
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,7 @@ error[E0277]: the trait bound `&'static mut Foo: ReadOnlyWorldQuery` is not sati
 | 
				
			|||||||
            (F0, F1, F2, F3, F4)
 | 
					            (F0, F1, F2, F3, F4)
 | 
				
			||||||
            (F0, F1, F2, F3, F4, F5)
 | 
					            (F0, F1, F2, F3, F4, F5)
 | 
				
			||||||
            (F0, F1, F2, F3, F4, F5, F6)
 | 
					            (F0, F1, F2, F3, F4, F5, F6)
 | 
				
			||||||
          and 51 others
 | 
					          and 52 others
 | 
				
			||||||
note: required by a bound in `_::assert_readonly`
 | 
					note: required by a bound in `_::assert_readonly`
 | 
				
			||||||
 --> tests/ui/world_query_derive.rs:7:10
 | 
					 --> tests/ui/world_query_derive.rs:7:10
 | 
				
			||||||
  |
 | 
					  |
 | 
				
			||||||
@ -36,7 +36,7 @@ error[E0277]: the trait bound `MutableMarked: ReadOnlyWorldQuery` is not satisfi
 | 
				
			|||||||
             (F0, F1, F2, F3, F4)
 | 
					             (F0, F1, F2, F3, F4)
 | 
				
			||||||
             (F0, F1, F2, F3, F4, F5)
 | 
					             (F0, F1, F2, F3, F4, F5)
 | 
				
			||||||
             (F0, F1, F2, F3, F4, F5, F6)
 | 
					             (F0, F1, F2, F3, F4, F5, F6)
 | 
				
			||||||
           and 51 others
 | 
					           and 52 others
 | 
				
			||||||
note: required by a bound in `_::assert_readonly`
 | 
					note: required by a bound in `_::assert_readonly`
 | 
				
			||||||
  --> tests/ui/world_query_derive.rs:18:10
 | 
					  --> tests/ui/world_query_derive.rs:18:10
 | 
				
			||||||
   |
 | 
					   |
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user