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

Remove Sync bound on Component and Resource #4680

Closed
wants to merge 17 commits into from

Conversation

james7132
Copy link
Member

@james7132 james7132 commented May 6, 2022

Objective

Fixes #2487. Remove the Sync bound on Component and Resource to allow Send-only components.

Solution

  • Remove Sync bound from Component and Resource.
  • Address the compilation errors.
  • Changed the PhantomData<T> in FetchState and SystemParamState to use PhantomData<fn() -> T> to ensure they're Sync.
  • Add a compile_fail_test.
  • Add Sync bound on the WorldQuery impl for &T.
  • Add Sync bound on Res<T> and Option<Res<T>>
  • Add Sync bound on Query::get_component, World::get, EntityRef::get, and EntityMut::get.

Changelog

Removed: Sync bound on Component and Resource.

Migration Guide

Component and Resource no longer requires Sync. Any generic code using Component as a bound, &T as Query parameter, or Res<T> might require an additional Sync bound.

@github-actions github-actions bot added the S-Needs-Triage This issue needs to be labelled label May 6, 2022
@james7132 james7132 force-pushed the relax-sync-bound branch from 50fce3c to 998b4bf Compare May 6, 2022 20:19
@DJMcNab
Copy link
Member

DJMcNab commented May 6, 2022

It's worth noting that at the time #2487 was written, Component also meant Resource (because #[derive(Component)] hadn't landed).

It's actually more interesting and useful to do the same transformation for resources.

That being said, if we can get this incrementally added I'm not too unhappy.

@james7132 james7132 added C-Feature A new feature, making something new possible A-ECS Entities, components, systems, and events and removed S-Needs-Triage This issue needs to be labelled labels May 6, 2022
@@ -13,7 +13,7 @@ use std::marker::PhantomData;
use super::Resource;

/// A [`World`] mutation.
pub trait Command: Send + Sync + 'static {
pub trait Command: Send + 'static {
Copy link
Member

Choose a reason for hiding this comment

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

I think we'll also want to do the same transformation for Send at some point.

Note that doing that requires we keep proper main thread management - it requires a lot of care.

Copy link

Choose a reason for hiding this comment

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

Is the Send + Sync necessary when the target is wasm?

Copy link
Member Author

Choose a reason for hiding this comment

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

Eventually we'll want Web Worker-based multithreading, so it will still be required.

@james7132
Copy link
Member Author

This is basically ready for review. I still need to figure out how to make the compile tests work.

@james7132 james7132 marked this pull request as ready for review May 7, 2022 00:36
@@ -370,7 +370,7 @@ mod menu {

// This system updates the settings when a new value for a setting is selected, and marks
// the button as the one currently selected
fn setting_button<T: Component + PartialEq + Copy>(
fn setting_button<T: Component + Sync + PartialEq + Copy>(
Copy link
Member

Choose a reason for hiding this comment

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

This is an unfortunate bound to need to add in end-user code.

What happens if it's omitted?

Copy link
Member Author

@james7132 james7132 May 7, 2022

Choose a reason for hiding this comment

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

The bound on &T fails to compile. This honestly only comes up in generic code though.

@james7132 james7132 changed the title Remove Sync bound on Component Remove Sync bound on Component and Resource May 8, 2022
@james7132
Copy link
Member Author

james7132 commented May 9, 2022

Following @DJMcNab's suggestion, I've been thinking on how to make &T and Res<T> safe for !Sync types, and concluded we basically just need &T to have the same effect as &mut T or ResMut<T> does for Sync types. However, this seems like the actual implementation needs either negative trait bounds to split the Component/Resource implementation, or rely on specialization of some kind, both of which are currently unstable or still very early in the RFC process for Rust itself. This seems like something we'll just have to come back to later when there's better language support.

@james7132 james7132 added the M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide label May 12, 2022
@JohnTheCoolingFan
Copy link
Contributor

JohnTheCoolingFan commented Jul 15, 2022

This PR would allow me to make a game similar to screeps but with lua using mlua crate. Hopefully this gets merged soon.

@alice-i-cecile
Copy link
Member

@JohnTheCoolingFan can you link to the mlua struct that needs this so we can try to understand a bit more about how this would help?

@JohnTheCoolingFan
Copy link
Contributor

https://docs.rs/mlua/latest/mlua/struct.Lua.html

@@ -553,12 +578,12 @@ impl<T: Component> WorldQuery for &T {
#[doc(hidden)]
pub struct ReadState<T> {
component_id: ComponentId,
marker: PhantomData<T>,
marker: PhantomData<fn() -> T>,
Copy link
Member

Choose a reason for hiding this comment

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

This aligns with my mental model of how this should be modelled, but this is subtle enough that it deserves a comment.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, I don't really think it's needed. This is very much the standard way to express 'this represents something which can produce a T'.

It's no more strange than the initial use of PhantomData imo - maybe we should have a comment that we need to be able to 'reconstruct' the original T, so store it here. But we don't need to comment specifically on it being fn()->T

@@ -292,6 +292,31 @@ use std::{cell::UnsafeCell, marker::PhantomData};
///
/// # bevy_ecs::system::assert_is_system(my_system);
/// ```
///
/// ## Non-Sync Queries
Copy link
Member

Choose a reason for hiding this comment

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

These docs are great; add a copy of this to Res and NonSend?

We should also try to deduplicate these docs with the include_str! doc macro trick; these are subtle and critical enough that I really don't want that duplication.

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.

Core changes are good, and make sense to me.

I have some doc nits that should be addressed, and I think that doc deduplication is unusually important here.

@Weibye Weibye added the S-Adopt-Me The original PR author has no intent to complete this work. Pick me up! label Aug 10, 2022
@alice-i-cecile
Copy link
Member

Closing in favor of the revived #5879.

@james7132 james7132 deleted the relax-sync-bound branch December 12, 2022 06:38
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-Feature A new feature, making something new possible M-Needs-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide S-Adopt-Me The original PR author has no intent to complete this work. Pick me up!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Component: Sync (might be) too strict.
6 participants