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 <giaco.stevanato@gmail.com>
This commit is contained in:
0xc0001a2040 2023-06-26 20:35:11 +02:00 committed by GitHub
parent 1e73312e49
commit 15be0d1a61
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 9 deletions

View file

@ -307,11 +307,19 @@ impl<'w, 's> Commands<'w, 's> {
#[inline]
#[track_caller]
pub fn entity<'a>(&'a mut self, entity: Entity) -> EntityCommands<'w, 's, 'a> {
self.get_entity(entity).unwrap_or_else(|| {
#[inline(never)]
#[cold]
#[track_caller]
fn panic_no_entity(entity: Entity) -> ! {
panic!(
"Attempting to create an EntityCommands for entity {entity:?}, which doesn't exist.",
)
})
);
}
match self.get_entity(entity) {
Some(entity) => entity,
None => panic_no_entity(entity),
}
}
/// Returns the [`EntityCommands`] for the requested [`Entity`], if it exists.

View file

@ -241,10 +241,19 @@ impl World {
/// assert_eq!(position.x, 0.0);
/// ```
#[inline]
#[track_caller]
pub fn entity(&self, entity: Entity) -> EntityRef {
// Lazily evaluate panic!() via unwrap_or_else() to avoid allocation unless failure
self.get_entity(entity)
.unwrap_or_else(|| panic!("Entity {entity:?} does not exist"))
#[inline(never)]
#[cold]
#[track_caller]
fn panic_no_entity(entity: Entity) -> ! {
panic!("Entity {entity:?} does not exist");
}
match self.get_entity(entity) {
Some(entity) => entity,
None => panic_no_entity(entity),
}
}
/// Retrieves an [`EntityMut`] that exposes read and write operations for the given `entity`.
@ -267,10 +276,19 @@ impl World {
/// position.x = 1.0;
/// ```
#[inline]
#[track_caller]
pub fn entity_mut(&mut self, entity: Entity) -> EntityMut {
// Lazily evaluate panic!() via unwrap_or_else() to avoid allocation unless failure
self.get_entity_mut(entity)
.unwrap_or_else(|| panic!("Entity {entity:?} does not exist"))
#[inline(never)]
#[cold]
#[track_caller]
fn panic_no_entity(entity: Entity) -> ! {
panic!("Entity {entity:?} does not exist");
}
match self.get_entity_mut(entity) {
Some(entity) => entity,
None => panic_no_entity(entity),
}
}
/// Returns the components of an [`Entity`](crate::entity::Entity) through [`ComponentInfo`](crate::component::ComponentInfo).