@@ -142,11 +142,20 @@ impl<'w> BundleRemover<'w> {
142142 // SAFETY: We only keep access to archetype/bundle data.
143143 let mut deferred_world = self . world . into_deferred ( ) ;
144144 let bundle_components_in_archetype = || {
145- self . bundle_info
146- . as_ref ( )
145+ // SAFETY:
146+ // * Pointer was created from a reference in `Self::new_with_id` and so is `dereferencable`.
147+ // * `Self`'s lifetime is tied to an exclusive reference to `World` and it does not make structural
148+ // changes to the world, so the data is valid for the lifetime of `Self`
149+ let ( bundle_info, old_archetype) =
150+ ( self . bundle_info . as_ref ( ) , self . old_archetype . as_ref ( ) ) ;
151+ bundle_info
147152 . iter_explicit_components ( )
148- . filter ( |component_id| self . old_archetype . as_ref ( ) . contains ( * component_id) )
153+ . filter ( |component_id| old_archetype. contains ( * component_id) )
149154 } ;
155+ // SAFETY:
156+ // * Pointer was created from a reference in `Self::new_with_id` and so is `dereferencable`.
157+ // * `Self`'s lifetime is tied to an exclusive reference to `World` and it does not make structural
158+ // changes to the world, so the data is valid for the lifetime of `Self`
150159 if self . old_archetype . as_ref ( ) . has_replace_observer ( ) {
151160 let components = bundle_components_in_archetype ( ) . collect :: < Vec < _ > > ( ) ;
152161 // SAFETY: the REPLACE event_key corresponds to the Replace event's type
@@ -160,12 +169,20 @@ impl<'w> BundleRemover<'w> {
160169 ) ;
161170 }
162171 deferred_world. trigger_on_replace (
172+ // SAFETY:
173+ // * Pointer was created from a reference in `Self::new_with_id` and so is `dereferencable`.
174+ // * `Self`'s lifetime is tied to an exclusive reference to `World` and it does not make structural
175+ // changes to the world, so the data is valid for the lifetime of `Self`
163176 self . old_archetype . as_ref ( ) ,
164177 entity,
165178 bundle_components_in_archetype ( ) ,
166179 caller,
167180 self . relationship_hook_mode ,
168181 ) ;
182+ // SAFETY:
183+ // * Pointer was created from a reference in `Self::new_with_id` and so is `dereferencable`.
184+ // * `Self`'s lifetime is tied to an exclusive reference to `World` and it does not make structural
185+ // changes to the world, so the data is valid for the lifetime of `Self`
169186 if self . old_archetype . as_ref ( ) . has_remove_observer ( ) {
170187 let components = bundle_components_in_archetype ( ) . collect :: < Vec < _ > > ( ) ;
171188 // SAFETY: the REMOVE event_key corresponds to the Remove event's type
@@ -179,6 +196,10 @@ impl<'w> BundleRemover<'w> {
179196 ) ;
180197 }
181198 deferred_world. trigger_on_remove (
199+ // SAFETY:
200+ // * Pointer was created from a reference in `Self::new_with_id` and so is `dereferencable`.
201+ // * `Self`'s lifetime is tied to an exclusive reference to `World` and it does not make structural
202+ // changes to the world, so the data is valid for the lifetime of `Self`
182203 self . old_archetype . as_ref ( ) ,
183204 entity,
184205 bundle_components_in_archetype ( ) ,
@@ -196,18 +217,34 @@ impl<'w> BundleRemover<'w> {
196217 // SAFETY: There is no conflicting access for this scope.
197218 . map ( |( old, _) | unsafe { & mut * old. as_ptr ( ) } ) ,
198219 & world. components ,
199- self . bundle_info . as_ref ( ) . explicit_components ( ) ,
220+ // SAFETY:
221+ // * Pointer was created from a reference in `Self::new_with_id` and so is `dereferencable`.
222+ // * `Self`'s lifetime is tied to an exclusive reference to `World` and it does not make structural
223+ // changes to the world, so the data is valid for the lifetime of `Self`
224+ unsafe { self . bundle_info . as_ref ( ) } . explicit_components ( ) ,
200225 ) ;
201226
202227 // Handle sparse set removes
203- for component_id in self . bundle_info . as_ref ( ) . iter_explicit_components ( ) {
204- if self . old_archetype . as_ref ( ) . contains ( component_id) {
228+ // SAFETY:
229+ // * Pointer was created from a reference in `Self::new_with_id` and so is `dereferencable`.
230+ // * `Self`'s lifetime is tied to an exclusive reference to `World` and it does not make structural
231+ // changes to the world, so the data is valid for the lifetime of `Self`
232+ for component_id in unsafe { self . bundle_info . as_ref ( ) } . iter_explicit_components ( ) {
233+ // SAFETY:
234+ // * Pointer was created from a reference in `Self::new_with_id` and so is `dereferencable`.
235+ // * `Self`'s lifetime is tied to an exclusive reference to `World` and it does not make structural
236+ // changes to the world, so the data is valid for the lifetime of `Self`
237+ if unsafe { self . old_archetype . as_ref ( ) } . contains ( component_id) {
205238 world. removed_components . write ( component_id, entity) ;
206239
207240 // Make sure to drop components stored in sparse sets.
208241 // Dense components are dropped later in `move_to_and_drop_missing_unchecked`.
209242 if let Some ( StorageType :: SparseSet ) =
210- self . old_archetype . as_ref ( ) . get_storage_type ( component_id)
243+ // SAFETY:
244+ // * Pointer was created from a reference in `Self::new_with_id` and so is `dereferencable`.
245+ // * `Self`'s lifetime is tied to an exclusive reference to `World` and it does not make structural
246+ // changes to the world, so the data is valid for the lifetime of `Self`
247+ unsafe { self . old_archetype . as_ref ( ) } . get_storage_type ( component_id)
211248 {
212249 world
213250 . storages
@@ -222,10 +259,12 @@ impl<'w> BundleRemover<'w> {
222259 }
223260
224261 // Handle archetype change
225- let remove_result = self
226- . old_archetype
227- . as_mut ( )
228- . swap_remove ( location. archetype_row ) ;
262+ let remove_result =
263+ // SAFETY:
264+ // * Pointer was created from a reference in `Self::new_with_id` and so is `dereferencable`.
265+ // * `Self`'s lifetime is tied to an exclusive reference to `World` and it does not make structural
266+ // changes to the world, so the data is valid for the lifetime of `Self`
267+ unsafe { self . old_archetype . as_mut ( ) } . swap_remove ( location. archetype_row ) ;
229268 // if an entity was moved into this entity's archetype row, update its archetype row
230269 if let Some ( swapped_entity) = remove_result. swapped_entity {
231270 let swapped_location = world. entities . get_spawned ( swapped_entity) . unwrap ( ) ;
@@ -244,28 +283,36 @@ impl<'w> BundleRemover<'w> {
244283 // Handle table change
245284 let new_location = if let Some ( ( mut old_table, mut new_table) ) = self . old_and_new_table {
246285 let move_result = if needs_drop {
286+ // SAFETY:
287+ // * Pointer was created from a reference in `Self::new_with_id` and so is `dereferencable`.
288+ // * `Self`'s lifetime is tied to an exclusive reference to `World` and it does not make structural
289+ // changes to the world, so the data is valid for the lifetime of `Self`
290+ let old_table = unsafe { old_table. as_mut ( ) } ;
291+
247292 // SAFETY: old_table_row exists
248293 unsafe {
249294 old_table
250- . as_mut ( )
251295 . move_to_and_drop_missing_unchecked ( location. table_row , new_table. as_mut ( ) )
252296 }
253297 } else {
298+ // SAFETY:
299+ // * Pointer was created from a reference in `Self::new_with_id` and so is `dereferencable`.
300+ // * `Self`'s lifetime is tied to an exclusive reference to `World` and it does not make structural
301+ // changes to the world, so the data is valid for the lifetime of `Self`
302+ let ( old_table, new_table) = unsafe { ( old_table. as_mut ( ) , new_table. as_mut ( ) ) } ;
254303 // SAFETY: old_table_row exists
255304 unsafe {
256- old_table. as_mut ( ) . move_to_and_forget_missing_unchecked (
257- location. table_row ,
258- new_table. as_mut ( ) ,
259- )
305+ old_table. move_to_and_forget_missing_unchecked ( location. table_row , new_table)
260306 }
261307 } ;
262308
309+ // SAFETY:
310+ // * Pointer was created from a reference in `Self::new_with_id` and so is `dereferencable`.
311+ // * `Self`'s lifetime is tied to an exclusive reference to `World` and it does not make structural
312+ // changes to the world, so the data is valid for the lifetime of `Self`
313+ let new_archetype = unsafe { self . new_archetype . as_mut ( ) } ;
263314 // SAFETY: move_result.new_row is a valid position in new_archetype's table
264- let new_location = unsafe {
265- self . new_archetype
266- . as_mut ( )
267- . allocate ( entity, move_result. new_row )
268- } ;
315+ let new_location = unsafe { new_archetype. allocate ( entity, move_result. new_row ) } ;
269316
270317 // if an entity was moved into this entity's table row, update its table row
271318 if let Some ( swapped_entity) = move_result. swapped_entity {
@@ -286,10 +333,13 @@ impl<'w> BundleRemover<'w> {
286333
287334 new_location
288335 } else {
336+ // SAFETY:
337+ // * Pointer was created from a reference in `Self::new_with_id` and so is `dereferencable`.
338+ // * `Self`'s lifetime is tied to an exclusive reference to `World` and it does not make structural
339+ // changes to the world, so the data is valid for the lifetime of `Self`
340+ let new_archetype = unsafe { self . new_archetype . as_mut ( ) } ;
289341 // The tables are the same
290- self . new_archetype
291- . as_mut ( )
292- . allocate ( entity, location. table_row )
342+ new_archetype. allocate ( entity, location. table_row )
293343 } ;
294344
295345 // SAFETY: The entity is valid and has been moved to the new location already.
0 commit comments