Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - drop old value in insert_resource_by_id if exists #5587

Conversation

jakobhellermann
Copy link
Contributor

Objective

While trying out the lint unsafe_op_in_unsafe_fn I noticed that insert_resource_by_id didn't drop the old value if it already existed, and reimplemented Column::replace manually for no apparent reason.

Solution

  • use Column::replace and add a test expecting the correct drop count

Changelog

  • World::insert_resource_by_id will now correctly drop the old resource value, if one already existed

@jakobhellermann jakobhellermann added C-Bug An unexpected or incorrect behavior A-ECS Entities, components, systems, and events labels Aug 5, 2022
@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Aug 7, 2022
@@ -1813,6 +1807,46 @@ mod tests {
assert_eq!(DROP_COUNT.load(std::sync::atomic::Ordering::SeqCst), 1);
}

#[test]
fn insert_resource_by_id_drop_old() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use DropTestHelper and a regular rust type for the resource instead of doing this all dynamically. You can get the ComponentId representing the rust type via world.components.get_resource_id(TypeId::of::<Whatever>()).unwrap() (after you've inserted the resource the first time otherwise it wont have been registered lol)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the test to use DropTestHelper: https://github.com/bevyengine/bevy/pull/5587/files#diff-8799631eaab5e61e5dbc20251e08d83474df566ba159061cf2a78ce8f1fd59d5R1810-R1854

Unfortunately I had to use AssertUnwindSafe to be able to create the world outside of the catch_unwind and reference it afterwards, otherwise I was getting
| `&mut world::World` may not be safely transferred across an unwind boundary
I don't know much about unwind safety, do you know if this assertion is justified?
Alternatively I can create the world inside the catch_unwind and not remove the !contains_resource assert.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively I can create the world inside the catch_unwind and not remove the !contains_resource assert.

I prefer this approach as it's a bit less spooky.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can set make_component(false, 1) and get rid of the catch unwind/assertunwindsafe. I don't think panic in drop was relevent to this issue was it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can set make_component(false, 1) and get rid of the catch unwind/assertunwindsafe. I don't think panic in drop was relevent to this issue was it?

That is currently not possible with the DropTestHelper because it needs at least one dropped make_component(true) to "defuse" itself: #5615

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the AssertUnwindSafe and the !contains_resource assert.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh thats unfortunate oh well ...

@alice-i-cecile
Copy link
Member

bors r+

bors bot pushed a commit that referenced this pull request Aug 9, 2022
# Objective

While trying out the lint `unsafe_op_in_unsafe_fn` I noticed that `insert_resource_by_id` didn't drop the old value if it already existed, and reimplemented `Column::replace` manually for no apparent reason.

## Solution

- use `Column::replace` and add a test expecting the correct drop count

---

## Changelog

- `World::insert_resource_by_id` will now correctly drop the old resource value, if one already existed
@bors
Copy link
Contributor

bors bot commented Aug 9, 2022

Build failed (retrying...):

bors bot pushed a commit that referenced this pull request Aug 9, 2022
# Objective

While trying out the lint `unsafe_op_in_unsafe_fn` I noticed that `insert_resource_by_id` didn't drop the old value if it already existed, and reimplemented `Column::replace` manually for no apparent reason.

## Solution

- use `Column::replace` and add a test expecting the correct drop count

---

## Changelog

- `World::insert_resource_by_id` will now correctly drop the old resource value, if one already existed
@alice-i-cecile
Copy link
Member

bors r-

@bors
Copy link
Contributor

bors bot commented Aug 9, 2022

Canceled.

@alice-i-cecile
Copy link
Member

@jakobhellermann you'll need to update this PR to reflect the new explicit #[derive(Resource)] requirement.

@jakobhellermann
Copy link
Contributor Author

@jakobhellermann you'll need to update this PR to reflect the new explicit #[derive(Resource)] requirement.

done

@alice-i-cecile
Copy link
Member

bors r+

bors bot pushed a commit that referenced this pull request Aug 9, 2022
# Objective

While trying out the lint `unsafe_op_in_unsafe_fn` I noticed that `insert_resource_by_id` didn't drop the old value if it already existed, and reimplemented `Column::replace` manually for no apparent reason.

## Solution

- use `Column::replace` and add a test expecting the correct drop count

---

## Changelog

- `World::insert_resource_by_id` will now correctly drop the old resource value, if one already existed
@bors bors bot changed the title drop old value in insert_resource_by_id if exists [Merged by Bors] - drop old value in insert_resource_by_id if exists Aug 9, 2022
@bors bors bot closed this Aug 9, 2022
@jakobhellermann jakobhellermann deleted the insert-resource-by-id-drop-old branch August 10, 2022 13:12
bors bot pushed a commit that referenced this pull request Aug 30, 2022
# Objective

remove `insert_resource_with_id` because `insert_resource_by_id` exists and does almost exactly the same thing

blocked on #5587 because otherwise we will leak a resource when it's inserted 

## Solution

remove the function and also add a safety invariant of to `insert_resource_by_id` that the id be valid for the world.

I didn't see any discussion in #4447 about this safety invariant being left off in favor of a panic so I'm curious if there was one or if it just seemed nicer to have less safety invariants for callers to uphold 😅 

---

## Changelog

- safety invariant added to `insert_resource_by_id` requiring the id to be valid for world

## Migration Guide

- audit any calls to `insert_resource_by_id` making sure that the id is valid for the world

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
maccesch pushed a commit to Synphonyte/bevy that referenced this pull request Sep 28, 2022
# Objective

While trying out the lint `unsafe_op_in_unsafe_fn` I noticed that `insert_resource_by_id` didn't drop the old value if it already existed, and reimplemented `Column::replace` manually for no apparent reason.

## Solution

- use `Column::replace` and add a test expecting the correct drop count

---

## Changelog

- `World::insert_resource_by_id` will now correctly drop the old resource value, if one already existed
james7132 pushed a commit to james7132/bevy that referenced this pull request Oct 28, 2022
# Objective

While trying out the lint `unsafe_op_in_unsafe_fn` I noticed that `insert_resource_by_id` didn't drop the old value if it already existed, and reimplemented `Column::replace` manually for no apparent reason.

## Solution

- use `Column::replace` and add a test expecting the correct drop count

---

## Changelog

- `World::insert_resource_by_id` will now correctly drop the old resource value, if one already existed
james7132 pushed a commit to james7132/bevy that referenced this pull request Oct 28, 2022
# Objective

remove `insert_resource_with_id` because `insert_resource_by_id` exists and does almost exactly the same thing

blocked on bevyengine#5587 because otherwise we will leak a resource when it's inserted 

## Solution

remove the function and also add a safety invariant of to `insert_resource_by_id` that the id be valid for the world.

I didn't see any discussion in bevyengine#4447 about this safety invariant being left off in favor of a panic so I'm curious if there was one or if it just seemed nicer to have less safety invariants for callers to uphold 😅 

---

## Changelog

- safety invariant added to `insert_resource_by_id` requiring the id to be valid for world

## Migration Guide

- audit any calls to `insert_resource_by_id` making sure that the id is valid for the world

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
# Objective

While trying out the lint `unsafe_op_in_unsafe_fn` I noticed that `insert_resource_by_id` didn't drop the old value if it already existed, and reimplemented `Column::replace` manually for no apparent reason.

## Solution

- use `Column::replace` and add a test expecting the correct drop count

---

## Changelog

- `World::insert_resource_by_id` will now correctly drop the old resource value, if one already existed
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
# Objective

remove `insert_resource_with_id` because `insert_resource_by_id` exists and does almost exactly the same thing

blocked on bevyengine#5587 because otherwise we will leak a resource when it's inserted 

## Solution

remove the function and also add a safety invariant of to `insert_resource_by_id` that the id be valid for the world.

I didn't see any discussion in bevyengine#4447 about this safety invariant being left off in favor of a panic so I'm curious if there was one or if it just seemed nicer to have less safety invariants for callers to uphold 😅 

---

## Changelog

- safety invariant added to `insert_resource_by_id` requiring the id to be valid for world

## Migration Guide

- audit any calls to `insert_resource_by_id` making sure that the id is valid for the world

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Bug An unexpected or incorrect behavior S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants