Skip to content

EntityRef as WorldQuery is unsound. #9422

Closed
@joseph-gio

Description

@joseph-gio

Bevy version

Main branch.

What you did

    #[test]
    fn unsound_disjoint_mutable_access() {
        fn unsound_system(
            mut query: Query<(Entity, &mut TestComponent)>,
            refs: Query<super::EntityRef, Without<TestComponent>>,
        ) {
            let (id, mut c) = query.iter_mut().next().unwrap();
            let world = refs.iter().next().unwrap().world();

            // We now have mutable and shared access to the same component at the same time.
            let c2 = world.entity(id).get::<TestComponent>().unwrap();
            *c = TestComponent(1);
            println!("{c2:?}");
        }

        let mut world = World::new();
        world.spawn(TestComponent(0));
        world.spawn_empty();

        let mut schedule = Schedule::new();
        schedule.add_systems(unsound_system);

        schedule.run(&mut world);
    }

What went wrong

This should panic at runtime since the accesses of the two system params conflict. Instead, it runs and allows aliased mutable access.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ECSEntities, components, systems, and eventsC-BugAn unexpected or incorrect behaviorP-HighThis is particularly urgent, and deserves immediate attentionP-UnsoundA bug that results in undefined compiler behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions