bevy/crates
Jakob Hellermann 3643074f21 fix mutable aliases for a very short time if WorldCell is already borrowed (#6639)
# Objective

Consider the test
```rust
let cell = world.cell();
let _value_a = cell.resource_mut::<A>();
let _value_b = cell.resource_mut::<A>();
```

Currently, this will roughly execute

```rust
// first call
let value = unsafe {
    self.world
    .get_non_send_unchecked_mut_with_id(component_id)?
};
return Some(WorldBorrowMut::new(value, archetype_component_id, self.access)))

// second call
let value = unsafe {
    self.world
    .get_non_send_unchecked_mut_with_id(component_id)?
};
return Some(WorldBorrowMut::new(value, archetype_component_id, self.access)))
```
where `WorldBorrowMut::new` will panic if the resource is already borrowed.

This means, that `_value_a` will be created, the access checked (OK), then `value_b` will be created, and the access checked (`panic`).
For a moment, both `_value_a` and `_value_b` existed as `&mut T` to the same location, which is insta-UB as far as I understand it.

## Solution
Flip the order so that `WorldBorrowMut::new` first checks the access, _then_ fetches creates the value. To do that, we pass a `impl FnOnce() -> Mut<T>` instead of the `Mut<T>` directly:

```rust
let get_value = || unsafe {
    self.world
    .get_non_send_unchecked_mut_with_id(component_id)?
};
return Some(WorldBorrowMut::new(get_value, archetype_component_id, self.access)))
```
2022-11-30 13:50:03 -08:00
..
bevy_animation Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_app Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_asset Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_audio Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_core Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_core_pipeline Make Core Pipeline Graph Nodes Public (#6605) 2022-11-30 13:48:54 -08:00
bevy_derive Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_diagnostic Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_dylib Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_dynamic_plugin Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_ecs fix mutable aliases for a very short time if WorldCell is already borrowed (#6639) 2022-11-30 13:50:03 -08:00
bevy_ecs_compile_fail_tests Fix trybuild tests broken by rust 1.65 (#6457) 2022-11-03 15:09:27 +00:00
bevy_encase_derive Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_gilrs Bump gilrs version to 0.10 (#6558) 2022-11-30 13:46:11 -08:00
bevy_gltf Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_hierarchy bevy_scene: Add missing registration for SmallVec<[Entity; 8]> (#6578) 2022-11-30 13:45:41 -08:00
bevy_input Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_internal Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_log Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_macro_utils Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_math Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_mikktspace Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_pbr Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_ptr Respect alignment for zero-sized types stored in the world (#6618) 2022-11-30 13:44:52 -08:00
bevy_reflect Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_render Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_scene Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_sprite wasm: pad globals uniform also in 2d (#6643) 2022-11-30 13:48:24 -08:00
bevy_tasks Fix panicking on another scope (#6524) 2022-11-30 13:49:35 -08:00
bevy_text Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_time Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_transform Fix panicking on another scope (#6524) 2022-11-30 13:49:35 -08:00
bevy_ui Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_utils Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_window Release 0.9.0 (#6568) 2022-11-12 20:01:29 +00:00
bevy_winit Removed Mobile Touch event y-axis flip (#6597) 2022-11-30 13:49:08 -08:00