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

Emphasize no structural changes in SystemParam::get_param #17996

Merged
merged 6 commits into from
Mar 4, 2025

Conversation

GlennFolker
Copy link
Contributor

Objective

Many systems like Schedule rely on the fact that every structural ECS changes are deferred until an exclusive system flushes the World itself. This gives us the benefits of being able to run systems in parallel without worrying about dangling references caused by memory (re)allocations, which will in turn lead to Undefined Behavior. However, this isn't explicitly documented in SystemParam; currently it only vaguely hints that in init_state, based on the fact that structural ECS changes require mutable access to the whole World.

Solution

Document this behavior explicitly in SystemParam's type-level documentations.

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 ✨

@alice-i-cecile alice-i-cecile added C-Docs An addition or correction to our documentation A-ECS Entities, components, systems, and events P-Unsound A bug that results in undefined compiler behavior D-Unsafe Touches with unsafe code in some way labels Feb 23, 2025
@alice-i-cecile alice-i-cecile added the S-Needs-Review Needs reviewer attention (from anyone!) to move forward label Feb 23, 2025
@GlennFolker
Copy link
Contributor Author

Should I document this behavior on System::run_unsafe and SystemState::get_unchecked_manual too? I just realized end-users of those might not stumble upon this documentation on SystemParam...

@GlennFolker
Copy link
Contributor Author

I've added the note to WorldQuery and SystemState::get_unchecked_manual... I'm now a little confused about what to do with System::run_unsafe. Requiring no structural ECS changes to run_unsafe would be a trait-level safety invariant, thus marking System an unsafe trait, but that'll probably be a breaking change and I'm not sure if that is in the scope of this PR.

@chescock
Copy link
Contributor

The agree that the safety docs here need some clarification, and I do like the idea of giving advice that structural changes like register_component should be made in init_param!

I'm not sure this belongs as a safety requirement on trait SystemParam, though. The only way to perform structural changes from an UnsafeWorldCell is by calling unsafe fn world_mut(), and the safety requirements for that make it impossible to call safely from get_param.

Maybe we could instead improve the safety docs for UnsafeWorldCell?

It might also be less of an issue now that Rust 2024 made the unsafe_op_in_unsafe_fn lint warn by default. Calling unsafe methods on UnsafeWorldCell from within unsafe fn get_param() will now require unsafe blocks, which should help make the safety requirements more obvious.

Also note that if #16622 happens, then &mut World will be a SystemParam and it will be possible to do structural changes! So I don't think we want SystemParam::get_param or SystemState::get_unchecked_manual to promise that there won't be any.

@GlennFolker
Copy link
Contributor Author

Ah, right! I suppose clarifying this on UnsafeWorldCell::world_mut() is a better idea.

And about #16622, I think the promise would then be implied by whether SystemParam::world_access_level is exclusive or not, which could probably be mentioned in SystemParam::get_param for convenience.

@alice-i-cecile alice-i-cecile added S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Feb 24, 2025
@GlennFolker
Copy link
Contributor Author

Sorry for the overly long delay, I kinda forgot I made this PR at all 😅 Anyway, only UnsafeWorldCell::world_mut docs is changed now, which explicitly mentions QueryParam and SystemState. That should probably be enough to show the stop sign to users trying to invoke structural ECS changes there!

@alice-i-cecile alice-i-cecile added S-Needs-Review Needs reviewer attention (from anyone!) to move forward and removed S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Mar 4, 2025
@chescock chescock added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Mar 4, 2025
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Mar 4, 2025
Merged via the queue into bevyengine:main with commit c819beb Mar 4, 2025
32 checks passed
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-Docs An addition or correction to our documentation D-Unsafe Touches with unsafe code in some way 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.

3 participants