Skip to content

Conversation

cBournhonesque
Copy link
Contributor

@cBournhonesque cBournhonesque commented Aug 1, 2024

Objective

  • Fixes Alias violations for EntityMut/EntityRef #14575
  • There is a soundness issue because we use conflicts() to check for system ambiguities + soundness issues. However since the current conflicts is a Vec<T>, we cannot express conflicts where there is no specific ComponentId at fault. For example q1: Query<EntityMut>, q2: Query<EntityMut>
    There was a TODO to handle the write_all case but it was never resolved

Solution

  • Introduce an AccessConflict enum that is either a list of specific ids that are conflicting or All if all component ids are conflicting

Testing

  • Introduced a new unit test to check for the EntityMut case

Migration guide

The get_conflicts method of Access now returns an AccessConflict enum instead of simply a Vec of ComponentIds that are causing the access conflict. This can be useful in cases where there are no particular ComponentIds conflicting, but instead all of them are; for example fn system(q1: Query<EntityMut>, q2: Query<EntityRef>)

AccessConflict::All => {
// there is no specific component conflicting, but the systems are overall incompatible
// for example 2 systems with `Query<EntityMut>`
conflicting_systems.push((a, b, Vec::new()));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is not ideal.. maybe we'd like to introduce a similar enum in the schedule graph conflicts? not sure if that's what we want

Copy link
Member

Choose a reason for hiding this comment

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

IMO this can wait until follow-up.

Copy link
Contributor

@hymm hymm Aug 2, 2024

Choose a reason for hiding this comment

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

Out of curiousity, what happens with the ambiguity reporting in this case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cBournhonesque cBournhonesque added A-ECS Entities, components, systems, and events C-Bug An unexpected or incorrect behavior P-High This is particularly urgent, and deserves immediate attention P-Unsound A bug that results in undefined compiler behavior S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Aug 1, 2024
@cBournhonesque cBournhonesque added the D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes label Aug 2, 2024
@alice-i-cecile alice-i-cecile added this to the 0.14.1 milestone Aug 2, 2024
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.

I'm in favor of newtyping the conflicts here: more flexible and clearer.

This has tests for both the query and the system case which is great, but I'd also like to see EntityRef + EntityMut, and EntityMut + &World tested.

@alice-i-cecile alice-i-cecile modified the milestones: 0.14.1, 0.14.2 Aug 2, 2024
let mut conflicts = FixedBitSet::new();
if self.reads_all {
// QUESTION: How to handle `other.writes_all`?
if other.writes_all {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is the key change


/// Returns a vector of elements that this and `other` cannot access at the same time.
pub fn get_conflicts(&self, other: &FilteredAccess<T>) -> Vec<T> {
pub fn get_conflicts(&self, other: &FilteredAccess<T>) -> AccessConflict {
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 technically breaking, but I don't think it's worth refactoring to avoid this.

Copy link
Contributor

Choose a reason for hiding this comment

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

my general opinion is that fixing unsoundness takes priority over semver. there are of course ways to avoid both in the same release but getting the soundness fix out as quickly as possible is important imo.

@alice-i-cecile alice-i-cecile added the M-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide label Aug 2, 2024
@alice-i-cecile alice-i-cecile modified the milestones: 0.14.2, 0.15 Aug 2, 2024
Copy link
Contributor

github-actions bot commented Aug 2, 2024

It looks like your PR is a breaking change, but you didn't provide a migration guide.

Could you add some context on what users should update when this change get released in a new version of Bevy?
It will be used to help writing the migration guide for the version. Putting it after a ## Migration Guide will help it get automatically picked up by our tooling.

Copy link
Contributor

@soqb soqb left a comment

Choose a reason for hiding this comment

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

definitely a solid soundness fix; a couple of nits which can easily wait until a followup!

@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 Aug 3, 2024
@alice-i-cecile
Copy link
Member

I like these little suggestions: let me know if you want to do them now or in a follow-up :)

@cBournhonesque
Copy link
Contributor Author

I like these little suggestions: let me know if you want to do them now or in a follow-up :)

They make sense to me; I applied them now!

@alice-i-cecile alice-i-cecile 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-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Aug 3, 2024
@alice-i-cecile alice-i-cecile modified the milestones: 0.15, 0.14.2 Aug 3, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Aug 6, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to a conflict with the base branch Aug 6, 2024
@alice-i-cecile
Copy link
Member

@cBournhonesque let me know when the conflicts are resolved. I was pretty sure this would happen 😂

@cBournhonesque
Copy link
Contributor Author

@cBournhonesque let me know when the conflicts are resolved. I was pretty sure this would happen 😂

Indeed! Updated :)

@alice-i-cecile alice-i-cecile added this pull request to the merge queue Aug 6, 2024
Merged via the queue into bevyengine:main with commit e85c072 Aug 6, 2024
Comment on lines -507 to 521
if self.reads_all_resources {
// QUESTION: How to handle `other.writes_all`?
if other.reads_all_resources {
return AccessConflicts::All;
}
conflicts.extend(other.resource_writes.ones());
}

if other.reads_all_resources {
// QUESTION: How to handle `self.writes_all`.
if self.reads_all_resources {
return AccessConflicts::All;
}
conflicts.extend(self.resource_writes.ones());
Copy link
Contributor

Choose a reason for hiding this comment

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

These two new inner ifs should check for writes_all_resources and not reads_all_resources.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh you'r right, that's a bug..
We don't have a unit test for this because there's nothing that queries all resources but not all components

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should we remove the AccessConflicts::ALL conflicts for resources entirely?

github-merge-queue bot pushed a commit that referenced this pull request Aug 6, 2024
# Objective

- I made a mistake when fixing the merge conflicts here:
#14579 (comment)

It wasn't caught because there's no easy way to trigger access conflicts
with resources without triggering them with components first.
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-Bug An unexpected or incorrect behavior D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes M-Migration-Guide A breaking change to Bevy's public API that needs to be noted in a migration guide P-High This is particularly urgent, and deserves immediate attention 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.

Alias violations for EntityMut/EntityRef

5 participants