-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Hooks and observers that run on spawn and immediately despawn their entity are unsound #19828
Copy link
Copy link
Closed
Labels
A-ECSEntities, components, systems, and eventsEntities, components, systems, and eventsC-BugAn unexpected or incorrect behaviorAn unexpected or incorrect behaviorP-UnsoundA bug that results in undefined compiler behaviorA bug that results in undefined compiler behavior
Description
Bevy version
0.16.1 and main branch
What you did
Attempted to despawn an entity from an insert hook, which triggered a debug panic in EntityWorldMut::new. For example:
use bevy::ecs::{
component::{Component, HookContext},
world::{DeferredWorld, World},
};
#[derive(Component)]
#[component(on_insert = on_insert_a)]
struct A;
fn on_insert_a(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) {
// This causes a panic in debug builds, but not in release builds.
world.commands().entity(entity).despawn();
}
fn main() {
let mut world = World::new();
world.spawn(A);
}What went wrong
When an entity is immediately despawned by a hook or observer, this flush in World::spawn_with_caller:
bevy/crates/bevy_ecs/src/world/mod.rs
Lines 1182 to 1185 in 479c93d
| if !unsafe { self.command_queue.is_empty() } { | |
| self.flush(); | |
| entity_location = self.entities().get(entity); | |
| } |
Invalidates this safety guarantee a few lines later:
bevy/crates/bevy_ecs/src/world/mod.rs
Lines 1187 to 1188 in 479c93d
| // SAFETY: entity and location are valid, as they were just created above | |
| let mut entity = unsafe { EntityWorldMut::new(self, entity, entity_location) }; |
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
A-ECSEntities, components, systems, and eventsEntities, components, systems, and eventsC-BugAn unexpected or incorrect behaviorAn unexpected or incorrect behaviorP-UnsoundA bug that results in undefined compiler behaviorA bug that results in undefined compiler behavior
Type
Projects
Status
Observer overhaul