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::<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.
This commit is contained in:
Sludge 2023-12-13 01:55:30 +01:00 committed by GitHub
parent ff7497cb9a
commit 41db723c5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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>() }
/// }