Skip to content

Commit

Permalink
Fix soundness of UnsafeWorldCell usage example (bevyengine#10941)
Browse files Browse the repository at this point in the history
# 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::<MyRes>().unwrap();
    let mut r2 = res.get_resource_mut::<MyRes>().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.
  • Loading branch information
SludgePhD committed Dec 13, 2023
1 parent ff7497c commit 41db723
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/world/unsafe_world_cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: Resource>(&mut self) -> Option<Mut<'w, T>> {
/// fn get_resource_mut<T: Resource>(&mut self) -> Option<Mut<'_, T>> {
/// // SAFETY: resource access is allowed through this UnsafeWorldCell
/// unsafe { self.0.get_resource_mut::<T>() }
/// }
Expand Down

0 comments on commit 41db723

Please sign in to comment.