mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 20:53:53 +00:00
Replace some unsafe system executor code with safe code (#8274)
# Objective The function `SyncUnsafeCell::from_mut` returns `&SyncUnsafeCell<T>`, even though it could return `&mut SyncUnsafeCell<T>`. This means it is not possible to call `get_mut` on the returned value, so you need to use unsafe code to get exclusive access back. ## Solution Return `&mut Self` instead of `&Self` in `SyncUnsafeCell::from_mut`. This is consistent with my proposal for `UnsafeCell::from_mut`: https://github.com/rust-lang/libs-team/issues/198. Replace an unsafe pointer dereference with a safe call to `get_mut`. --- ## Changelog + The function `bevy_utils::SyncUnsafeCell::get_mut` now returns a value of type `&mut SyncUnsafeCell<T>`. Previously, this returned an immutable reference. ## Migration Guide The function `bevy_utils::SyncUnsafeCell::get_mut` now returns a value of type `&mut SyncUnsafeCell<T>`. Previously, this returned an immutable reference.
This commit is contained in:
parent
711efed018
commit
ae39b07d26
2 changed files with 8 additions and 8 deletions
|
@ -216,10 +216,8 @@ impl SystemExecutor for MultiThreadedExecutor {
|
|||
|
||||
if self.apply_final_buffers {
|
||||
// Do one final apply buffers after all systems have completed
|
||||
// SAFETY: all systems have completed, and so no outstanding accesses remain
|
||||
let world = unsafe { &mut *world.get() };
|
||||
// Commands should be applied while on the scope's thread, not the executor's thread
|
||||
apply_system_buffers(&self.unapplied_systems, systems, world);
|
||||
apply_system_buffers(&self.unapplied_systems, systems, world.get_mut());
|
||||
self.unapplied_systems.clear();
|
||||
debug_assert!(self.unapplied_systems.is_clear());
|
||||
}
|
||||
|
|
|
@ -76,11 +76,13 @@ impl<T: ?Sized> SyncUnsafeCell<T> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
/// Returns a `&SyncUnsafeCell<T>` from a `&mut T`.
|
||||
pub fn from_mut(t: &mut T) -> &SyncUnsafeCell<T> {
|
||||
// SAFETY: `&mut` ensures unique access, and `UnsafeCell<T>` and `SyncUnsafeCell<T>`
|
||||
// have #[repr(transparent)]
|
||||
unsafe { &*(t as *mut T as *const SyncUnsafeCell<T>) }
|
||||
/// Returns a `&mut SyncUnsafeCell<T>` from a `&mut T`.
|
||||
pub fn from_mut(t: &mut T) -> &mut SyncUnsafeCell<T> {
|
||||
let ptr = t as *mut T as *mut SyncUnsafeCell<T>;
|
||||
// SAFETY: `ptr` must be safe to mutably dereference, since it was originally
|
||||
// obtained from a mutable reference. `SyncUnsafeCell` has the same representation
|
||||
// as the original type `T`, since the former is annotated with #[repr(transparent)].
|
||||
unsafe { &mut *ptr }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue