Skip to content

Commit ae39b07

Browse files
authored
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`: rust-lang/libs-team#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.
1 parent 711efed commit ae39b07

File tree

2 files changed

+8
-8
lines changed

2 files changed

+8
-8
lines changed

crates/bevy_ecs/src/schedule/executor/multi_threaded.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,8 @@ impl SystemExecutor for MultiThreadedExecutor {
216216

217217
if self.apply_final_buffers {
218218
// Do one final apply buffers after all systems have completed
219-
// SAFETY: all systems have completed, and so no outstanding accesses remain
220-
let world = unsafe { &mut *world.get() };
221219
// Commands should be applied while on the scope's thread, not the executor's thread
222-
apply_system_buffers(&self.unapplied_systems, systems, world);
220+
apply_system_buffers(&self.unapplied_systems, systems, world.get_mut());
223221
self.unapplied_systems.clear();
224222
debug_assert!(self.unapplied_systems.is_clear());
225223
}

crates/bevy_utils/src/syncunsafecell.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,13 @@ impl<T: ?Sized> SyncUnsafeCell<T> {
7676
}
7777

7878
#[inline]
79-
/// Returns a `&SyncUnsafeCell<T>` from a `&mut T`.
80-
pub fn from_mut(t: &mut T) -> &SyncUnsafeCell<T> {
81-
// SAFETY: `&mut` ensures unique access, and `UnsafeCell<T>` and `SyncUnsafeCell<T>`
82-
// have #[repr(transparent)]
83-
unsafe { &*(t as *mut T as *const SyncUnsafeCell<T>) }
79+
/// Returns a `&mut SyncUnsafeCell<T>` from a `&mut T`.
80+
pub fn from_mut(t: &mut T) -> &mut SyncUnsafeCell<T> {
81+
let ptr = t as *mut T as *mut SyncUnsafeCell<T>;
82+
// SAFETY: `ptr` must be safe to mutably dereference, since it was originally
83+
// obtained from a mutable reference. `SyncUnsafeCell` has the same representation
84+
// as the original type `T`, since the former is annotated with #[repr(transparent)].
85+
unsafe { &mut *ptr }
8486
}
8587
}
8688

0 commit comments

Comments
 (0)