From 41db723c5cacee53b3d8c5ad831a9c0d93ec2652 Mon Sep 17 00:00:00 2001 From: Sludge <96552222+SludgePhD@users.noreply.github.com> Date: Wed, 13 Dec 2023 01:55:30 +0100 Subject: [PATCH] Fix soundness of `UnsafeWorldCell` usage example (#10941) # Objective - The example in the docs is unsound. Demo: ```rust #[derive(Resource)] struct MyRes(u32); fn main() { let mut w = World::new(); w.insert_resource(MyRes(0)); let (mut res, comp) = split_world_access(&mut w); let mut r1 = res.get_resource_mut::().unwrap(); let mut r2 = res.get_resource_mut::().unwrap(); *r1 = MyRes(1); *r2 = MyRes(2); } ``` The API in the example allows aliasing mutable references to the same resource. Miri also complains when running this. ## Solution - Change the example API to make the returned `Mut` borrow from the `OnlyResourceAccessWorld` instead of borrowing from the world via `'w`. This prevents obtaining more than one `Mut` at the same time from it. --- crates/bevy_ecs/src/world/unsafe_world_cell.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/world/unsafe_world_cell.rs b/crates/bevy_ecs/src/world/unsafe_world_cell.rs index 25d5ac62c0305..428a1c1157650 100644 --- a/crates/bevy_ecs/src/world/unsafe_world_cell.rs +++ b/crates/bevy_ecs/src/world/unsafe_world_cell.rs @@ -56,7 +56,7 @@ use std::{any::TypeId, cell::UnsafeCell, fmt::Debug, marker::PhantomData}; /// struct OnlyComponentAccessWorld<'w>(UnsafeWorldCell<'w>); /// /// impl<'w> OnlyResourceAccessWorld<'w> { -/// fn get_resource_mut(&mut self) -> Option> { +/// fn get_resource_mut(&mut self) -> Option> { /// // SAFETY: resource access is allowed through this UnsafeWorldCell /// unsafe { self.0.get_resource_mut::() } /// }