Skip to content

Commit 15be0d1

Browse files
Add/fix track_caller attribute on panicking entity accessor methods (#8951)
# Objective `World::entity`, `World::entity_mut` and `Commands::entity` should be marked with `track_caller` to display where (in user code) the call with the invalid `Entity` was made. `Commands::entity` already has the attibute, but it does nothing due to the call to `unwrap_or_else`. ## Solution - Apply the `track_caller` attribute to the `World::entity_mut` and `World::entity`. - Remove the call to `unwrap_or_else` which makes the `track_caller` attribute useless (because `unwrap_or_else` is not `track_caller` itself). The avoid eager evaluation of the panicking branch it is never inlined. --------- Co-authored-by: Giacomo Stevanato <[email protected]>
1 parent 1e73312 commit 15be0d1

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

crates/bevy_ecs/src/system/commands/mod.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,11 +307,19 @@ impl<'w, 's> Commands<'w, 's> {
307307
#[inline]
308308
#[track_caller]
309309
pub fn entity<'a>(&'a mut self, entity: Entity) -> EntityCommands<'w, 's, 'a> {
310-
self.get_entity(entity).unwrap_or_else(|| {
310+
#[inline(never)]
311+
#[cold]
312+
#[track_caller]
313+
fn panic_no_entity(entity: Entity) -> ! {
311314
panic!(
312315
"Attempting to create an EntityCommands for entity {entity:?}, which doesn't exist.",
313-
)
314-
})
316+
);
317+
}
318+
319+
match self.get_entity(entity) {
320+
Some(entity) => entity,
321+
None => panic_no_entity(entity),
322+
}
315323
}
316324

317325
/// Returns the [`EntityCommands`] for the requested [`Entity`], if it exists.

crates/bevy_ecs/src/world/mod.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,19 @@ impl World {
241241
/// assert_eq!(position.x, 0.0);
242242
/// ```
243243
#[inline]
244+
#[track_caller]
244245
pub fn entity(&self, entity: Entity) -> EntityRef {
245-
// Lazily evaluate panic!() via unwrap_or_else() to avoid allocation unless failure
246-
self.get_entity(entity)
247-
.unwrap_or_else(|| panic!("Entity {entity:?} does not exist"))
246+
#[inline(never)]
247+
#[cold]
248+
#[track_caller]
249+
fn panic_no_entity(entity: Entity) -> ! {
250+
panic!("Entity {entity:?} does not exist");
251+
}
252+
253+
match self.get_entity(entity) {
254+
Some(entity) => entity,
255+
None => panic_no_entity(entity),
256+
}
248257
}
249258

250259
/// Retrieves an [`EntityMut`] that exposes read and write operations for the given `entity`.
@@ -267,10 +276,19 @@ impl World {
267276
/// position.x = 1.0;
268277
/// ```
269278
#[inline]
279+
#[track_caller]
270280
pub fn entity_mut(&mut self, entity: Entity) -> EntityMut {
271-
// Lazily evaluate panic!() via unwrap_or_else() to avoid allocation unless failure
272-
self.get_entity_mut(entity)
273-
.unwrap_or_else(|| panic!("Entity {entity:?} does not exist"))
281+
#[inline(never)]
282+
#[cold]
283+
#[track_caller]
284+
fn panic_no_entity(entity: Entity) -> ! {
285+
panic!("Entity {entity:?} does not exist");
286+
}
287+
288+
match self.get_entity_mut(entity) {
289+
Some(entity) => entity,
290+
None => panic_no_entity(entity),
291+
}
274292
}
275293

276294
/// Returns the components of an [`Entity`](crate::entity::Entity) through [`ComponentInfo`](crate::component::ComponentInfo).

0 commit comments

Comments
 (0)