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.
This commit is contained in:
		
							parent
							
								
									6ac9d6876f
								
							
						
					
					
						commit
						af22cc1dc3
					
				@ -20,6 +20,7 @@ use crate::{
 | 
				
			|||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
    any::TypeId,
 | 
					    any::TypeId,
 | 
				
			||||||
    fmt,
 | 
					    fmt,
 | 
				
			||||||
 | 
					    mem::ManuallyDrop,
 | 
				
			||||||
    sync::atomic::{AtomicU32, Ordering},
 | 
					    sync::atomic::{AtomicU32, Ordering},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1003,13 +1004,13 @@ impl World {
 | 
				
			|||||||
    /// # Safety
 | 
					    /// # Safety
 | 
				
			||||||
    /// `component_id` must be valid and correspond to a resource component of type T
 | 
					    /// `component_id` must be valid and correspond to a resource component of type T
 | 
				
			||||||
    #[inline]
 | 
					    #[inline]
 | 
				
			||||||
    unsafe fn insert_resource_with_id<T>(&mut self, component_id: ComponentId, mut value: T) {
 | 
					    unsafe fn insert_resource_with_id<T>(&mut self, component_id: ComponentId, value: T) {
 | 
				
			||||||
        let change_tick = self.change_tick();
 | 
					        let change_tick = self.change_tick();
 | 
				
			||||||
        let column = self.initialize_resource_internal(component_id);
 | 
					        let column = self.initialize_resource_internal(component_id);
 | 
				
			||||||
        if column.is_empty() {
 | 
					        if column.is_empty() {
 | 
				
			||||||
 | 
					            let mut value = ManuallyDrop::new(value);
 | 
				
			||||||
            // SAFE: column is of type T and has been allocated above
 | 
					            // SAFE: column is of type T and has been allocated above
 | 
				
			||||||
            let data = (&mut value as *mut T).cast::<u8>();
 | 
					            let data = (&mut *value as *mut T).cast::<u8>();
 | 
				
			||||||
            std::mem::forget(value);
 | 
					 | 
				
			||||||
            column.push(data, ComponentTicks::new(change_tick));
 | 
					            column.push(data, ComponentTicks::new(change_tick));
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            // SAFE: column is of type T and has already been allocated
 | 
					            // SAFE: column is of type T and has already been allocated
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user