bevy icon indicating copy to clipboard operation
bevy copied to clipboard

Remove ability to `#[reflect(ignore)]` enum variants

Open MrGVSV opened this issue 3 years ago • 2 comments

What problem does this solve or what need does it fill?

#4761 added the ability to reflect enums. With this, it also allowed for entire variants to be excluded from reflection using the #[reflect(ignore)] attribute. As mentioned in this comment, this can cause some problems.

Essentially, the code will panic if we try to call certain methods on an ignored variant.

#[derive(Reflect)]
enum Foo {
  #[reflect(ignore)]
  Bar
}

let value = Foo::Bar;

let name = Enum::variant_name(&value); // <-- PANIC!

What solution would you like?

Remove the ability to ignore entire variants (along with the relevant tests).

What alternative(s) have you considered?

Other solutions could be to:

  1. Allow ignored variants to be used by certain methods
  2. Return default-able values (Option<T> rather than T)
  3. Ignore only the fields within the variant, not the variant itself

Option 1 is probably the best, but now we break the reflection promise that the variant is ignored since we have to use and return its data.

Option 2 negatively affects ergonomics.

Option 3 is okay, but it's not obvious that we are ignoring the fields and not the variant itself.

MrGVSV avatar Sep 14 '22 01:09 MrGVSV

I don't get where it's useful to ignore a variant of an enum. If we consider enums like a safe tagged union, ignoring a variant is like rejecting a specific value for a field. For example, reject Vec2 when x is 0. I'm in favor of the third option. We can use ignore_fields instead of ignore to make clear this is not the variant that is ignored but its fields.

tguichaoua avatar Sep 14 '22 06:09 tguichaoua

I don't get where it's useful to ignore a variant of an enum. If we consider enums like a safe tagged union, ignoring a variant is like rejecting a specific value for a field. For example, reject Vec2 when x is 0.

Yeah, I added it with the thought that maybe it could be used to separate "public" runtime variants from "private" serialized variants. But I didn't really go beyond that and realize how broken it could be if used incorrectly.

I'm in favor of the third option. We can use ignore_fields instead of ignore to make clear this is not the variant that is ignored but its fields.

Yeah this could work. However, I don't think it's a priority. So for sure remove the ability to ignore variants, but maybe add the ability to ignore all fields if there's a real need for it.

MrGVSV avatar Sep 14 '22 07:09 MrGVSV

I'm going to close this issue as I think this behavior was actually removed by #5250.

MrGVSV avatar Oct 19 '22 07:10 MrGVSV