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] - Improve safety for BlobVec::replace_unchecked #7181

Closed
wants to merge 23 commits into from

Conversation

JoJoJet
Copy link
Member

@JoJoJet JoJoJet commented Jan 13, 2023

Objective

  • The function BlobVec::replace_unchecked has informal use of safety comments.
  • This function does strange things with OwningPtr in order to get around the borrow checker.

Solution

  • Put safety comments in front of each unsafe operation. Describe the specific invariants of each operation and how they apply here.
  • Added a guard type OnDrop, which is used to simplify ownership transfer in case of a panic.

Changelog

  • Added the guard type bevy_utils::OnDrop.
  • Added conversions from Ptr, PtrMut, and OwningPtr to NonNull<u8>.

@JoJoJet JoJoJet added A-ECS Entities, components, systems, and events C-Code-Quality A section of code that is hard to understand or change labels Jan 13, 2023
Comment on lines 238 to 242
/// A type which calls a function when dropped.
/// This can be used to ensure that cleanup code is run even in case of a panic.
pub struct OnDrop<F: FnOnce()> {
callback: ManuallyDrop<F>,
}
Copy link
Member Author

Choose a reason for hiding this comment

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

The previous (private) version of this type used F: FnMut(), which made working with owned values complicated. Since we need unsafe code in order to make this work using FnOnce(), I figured it's worth going the extra mile and making this public.

Copy link
Member

Choose a reason for hiding this comment

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

Very clever: I like this. It would be nice to see a small doc test here.

@JoJoJet JoJoJet requested review from BoxyUwU and james7132 and removed request for BoxyUwU January 13, 2023 17:42
Copy link
Member

@james7132 james7132 left a comment

Choose a reason for hiding this comment

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

Generally LGTM. There are a few points to cover though.

let old_len = self.len;
let ptr = self.get_unchecked_mut(index).promote().as_ptr();
self.len = 0;
Copy link
Member

Choose a reason for hiding this comment

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

Thinking on this a bit more. This doesn't need to be done unless the drop value is Some.

Perhaps we should just branch on - drop and simplify the non-drop path.

Copy link
Member Author

Choose a reason for hiding this comment

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

I was doubtful at first but this suggestion turned out very nicely.

crates/bevy_ecs/src/storage/blob_vec.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/blob_vec.rs Outdated Show resolved Hide resolved
Copy link
Member

@james7132 james7132 left a comment

Choose a reason for hiding this comment

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

This looks so much better. LGTM.

Wondering if this saves a bit of perf on table moves.


/// A type which calls a function when dropped.
/// This can be used to ensure that cleanup code is run even in case of a panic.
pub struct OnDrop<F: FnOnce()> {
Copy link
Member

Choose a reason for hiding this comment

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

Btw, bevy_tasks also has a CallOnDrop impl which could replaced with this. Not sure if it's worth taking on bevy_utils as a dependency.

crates/bevy_ecs/src/storage/blob_vec.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/blob_vec.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/storage/blob_vec.rs Outdated Show resolved Hide resolved
Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

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

Much cleaner; I'm glad to see that Boxy's review comments helped.

@JoJoJet JoJoJet 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 Jan 15, 2023
@alice-i-cecile
Copy link
Member

bors r+

bors bot pushed a commit that referenced this pull request Jan 16, 2023
# Objective

- The function `BlobVec::replace_unchecked` has informal use of safety comments.
- This function does strange things with `OwningPtr` in order to get around the borrow checker.

## Solution

- Put safety comments in front of each unsafe operation. Describe the specific invariants of each operation and how they apply here.
- Added a guard type `OnDrop`, which is used to simplify ownership transfer in case of a panic.

---

## Changelog

+ Added the guard type `bevy_utils::OnDrop`.
+ Added conversions from `Ptr`, `PtrMut`, and `OwningPtr` to `NonNull<u8>`.
@bors bors bot changed the title Improve safety for BlobVec::replace_unchecked [Merged by Bors] - Improve safety for BlobVec::replace_unchecked Jan 16, 2023
@bors bors bot closed this Jan 16, 2023
alradish pushed a commit to alradish/bevy that referenced this pull request Jan 22, 2023
# Objective

- The function `BlobVec::replace_unchecked` has informal use of safety comments.
- This function does strange things with `OwningPtr` in order to get around the borrow checker.

## Solution

- Put safety comments in front of each unsafe operation. Describe the specific invariants of each operation and how they apply here.
- Added a guard type `OnDrop`, which is used to simplify ownership transfer in case of a panic.

---

## Changelog

+ Added the guard type `bevy_utils::OnDrop`.
+ Added conversions from `Ptr`, `PtrMut`, and `OwningPtr` to `NonNull<u8>`.
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
# Objective

- The function `BlobVec::replace_unchecked` has informal use of safety comments.
- This function does strange things with `OwningPtr` in order to get around the borrow checker.

## Solution

- Put safety comments in front of each unsafe operation. Describe the specific invariants of each operation and how they apply here.
- Added a guard type `OnDrop`, which is used to simplify ownership transfer in case of a panic.

---

## Changelog

+ Added the guard type `bevy_utils::OnDrop`.
+ Added conversions from `Ptr`, `PtrMut`, and `OwningPtr` to `NonNull<u8>`.
@JoJoJet JoJoJet deleted the ptr-safety branch March 30, 2023 11:56
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-Code-Quality A section of code that is hard to understand or change 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