-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Improve warning for Send resources marked as non_send #8000
Improve warning for Send resources marked as non_send #8000
Conversation
Welcome, new contributor! Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨ |
if SEND { | ||
assert!(component_info.is_send_and_sync()); | ||
assert!( | ||
component_info.is_send_and_sync(), | ||
"Send + Sync resource {} initialized as non_send", | ||
component_info.name(), | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I already asked on Discord but nobody answered: this check only triggers if a resource is first inserted as non-Send
and then as Send
. If the order is swapped this won't trigger (there's even a test for this). IMO this is inconsistent, it should either always trigger or never.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's perfectly safe to store a Send
type in !Send
storage, though probably a mistake to do so. We could fire a warning in the opposite case, but I'm against hard-failing when there's no safety issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's perfectly safe to store a
Send
type in!Send
storage
It's also safe to store a Send
type in Send
storage though. The problem is that component_info
is shared between Send
and non-Send
resources with the same TypeId
. When a resource is inserted as both Send
and non-Send
then component_info.is_send_and_sync()
will report only the value of the first one, which is however wrong for when the resource is first inserted as non-Send
. This can be fixed by either:
- giving two different
ComponentId
s toSend
and non-Send
resources with the sameTypeId
- for example this could be done by duplicating
Components::resource_indices
for non-Send
resources - in this case the given assertion would just become a sanity check and should never trigger in practice
- for example this could be done by duplicating
- or making it a hard fail
- this would essentially consist in making this assertion trigger in the opposite direction too, that is when a resource is inserted as
Send
first and then as non-Send
- this would essentially consist in making this assertion trigger in the opposite direction too, that is when a resource is inserted as
- or updating the
component_info
to setis_send_and_sync
when it isfalse
but aSend
Resource
is being inserted- this feels the worst option since it doesn't really fix the issue, it just hides it
At the end I would expect these two functions to either both succeed or both fail (currently only the first one succeeds):
#[derive(Resource)]
struct Foo;
fn send_then_non_send() {
let mut world = World::new();
world.insert_resource(Foo);
world.insert_non_send_resource(Foo);
}
fn non_send_then_send() {
let mut world = World::new();
world.insert_non_send_resource(Foo);
world.insert_resource(Foo);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The case where I ran into this error is much simpler and simply requires insert_non_send_resource, then adding a system that uses it. Doing insert_resource first does prevent the error, which seems a bit odd but that doesn't really cause any usability problems
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this is a pretty big footgun as is, changing the behavior here would be a breaking change, and probably not suited for a PR aiming at 0.10.1. I'm OK with just changing the panic message for now, and have a separate PR resolve this for 0.11.
Hopefully we get !Send
resources out of the World before then though.
Co-authored-by: James Liu <contact@jamessliu.com>
Objective
insert_non_send_resource
is called on a Send resourceSolution