Skip to content

Commit

Permalink
Fix unsoundness in query component access (bevyengine#1929)
Browse files Browse the repository at this point in the history
Pretty much does what it says in the title lol
  • Loading branch information
BoxyUwU authored and ostwilkens committed Jul 27, 2021
1 parent 980e93a commit a064113
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 0 deletions.
7 changes: 7 additions & 0 deletions crates/bevy_ecs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,13 @@ mod tests {
world.query::<(&A, &mut A)>();
}

#[test]
#[should_panic]
fn mut_and_ref_query_panic() {
let mut world = World::new();
world.query::<(&mut A, &A)>();
}

#[test]
#[should_panic]
fn mut_and_mut_query_panic() {
Expand Down
8 changes: 8 additions & 0 deletions crates/bevy_ecs/src/query/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ unsafe impl<T: Component> FetchState for ReadState<T> {
}

fn update_component_access(&self, access: &mut FilteredAccess<ComponentId>) {
if access.access().has_write(self.component_id) {
panic!("&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
std::any::type_name::<T>());
}
access.add_read(self.component_id)
}

Expand Down Expand Up @@ -656,6 +660,10 @@ unsafe impl<T: Component> FetchState for ChangeTrackersState<T> {
}

fn update_component_access(&self, access: &mut FilteredAccess<ComponentId>) {
if access.access().has_write(self.component_id) {
panic!("ChangeTrackers<{}> conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
std::any::type_name::<T>());
}
access.add_read(self.component_id)
}

Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_ecs/src/query/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,10 @@ macro_rules! impl_tick_filter {

#[inline]
fn update_component_access(&self, access: &mut FilteredAccess<ComponentId>) {
if access.access().has_write(self.component_id) {
panic!("$state_name<{}> conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
std::any::type_name::<T>());
}
access.add_read(self.component_id);
}

Expand Down

0 comments on commit a064113

Please sign in to comment.