-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add attribute to ignore fields of derived labels (#5366)
# Objective Fixes #5362 ## Solution Add the attribute `#[label(ignore_fields)]` for `*Label` types. ```rust #[derive(SystemLabel)] pub enum MyLabel { One, // Previously this was not allowed since labels cannot contain data. #[system_label(ignore_fields)] Two(PhantomData<usize>), } ``` ## Notes This label makes it possible for equality to behave differently depending on whether or not you are treating the type as a label. For example: ```rust #[derive(SystemLabel, PartialEq, Eq)] #[system_label(ignore_fields)] pub struct Foo(usize); ``` If you compare it as a label, it will ignore the wrapped fields as the user requested. But if you compare it as a `Foo`, the derive will incorrectly compare the inner fields. I see a few solutions 1. Do nothing. This is technically intended behavior, but I think we should do our best to prevent footguns. 2. Generate impls of `PartialEq` and `Eq` along with the `#[derive(Label)]` macros. This is a breaking change as it requires all users to remove these derives from their types. 3. Only allow `PhantomData` to be used with `ignore_fields` -- seems needlessly prescriptive. --- ## Changelog * Added the `ignore_fields` attribute to the derive macros for `*Label` types. * Added an example showing off different forms of the derive macro. <!-- ## Migration Guide > This section is optional. If there are no breaking changes, you can delete this section. - If this PR is a breaking change (relative to the last release of Bevy), describe how a user might need to migrate their code to support these changes - Simply adding new functionality is not a breaking change. - Fixing behavior that was definitely a bug, rather than a questionable design choice is not a breaking change. -->
- Loading branch information
Showing
5 changed files
with
166 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use std::marker::PhantomData; | ||
|
||
use bevy_ecs::prelude::*; | ||
|
||
fn main() { | ||
// Unit labels are always equal. | ||
assert_eq!(UnitLabel.as_label(), UnitLabel.as_label()); | ||
|
||
// Enum labels depend on the variant. | ||
assert_eq!(EnumLabel::One.as_label(), EnumLabel::One.as_label()); | ||
assert_ne!(EnumLabel::One.as_label(), EnumLabel::Two.as_label()); | ||
|
||
// Labels annotated with `ignore_fields` ignore their fields. | ||
assert_eq!(WeirdLabel(1).as_label(), WeirdLabel(2).as_label()); | ||
|
||
// Labels don't depend only on the variant name but on the full type | ||
assert_ne!( | ||
GenericLabel::<f64>::One.as_label(), | ||
GenericLabel::<char>::One.as_label(), | ||
); | ||
} | ||
|
||
#[derive(SystemLabel)] | ||
pub struct UnitLabel; | ||
|
||
#[derive(SystemLabel)] | ||
pub enum EnumLabel { | ||
One, | ||
Two, | ||
} | ||
|
||
#[derive(SystemLabel)] | ||
#[system_label(ignore_fields)] | ||
pub struct WeirdLabel(i32); | ||
|
||
#[derive(SystemLabel)] | ||
pub enum GenericLabel<T> { | ||
One, | ||
#[system_label(ignore_fields)] | ||
Two(PhantomData<T>), | ||
} | ||
|
||
// FIXME: this should be a compile_fail test | ||
/*#[derive(SystemLabel)] | ||
pub union Foo { | ||
x: i32, | ||
}*/ | ||
|
||
// FIXME: this should be a compile_fail test | ||
/*#[derive(SystemLabel)] | ||
#[system_label(ignore_fields)] | ||
pub enum BadLabel { | ||
One, | ||
Two, | ||
}*/ | ||
|
||
// FIXME: this should be a compile_fail test | ||
/*#[derive(SystemLabel)] | ||
pub struct BadLabel2 { | ||
#[system_label(ignore_fields)] | ||
x: (), | ||
}*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters