Skip to content

Clean up pointer use in BundleSpawner/BundleInserter#12269

Merged
james7132 merged 9 commits intobevyengine:mainfrom
james7132:cleanup-bundles
Mar 6, 2024
Merged

Clean up pointer use in BundleSpawner/BundleInserter#12269
james7132 merged 9 commits intobevyengine:mainfrom
james7132:cleanup-bundles

Conversation

@james7132
Copy link
Copy Markdown
Member

@james7132 james7132 commented Mar 3, 2024

Objective

Following #10756, we're now using raw pointers in BundleInserter and BundleSpawner. This is primarily to get around the need to split the borrow on the World, but it leaves a lot to be desired in terms of safety guarantees. There's no type level guarantee the code can't dereference a null pointer, and it's restoring them to borrows fairly liberally within the associated functions.

Solution

  • Replace the pointers with NonNull and a new bevy_ptr::ConstNonNull that only allows conversion back to read-only borrows
  • Remove the closure to avoid potentially aliasing through the closure by restructuring the match expression.
  • Move all conversions back into borrows as far up as possible to ensure that the borrow checker is at least locally followed.

@james7132 james7132 added A-ECS Entities, components, systems, and events C-Code-Quality A section of code that is hard to understand or change P-Unsound A bug that results in undefined compiler behavior labels Mar 3, 2024
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 3, 2024

You added a new example but didn't add metadata for it. Please update the root Cargo.toml file.

Copy link
Copy Markdown
Contributor

@james-j-obrien james-j-obrien left a comment

Choose a reason for hiding this comment

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

Looks reasonable to me.

@alice-i-cecile alice-i-cecile added this to the 0.14 milestone Mar 3, 2024
Copy link
Copy Markdown
Member

@joseph-gio joseph-gio left a comment

Choose a reason for hiding this comment

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

Definitely seems like an improvement

I wonder if it would make more sense for bevy_ptr's non-null API to look more like a typed version of bevy_ptr::Ptr

pub struct NonNull<'a, T> {
    ptr: NonNull<T>,
    _ref: PhantomData<&'a T>,
}
pub struct NonNullMut<'a, T> {
    ptr: NonNull<T>,
    _ref: PhantomData<&'a mut T>,
}

This should allow us to enforce at compile time that the data is initialized and aligned and valid for reads/writes, so to dereference it you'd just need to guarantee there's no aliasing

@james7132
Copy link
Copy Markdown
Member Author

james7132 commented Mar 4, 2024

I wonder if it would make more sense for bevy_ptr's non-null API to look more like a typed version of bevy_ptr::Ptr

Isn't that just &'a T and &'a mut T? The way I view it is that borrows are lifetimed, mutability-locked, aligned, and strongly typed pointers, and bevy_ptr tries to fill the gap between *mut () and &'a T by dropping one or more of the constraints on borrows.

@james7132 james7132 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 Mar 4, 2024
@joseph-gio
Copy link
Copy Markdown
Member

Isn't that just &'a T and &'a mut T?

I see it as an &'a mut T with the aliasing requirement lifted -- but I guess that's just &'a UnsafeCell<T>

@james7132 james7132 enabled auto-merge March 6, 2024 04:38
@alice-i-cecile alice-i-cecile disabled auto-merge March 6, 2024 04:41
@alice-i-cecile
Copy link
Copy Markdown
Member

CI is failing still <3

@james7132 james7132 added this pull request to the merge queue Mar 6, 2024
Merged via the queue into bevyengine:main with commit 4cd53cc Mar 6, 2024
spectria-limina pushed a commit to spectria-limina/bevy that referenced this pull request Mar 9, 2024
# Objective
Following bevyengine#10756, we're now using raw pointers in BundleInserter and
BundleSpawner. This is primarily to get around the need to split the
borrow on the World, but it leaves a lot to be desired in terms of
safety guarantees. There's no type level guarantee the code can't
dereference a null pointer, and it's restoring them to borrows fairly
liberally within the associated functions.

## Solution

* Replace the pointers with `NonNull` and a new `bevy_ptr::ConstNonNull`
that only allows conversion back to read-only borrows
* Remove the closure to avoid potentially aliasing through the closure
by restructuring the match expression.
* Move all conversions back into borrows as far up as possible to ensure
that the borrow checker is at least locally followed.
@james7132 james7132 deleted the cleanup-bundles branch March 10, 2024 07:27
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 P-Unsound A bug that results in undefined compiler 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.

5 participants