Skip to content

Box world to prevent pointer invalidation#20775

Closed
radiantgurl wants to merge 1 commit intobevyengine:mainfrom
radiantgurl:patch-1
Closed

Box world to prevent pointer invalidation#20775
radiantgurl wants to merge 1 commit intobevyengine:mainfrom
radiantgurl:patch-1

Conversation

@radiantgurl
Copy link

Objective

  • During subapp insertions, and depending on the hashmap implementation, subapps may be moved around for a rehash and reallocation. If there are any pointers held to the world unsafely, such as by the rendering pipeline, modifying subapps will invalidate them.

Solution

  • Boxing the world would pin it in place preventing the world pointer from becoming invalid if the subapps change.

Testing

  • Untested, i wrote the changes from my phone.

@github-actions
Copy link
Contributor

Welcome, new contributor!

Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨

Copy link
Contributor

@PhantomMorrigan PhantomMorrigan left a comment

Choose a reason for hiding this comment

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

This should use Pin<World> instead, while I don't think box would ever reallocate the world here, it's not guaranteed.Pin exists specifically for this kind of thing.

@SludgePhD
Copy link
Contributor

Why do you need to hold on to a raw pointer to World? That pointer will get invalidated when a &mut World is created by any plugin or user code, whether the World is boxed or not.

If bevy does decide to guarantee address stability for things like this, that guarantee should also be explicitly communicated in the documentation of the relevant types.

@SludgePhD
Copy link
Contributor

This should use Pin<World> instead, while I don't think box would ever reallocate the world here, it's not guaranteed.Pin exists specifically for this kind of thing.

Pin<Box<World>> does not prevent destructing and deallocating its contents. It is generally fine to use Box to achieve address stability, but the code that does so has to precisely define what invariants it actually provides. App allows callers to remove SubApps, and it allows obtaining mutable references to them (and their Worlds), which invalidates all other pointers.

@PhantomMorrigan
Copy link
Contributor

Oh, also this requires World to not implement Unpin. Which it does, because bevy currently gives absolutely no address guarantees. I think it's probably more reasonable to pin the whole SubApp instead of just the World.

As for the why, the answer is modding, and being able to do stuff like modifying SubApps during runtime. It's a bit of a weird exotic use case, but it is pretty interesting.

@james7132
Copy link
Member

I don't recall us having any point where we're holding non-lifetimed pointers into the render world ,and more specifically into it's on-stack representation. @radiantgurl could you illustrate where this is happening or what use case you envision this to enable? It's otherwise unclear what the motivation here is.

@alice-i-cecile alice-i-cecile added A-ECS Entities, components, systems, and events A-App Bevy apps and plugins X-Contentious There are nontrivial implications that should be thought through S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Aug 28, 2025
@radiantgurl
Copy link
Author

Superseded by #20975

This PR was supoosed to add constraints ensuring certain safety properties, but i found a better way of fixing the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-App Bevy apps and plugins A-ECS Entities, components, systems, and events S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged X-Contentious There are nontrivial implications that should be thought through

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants