-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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 Query::to_readonly
#5866
Conversation
dd80e6a
to
f854b85
Compare
added in #5376, pinging @harudagondi in case you have an opinion on keeping this api |
Can we do |
same issue as I definitely agree with this being a super useful feature :( A lot of work went into making it possible to implement and its disappointing that it can't be done "properly" yet.. |
Salvaging this feature in some way is important to me; I definitely agree that we should prioritize a simple solution to start though rather than wait on a full fix. @BoxyUwU what if we made the API unsafe for now? |
making the API unsafe basically renders it useless imo, the safety comment would be "dont call |
An alt fix could be to in Almost definitely slower than just checking |
|
Riffing on @BoxyUwU's variant idea: can we just have a |
Yeah that'd probably work too, its definitely not a "long term" fix but it would make this sound. |
Cool I think that has my preference as a short term fix. I'll put that together. A compile-time hungry option that might open some other design doors: Impl: Probably gratuitously expensive? |
Closing in favor of #6401 |
# Objective Fix the soundness issue outlined in #5866. In short the problem is that `query.to_readonly().get_component_mut::<T>()` can provide unsound mutable access to the component. This PR is an alternative to just removing the offending api. Given that `to_readonly` is a useful tool, I think this approach is a preferable short term solution. Long term I think theres a better solution out there, but we can find that on its own time. ## Solution Add what amounts to a "dirty flag" that marks Queries that have been converted to their read-only variant via `to_readonly` as dirty. When this flag is set to true, `get_component_mut` will fail with an error, preventing the unsound access.
…#6401) # Objective Fix the soundness issue outlined in bevyengine#5866. In short the problem is that `query.to_readonly().get_component_mut::<T>()` can provide unsound mutable access to the component. This PR is an alternative to just removing the offending api. Given that `to_readonly` is a useful tool, I think this approach is a preferable short term solution. Long term I think theres a better solution out there, but we can find that on its own time. ## Solution Add what amounts to a "dirty flag" that marks Queries that have been converted to their read-only variant via `to_readonly` as dirty. When this flag is set to true, `get_component_mut` will fail with an error, preventing the unsound access.
Query::to_readonly
is unsound:output of
cargo miri run
The "logic" for why this happens is because
get_component
(andget_component_mut
) rely onQueryState
's access exactly reflecting what the query is allowed to access. ButQuery::to_readonly()
invalidates that by having aQuery<&T>
exist with write access forT
.Alternative solutions:
to_readonly()
take&mut self
, I don't like this because implementingCopy
forQuery<Q: ReadOnlyWorldQuery>
would then be unsound which is something we should do in the futureget_component(_mut)
since they seem like they have limited utility and are now causing problems. This lifts the requirement by removing the only methods that actually rely on it. I'm opposed to this since it seems reasonable to me that the access of querystate does accurately reflect what you're allowed to access. Alternatively find some way to rewriteget_component(_mut)
to not use theQueryState
access and instead have a method onWorldQuery
to dynamically check if a component is part of our access (and at the same time remove the ability to access the access from querystate)QueryState
for the readonly variant and change to it inQuery::to_readonly
, I imagine this has some overlap with query joining since I expect that will want to be able to create "new"QueryState
's for that. I think I prefer this solution but it seems like a lot of work so doing this PR first to remove unsoundness seems best :)