From af22cc1dc3713a24115e1cf8088cf7d4703f6d34 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 3 Feb 2022 22:34:31 +0000 Subject: [PATCH] Use ManuallyDrop instead of forget in insert_resource_with_id (#2947) # Objective Calling forget would invalidate the data pointer before it is used. ## Solution Use `ManuallyDrop` to prevent the value from being dropped without moving it. --- crates/bevy_ecs/src/world/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/bevy_ecs/src/world/mod.rs b/crates/bevy_ecs/src/world/mod.rs index 24e302ade4..f53f4f3850 100644 --- a/crates/bevy_ecs/src/world/mod.rs +++ b/crates/bevy_ecs/src/world/mod.rs @@ -20,6 +20,7 @@ use crate::{ use std::{ any::TypeId, fmt, + mem::ManuallyDrop, sync::atomic::{AtomicU32, Ordering}, }; @@ -1003,13 +1004,13 @@ impl World { /// # Safety /// `component_id` must be valid and correspond to a resource component of type T #[inline] - unsafe fn insert_resource_with_id(&mut self, component_id: ComponentId, mut value: T) { + unsafe fn insert_resource_with_id(&mut self, component_id: ComponentId, value: T) { let change_tick = self.change_tick(); let column = self.initialize_resource_internal(component_id); if column.is_empty() { + let mut value = ManuallyDrop::new(value); // SAFE: column is of type T and has been allocated above - let data = (&mut value as *mut T).cast::(); - std::mem::forget(value); + let data = (&mut *value as *mut T).cast::(); column.push(data, ComponentTicks::new(change_tick)); } else { // SAFE: column is of type T and has already been allocated