Repository navigation
Conversation
|
This is lovely, much preferred over the state transmute hokey pokey I was doing in #25642 :) +1 on the removal of the I'm liking the changes to the safety comments a lot! |
| /// | ||
| /// - Component access of `Self::ReadOnly` must be a subset of `Self` | ||
| /// and `Self::ReadOnly` must match exactly the same archetypes/tables as `Self` | ||
| /// - It must be valid to transmute `Self::State` to `Self::ReadOnly::State`, |
There was a problem hiding this comment.
Extremely clear and helpful!
| // SAFETY: access of `FilteredEntityRef` is a subset of `FilteredEntityMut` | ||
| // SAFETY: | ||
| // - `State` is `Access` for both `FilteredEntityMut` and `FilteredEntityRef`. | ||
| // `FilteredEntityRef` accepts any `Access`, so the transmute is always valid. |
There was a problem hiding this comment.
Nit: I think these safety comments would be clearer if they explained that FilteredEntityRef etc have maximal access, and so any transmutation is necessarily a non-strict subset.
| /// - Component access of `Self::ReadOnly` must be a subset of `Self` | ||
| /// and `Self::ReadOnly` must match exactly the same archetypes/tables as `Self` | ||
| /// - It must be valid to transmute `Self::State` to `Self::ReadOnly::State`, | ||
| /// and the resulting `Self::ReadOnly` must have a subset of the access of `Self` |
There was a problem hiding this comment.
| /// and the resulting `Self::ReadOnly` must have a subset of the access of `Self` | |
| /// and the resulting `Self::ReadOnly` must have a non-strict subset of the access of `Self` |
|
|
||
| /// The read-only variant of this [`QueryData`], which satisfies the [`ReadOnlyQueryData`] trait. | ||
| type ReadOnly: ReadOnlyQueryData<State = <Self as WorldQuery>::State>; | ||
| type ReadOnly: ReadOnlyQueryData; |
| /// | ||
| /// # Safety | ||
| /// | ||
| /// - Component access of `Self::ReadOnly` must be a subset of `Self` |
There was a problem hiding this comment.
This change is a meaningful change to our safety invariants here, and important to any manual implementation, but any impl which met this also meets the new variants.
Is this worth putting in a migration guide? Like, on the one hand this is non-breaking, but on the other hand I would certainly want to be alerted to this so I can update my safety contract.
There was a problem hiding this comment.
Rust is working towards Safety Contracts as Types https://internals.rust-lang.org/t/pre-rfc-unsafe-reasons/22093/1
Which means in the future, such a thing would indeed be a breaking change, so perhaps we make it idiom early?
alice-i-cecile
left a comment
There was a problem hiding this comment.
I'm basically good to approve this, but I have a couple of nits to discuss :) Very cool to see this lifted.
alice-i-cecile
left a comment
There was a problem hiding this comment.
Two other notes caught by AI-augmented review:
- The QueryData derive fails for mutable nested queries. Important to fix eventually obviously, but not critical to do now.
- There's stale doc comments saying that this doesn't work for mutable queries (line 2815 and 2960 in fetch.rs).
Argh, when looking into how this was different from tuples, I managed to convince myself that the tuple implementations are unsound and we can't take this approach :(. The problem is that if we have So I think we need to abandon this approach :(. The simplest alternative is the one in #25642, where we store a (The other approach I've come up with is #[reprt(transparent)]
struct QueryState<D: QueryData, F: QueryFilter>(QueryStateInner<D::State, F::State>);And then using I'll push the doc changes I made in response to the other comments, since we'll want the changes to the @tim-blackbird Would you like to re-open #25642 and get a bunch of suggestions for documentation changes, or would you prefer that I adopt the PR? |
|
Sorry to hear this didn't work out. I would like it if you could adopt #25642 for me :) |
|
Closing in favor of #25809 |
Objective
Support mutable queries using
NestedQuery.The reason this was not supported in the initial version is that we want
NestedQuery<D, F>::ReadOnly == NestedQuery<D::ReadOnly, F>, but that doesn't satisfy theReadOnly::State == Stateconstraint sinceQueryState<D::ReadOnly, F> != QueryState<D, F>.Solution
Remove the
ReadOnly::State == Stateconstraint, and replace it with a safety requirement.QueryState<D, F>could always be transmuted toQueryState<D::ReadOnly, F>, so the outer transmute is still valid.Note that the type constraint was merely a lint here. It was never enough for the states to be the same type, they also had to have compatible values! For example,
<&T>::State == ComponentId, but any value other than theComponentIdofTwould be unsound. Make this requirement explicit, and update the safety comments of mutable query types to show that they satisfy it.See also #25642 for an alternative approach.